linux/drivers/char/agp/hp-agp.c
<<
>>
Prefs
   1/*
   2 * HP zx1 AGPGART routines.
   3 *
   4 * (c) Copyright 2002, 2003 Hewlett-Packard Development Company, L.P.
   5 *      Bjorn Helgaas <bjorn.helgaas@hp.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11
  12#include <linux/acpi.h>
  13#include <linux/module.h>
  14#include <linux/pci.h>
  15#include <linux/init.h>
  16#include <linux/agp_backend.h>
  17#include <linux/log2.h>
  18#include <linux/slab.h>
  19
  20#include <asm/acpi-ext.h>
  21
  22#include "agp.h"
  23
  24#define HP_ZX1_IOC_OFFSET       0x1000  /* ACPI reports SBA, we want IOC */
  25
  26/* HP ZX1 IOC registers */
  27#define HP_ZX1_IBASE            0x300
  28#define HP_ZX1_IMASK            0x308
  29#define HP_ZX1_PCOM             0x310
  30#define HP_ZX1_TCNFG            0x318
  31#define HP_ZX1_PDIR_BASE        0x320
  32
  33#define HP_ZX1_IOVA_BASE        GB(1UL)
  34#define HP_ZX1_IOVA_SIZE        GB(1UL)
  35#define HP_ZX1_GART_SIZE        (HP_ZX1_IOVA_SIZE / 2)
  36#define HP_ZX1_SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL
  37
  38#define HP_ZX1_PDIR_VALID_BIT   0x8000000000000000UL
  39#define HP_ZX1_IOVA_TO_PDIR(va) ((va - hp_private.iova_base) >> hp_private.io_tlb_shift)
  40
  41#define AGP8X_MODE_BIT          3
  42#define AGP8X_MODE              (1 << AGP8X_MODE_BIT)
  43
  44/* AGP bridge need not be PCI device, but DRM thinks it is. */
  45static struct pci_dev fake_bridge_dev;
  46
  47static int hp_zx1_gart_found;
  48
  49static struct aper_size_info_fixed hp_zx1_sizes[] =
  50{
  51        {0, 0, 0},              /* filled in by hp_zx1_fetch_size() */
  52};
  53
  54static struct gatt_mask hp_zx1_masks[] =
  55{
  56        {.mask = HP_ZX1_PDIR_VALID_BIT, .type = 0}
  57};
  58
  59static struct _hp_private {
  60        volatile u8 __iomem *ioc_regs;
  61        volatile u8 __iomem *lba_regs;
  62        int lba_cap_offset;
  63        u64 *io_pdir;           // PDIR for entire IOVA
  64        u64 *gatt;              // PDIR just for GART (subset of above)
  65        u64 gatt_entries;
  66        u64 iova_base;
  67        u64 gart_base;
  68        u64 gart_size;
  69        u64 io_pdir_size;
  70        int io_pdir_owner;      // do we own it, or share it with sba_iommu?
  71        int io_page_size;
  72        int io_tlb_shift;
  73        int io_tlb_ps;          // IOC ps config
  74        int io_pages_per_kpage;
  75} hp_private;
  76
  77static int __init hp_zx1_ioc_shared(void)
  78{
  79        struct _hp_private *hp = &hp_private;
  80
  81        printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR shared with sba_iommu\n");
  82
  83        /*
  84         * IOC already configured by sba_iommu module; just use
  85         * its setup.  We assume:
  86         *      - IOVA space is 1Gb in size
  87         *      - first 512Mb is IOMMU, second 512Mb is GART
  88         */
  89        hp->io_tlb_ps = readq(hp->ioc_regs+HP_ZX1_TCNFG);
  90        switch (hp->io_tlb_ps) {
  91                case 0: hp->io_tlb_shift = 12; break;
  92                case 1: hp->io_tlb_shift = 13; break;
  93                case 2: hp->io_tlb_shift = 14; break;
  94                case 3: hp->io_tlb_shift = 16; break;
  95                default:
  96                        printk(KERN_ERR PFX "Invalid IOTLB page size "
  97                               "configuration 0x%x\n", hp->io_tlb_ps);
  98                        hp->gatt = NULL;
  99                        hp->gatt_entries = 0;
 100                        return -ENODEV;
 101        }
 102        hp->io_page_size = 1 << hp->io_tlb_shift;
 103        hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
 104
 105        hp->iova_base = readq(hp->ioc_regs+HP_ZX1_IBASE) & ~0x1;
 106        hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE;
 107
 108        hp->gart_size = HP_ZX1_GART_SIZE;
 109        hp->gatt_entries = hp->gart_size / hp->io_page_size;
 110
 111        hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
 112        hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
 113
 114        if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
 115                /* Normal case when no AGP device in system */
 116                hp->gatt = NULL;
 117                hp->gatt_entries = 0;
 118                printk(KERN_ERR PFX "No reserved IO PDIR entry found; "
 119                       "GART disabled\n");
 120                return -ENODEV;
 121        }
 122
 123        return 0;
 124}
 125
 126static int __init
 127hp_zx1_ioc_owner (void)
 128{
 129        struct _hp_private *hp = &hp_private;
 130
 131        printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR dedicated to GART\n");
 132
 133        /*
 134         * Select an IOV page size no larger than system page size.
 135         */
 136        if (PAGE_SIZE >= KB(64)) {
 137                hp->io_tlb_shift = 16;
 138                hp->io_tlb_ps = 3;
 139        } else if (PAGE_SIZE >= KB(16)) {
 140                hp->io_tlb_shift = 14;
 141                hp->io_tlb_ps = 2;
 142        } else if (PAGE_SIZE >= KB(8)) {
 143                hp->io_tlb_shift = 13;
 144                hp->io_tlb_ps = 1;
 145        } else {
 146                hp->io_tlb_shift = 12;
 147                hp->io_tlb_ps = 0;
 148        }
 149        hp->io_page_size = 1 << hp->io_tlb_shift;
 150        hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
 151
 152        hp->iova_base = HP_ZX1_IOVA_BASE;
 153        hp->gart_size = HP_ZX1_GART_SIZE;
 154        hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - hp->gart_size;
 155
 156        hp->gatt_entries = hp->gart_size / hp->io_page_size;
 157        hp->io_pdir_size = (HP_ZX1_IOVA_SIZE / hp->io_page_size) * sizeof(u64);
 158
 159        return 0;
 160}
 161
 162static int __init
 163hp_zx1_ioc_init (u64 hpa)
 164{
 165        struct _hp_private *hp = &hp_private;
 166
 167        hp->ioc_regs = ioremap(hpa, 1024);
 168        if (!hp->ioc_regs)
 169                return -ENOMEM;
 170
 171        /*
 172         * If the IOTLB is currently disabled, we can take it over.
 173         * Otherwise, we have to share with sba_iommu.
 174         */
 175        hp->io_pdir_owner = (readq(hp->ioc_regs+HP_ZX1_IBASE) & 0x1) == 0;
 176
 177        if (hp->io_pdir_owner)
 178                return hp_zx1_ioc_owner();
 179
 180        return hp_zx1_ioc_shared();
 181}
 182
 183static int
 184hp_zx1_lba_find_capability (volatile u8 __iomem *hpa, int cap)
 185{
 186        u16 status;
 187        u8 pos, id;
 188        int ttl = 48;
 189
 190        status = readw(hpa+PCI_STATUS);
 191        if (!(status & PCI_STATUS_CAP_LIST))
 192                return 0;
 193        pos = readb(hpa+PCI_CAPABILITY_LIST);
 194        while (ttl-- && pos >= 0x40) {
 195                pos &= ~3;
 196                id = readb(hpa+pos+PCI_CAP_LIST_ID);
 197                if (id == 0xff)
 198                        break;
 199                if (id == cap)
 200                        return pos;
 201                pos = readb(hpa+pos+PCI_CAP_LIST_NEXT);
 202        }
 203        return 0;
 204}
 205
 206static int __init
 207hp_zx1_lba_init (u64 hpa)
 208{
 209        struct _hp_private *hp = &hp_private;
 210        int cap;
 211
 212        hp->lba_regs = ioremap(hpa, 256);
 213        if (!hp->lba_regs)
 214                return -ENOMEM;
 215
 216        hp->lba_cap_offset = hp_zx1_lba_find_capability(hp->lba_regs, PCI_CAP_ID_AGP);
 217
 218        cap = readl(hp->lba_regs+hp->lba_cap_offset) & 0xff;
 219        if (cap != PCI_CAP_ID_AGP) {
 220                printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
 221                       cap, hp->lba_cap_offset);
 222                iounmap(hp->lba_regs);
 223                return -ENODEV;
 224        }
 225
 226        return 0;
 227}
 228
 229static int
 230hp_zx1_fetch_size(void)
 231{
 232        int size;
 233
 234        size = hp_private.gart_size / MB(1);
 235        hp_zx1_sizes[0].size = size;
 236        agp_bridge->current_size = (void *) &hp_zx1_sizes[0];
 237        return size;
 238}
 239
 240static int
 241hp_zx1_configure (void)
 242{
 243        struct _hp_private *hp = &hp_private;
 244
 245        agp_bridge->gart_bus_addr = hp->gart_base;
 246        agp_bridge->capndx = hp->lba_cap_offset;
 247        agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
 248
 249        if (hp->io_pdir_owner) {
 250                writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
 251                readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
 252                writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
 253                readl(hp->ioc_regs+HP_ZX1_TCNFG);
 254                writel((unsigned int)(~(HP_ZX1_IOVA_SIZE-1)), hp->ioc_regs+HP_ZX1_IMASK);
 255                readl(hp->ioc_regs+HP_ZX1_IMASK);
 256                writel(hp->iova_base|1, hp->ioc_regs+HP_ZX1_IBASE);
 257                readl(hp->ioc_regs+HP_ZX1_IBASE);
 258                writel(hp->iova_base|ilog2(HP_ZX1_IOVA_SIZE), hp->ioc_regs+HP_ZX1_PCOM);
 259                readl(hp->ioc_regs+HP_ZX1_PCOM);
 260        }
 261
 262        return 0;
 263}
 264
 265static void
 266hp_zx1_cleanup (void)
 267{
 268        struct _hp_private *hp = &hp_private;
 269
 270        if (hp->ioc_regs) {
 271                if (hp->io_pdir_owner) {
 272                        writeq(0, hp->ioc_regs+HP_ZX1_IBASE);
 273                        readq(hp->ioc_regs+HP_ZX1_IBASE);
 274                }
 275                iounmap(hp->ioc_regs);
 276        }
 277        if (hp->lba_regs)
 278                iounmap(hp->lba_regs);
 279}
 280
 281static void
 282hp_zx1_tlbflush (struct agp_memory *mem)
 283{
 284        struct _hp_private *hp = &hp_private;
 285
 286        writeq(hp->gart_base | ilog2(hp->gart_size), hp->ioc_regs+HP_ZX1_PCOM);
 287        readq(hp->ioc_regs+HP_ZX1_PCOM);
 288}
 289
 290static int
 291hp_zx1_create_gatt_table (struct agp_bridge_data *bridge)
 292{
 293        struct _hp_private *hp = &hp_private;
 294        int i;
 295
 296        if (hp->io_pdir_owner) {
 297                hp->io_pdir = (u64 *) __get_free_pages(GFP_KERNEL,
 298                                                get_order(hp->io_pdir_size));
 299                if (!hp->io_pdir) {
 300                        printk(KERN_ERR PFX "Couldn't allocate contiguous "
 301                                "memory for I/O PDIR\n");
 302                        hp->gatt = NULL;
 303                        hp->gatt_entries = 0;
 304                        return -ENOMEM;
 305                }
 306                memset(hp->io_pdir, 0, hp->io_pdir_size);
 307
 308                hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
 309        }
 310
 311        for (i = 0; i < hp->gatt_entries; i++) {
 312                hp->gatt[i] = (unsigned long) agp_bridge->scratch_page;
 313        }
 314
 315        return 0;
 316}
 317
 318static int
 319hp_zx1_free_gatt_table (struct agp_bridge_data *bridge)
 320{
 321        struct _hp_private *hp = &hp_private;
 322
 323        if (hp->io_pdir_owner)
 324                free_pages((unsigned long) hp->io_pdir,
 325                            get_order(hp->io_pdir_size));
 326        else
 327                hp->gatt[0] = HP_ZX1_SBA_IOMMU_COOKIE;
 328        return 0;
 329}
 330
 331static int
 332hp_zx1_insert_memory (struct agp_memory *mem, off_t pg_start, int type)
 333{
 334        struct _hp_private *hp = &hp_private;
 335        int i, k;
 336        off_t j, io_pg_start;
 337        int io_pg_count;
 338
 339        if (type != mem->type ||
 340                agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
 341                return -EINVAL;
 342        }
 343
 344        io_pg_start = hp->io_pages_per_kpage * pg_start;
 345        io_pg_count = hp->io_pages_per_kpage * mem->page_count;
 346        if ((io_pg_start + io_pg_count) > hp->gatt_entries) {
 347                return -EINVAL;
 348        }
 349
 350        j = io_pg_start;
 351        while (j < (io_pg_start + io_pg_count)) {
 352                if (hp->gatt[j]) {
 353                        return -EBUSY;
 354                }
 355                j++;
 356        }
 357
 358        if (!mem->is_flushed) {
 359                global_cache_flush();
 360                mem->is_flushed = true;
 361        }
 362
 363        for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
 364                unsigned long paddr;
 365
 366                paddr = page_to_phys(mem->pages[i]);
 367                for (k = 0;
 368                     k < hp->io_pages_per_kpage;
 369                     k++, j++, paddr += hp->io_page_size) {
 370                        hp->gatt[j] = HP_ZX1_PDIR_VALID_BIT | paddr;
 371                }
 372        }
 373
 374        agp_bridge->driver->tlb_flush(mem);
 375        return 0;
 376}
 377
 378static int
 379hp_zx1_remove_memory (struct agp_memory *mem, off_t pg_start, int type)
 380{
 381        struct _hp_private *hp = &hp_private;
 382        int i, io_pg_start, io_pg_count;
 383
 384        if (type != mem->type ||
 385                agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
 386                return -EINVAL;
 387        }
 388
 389        io_pg_start = hp->io_pages_per_kpage * pg_start;
 390        io_pg_count = hp->io_pages_per_kpage * mem->page_count;
 391        for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
 392                hp->gatt[i] = agp_bridge->scratch_page;
 393        }
 394
 395        agp_bridge->driver->tlb_flush(mem);
 396        return 0;
 397}
 398
 399static unsigned long
 400hp_zx1_mask_memory (struct agp_bridge_data *bridge, dma_addr_t addr, int type)
 401{
 402        return HP_ZX1_PDIR_VALID_BIT | addr;
 403}
 404
 405static void
 406hp_zx1_enable (struct agp_bridge_data *bridge, u32 mode)
 407{
 408        struct _hp_private *hp = &hp_private;
 409        u32 command;
 410
 411        command = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
 412        command = agp_collect_device_status(bridge, mode, command);
 413        command |= 0x00000100;
 414
 415        writel(command, hp->lba_regs+hp->lba_cap_offset+PCI_AGP_COMMAND);
 416
 417        agp_device_command(command, (mode & AGP8X_MODE) != 0);
 418}
 419
 420const struct agp_bridge_driver hp_zx1_driver = {
 421        .owner                  = THIS_MODULE,
 422        .size_type              = FIXED_APER_SIZE,
 423        .configure              = hp_zx1_configure,
 424        .fetch_size             = hp_zx1_fetch_size,
 425        .cleanup                = hp_zx1_cleanup,
 426        .tlb_flush              = hp_zx1_tlbflush,
 427        .mask_memory            = hp_zx1_mask_memory,
 428        .masks                  = hp_zx1_masks,
 429        .agp_enable             = hp_zx1_enable,
 430        .cache_flush            = global_cache_flush,
 431        .create_gatt_table      = hp_zx1_create_gatt_table,
 432        .free_gatt_table        = hp_zx1_free_gatt_table,
 433        .insert_memory          = hp_zx1_insert_memory,
 434        .remove_memory          = hp_zx1_remove_memory,
 435        .alloc_by_type          = agp_generic_alloc_by_type,
 436        .free_by_type           = agp_generic_free_by_type,
 437        .agp_alloc_page         = agp_generic_alloc_page,
 438        .agp_alloc_pages        = agp_generic_alloc_pages,
 439        .agp_destroy_page       = agp_generic_destroy_page,
 440        .agp_destroy_pages      = agp_generic_destroy_pages,
 441        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 442        .cant_use_aperture      = true,
 443};
 444
 445static int __init
 446hp_zx1_setup (u64 ioc_hpa, u64 lba_hpa)
 447{
 448        struct agp_bridge_data *bridge;
 449        int error = 0;
 450
 451        error = hp_zx1_ioc_init(ioc_hpa);
 452        if (error)
 453                goto fail;
 454
 455        error = hp_zx1_lba_init(lba_hpa);
 456        if (error)
 457                goto fail;
 458
 459        bridge = agp_alloc_bridge();
 460        if (!bridge) {
 461                error = -ENOMEM;
 462                goto fail;
 463        }
 464        bridge->driver = &hp_zx1_driver;
 465
 466        fake_bridge_dev.vendor = PCI_VENDOR_ID_HP;
 467        fake_bridge_dev.device = PCI_DEVICE_ID_HP_PCIX_LBA;
 468        bridge->dev = &fake_bridge_dev;
 469
 470        error = agp_add_bridge(bridge);
 471  fail:
 472        if (error)
 473                hp_zx1_cleanup();
 474        return error;
 475}
 476
 477static acpi_status __init
 478zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret)
 479{
 480        acpi_handle handle, parent;
 481        acpi_status status;
 482        struct acpi_device_info *info;
 483        u64 lba_hpa, sba_hpa, length;
 484        int match;
 485
 486        status = hp_acpi_csr_space(obj, &lba_hpa, &length);
 487        if (ACPI_FAILURE(status))
 488                return AE_OK; /* keep looking for another bridge */
 489
 490        /* Look for an enclosing IOC scope and find its CSR space */
 491        handle = obj;
 492        do {
 493                status = acpi_get_object_info(handle, &info);
 494                if (ACPI_SUCCESS(status) && (info->valid & ACPI_VALID_HID)) {
 495                        /* TBD check _CID also */
 496                        match = (strcmp(info->hardware_id.string, "HWP0001") == 0);
 497                        kfree(info);
 498                        if (match) {
 499                                status = hp_acpi_csr_space(handle, &sba_hpa, &length);
 500                                if (ACPI_SUCCESS(status))
 501                                        break;
 502                                else {
 503                                        printk(KERN_ERR PFX "Detected HP ZX1 "
 504                                               "AGP LBA but no IOC.\n");
 505                                        return AE_OK;
 506                                }
 507                        }
 508                }
 509
 510                status = acpi_get_parent(handle, &parent);
 511                handle = parent;
 512        } while (ACPI_SUCCESS(status));
 513
 514        if (ACPI_FAILURE(status))
 515                return AE_OK;   /* found no enclosing IOC */
 516
 517        if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa))
 518                return AE_OK;
 519
 520        printk(KERN_INFO PFX "Detected HP ZX1 %s AGP chipset "
 521                "(ioc=%llx, lba=%llx)\n", (char *)context,
 522                sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa);
 523
 524        hp_zx1_gart_found = 1;
 525        return AE_CTRL_TERMINATE; /* we only support one bridge; quit looking */
 526}
 527
 528static int __init
 529agp_hp_init (void)
 530{
 531        if (agp_off)
 532                return -EINVAL;
 533
 534        acpi_get_devices("HWP0003", zx1_gart_probe, "HWP0003", NULL);
 535        if (hp_zx1_gart_found)
 536                return 0;
 537
 538        acpi_get_devices("HWP0007", zx1_gart_probe, "HWP0007", NULL);
 539        if (hp_zx1_gart_found)
 540                return 0;
 541
 542        return -ENODEV;
 543}
 544
 545static void __exit
 546agp_hp_cleanup (void)
 547{
 548}
 549
 550module_init(agp_hp_init);
 551module_exit(agp_hp_cleanup);
 552
 553MODULE_LICENSE("GPL and additional rights");
 554