fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / char / agp / hp-agp.c
index cafae37..907fb66 100644 (file)
@@ -1,7 +1,12 @@
 /*
- * HP AGPGART routines.
- *     Copyright (C) 2002-2003 Hewlett-Packard Co
- *             Bjorn Helgaas <bjorn_helgaas@hp.com>
+ * HP zx1 AGPGART routines.
+ *
+ * (c) Copyright 2002, 2003 Hewlett-Packard Development Company, L.P.
+ *     Bjorn Helgaas <bjorn.helgaas@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
 
 #include <linux/acpi.h>
@@ -54,8 +59,8 @@ static struct gatt_mask hp_zx1_masks[] =
 };
 
 static struct _hp_private {
-       volatile u8 *ioc_regs;
-       volatile u8 *lba_regs;
+       volatile u8 __iomem *ioc_regs;
+       volatile u8 __iomem *lba_regs;
        int lba_cap_offset;
        u64 *io_pdir;           // PDIR for entire IOVA
        u64 *gatt;              // PDIR just for GART (subset of above)
@@ -80,10 +85,10 @@ static int __init hp_zx1_ioc_shared(void)
        /*
         * IOC already configured by sba_iommu module; just use
         * its setup.  We assume:
-        *      - IOVA space is 1Gb in size
-        *      - first 512Mb is IOMMU, second 512Mb is GART
+        *      - IOVA space is 1Gb in size
+        *      - first 512Mb is IOMMU, second 512Mb is GART
         */
-       hp->io_tlb_ps = INREG64(hp->ioc_regs, HP_ZX1_TCNFG);
+       hp->io_tlb_ps = readq(hp->ioc_regs+HP_ZX1_TCNFG);
        switch (hp->io_tlb_ps) {
                case 0: hp->io_tlb_shift = 12; break;
                case 1: hp->io_tlb_shift = 13; break;
@@ -92,25 +97,25 @@ static int __init hp_zx1_ioc_shared(void)
                default:
                        printk(KERN_ERR PFX "Invalid IOTLB page size "
                               "configuration 0x%x\n", hp->io_tlb_ps);
-                       hp->gatt = 0;
+                       hp->gatt = NULL;
                        hp->gatt_entries = 0;
                        return -ENODEV;
        }
        hp->io_page_size = 1 << hp->io_tlb_shift;
        hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
 
-       hp->iova_base = INREG64(hp->ioc_regs, HP_ZX1_IBASE) & ~0x1;
+       hp->iova_base = readq(hp->ioc_regs+HP_ZX1_IBASE) & ~0x1;
        hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE;
 
        hp->gart_size = HP_ZX1_GART_SIZE;
        hp->gatt_entries = hp->gart_size / hp->io_page_size;
 
-       hp->io_pdir = phys_to_virt(INREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE));
+       hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
        hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
 
        if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
                /* Normal case when no AGP device in system */
-               hp->gatt = 0;
+               hp->gatt = NULL;
                hp->gatt_entries = 0;
                printk(KERN_ERR PFX "No reserved IO PDIR entry found; "
                       "GART disabled\n");
@@ -169,7 +174,7 @@ hp_zx1_ioc_init (u64 hpa)
         * If the IOTLB is currently disabled, we can take it over.
         * Otherwise, we have to share with sba_iommu.
         */
-       hp->io_pdir_owner = (INREG64(hp->ioc_regs, HP_ZX1_IBASE) & 0x1) == 0;
+       hp->io_pdir_owner = (readq(hp->ioc_regs+HP_ZX1_IBASE) & 0x1) == 0;
 
        if (hp->io_pdir_owner)
                return hp_zx1_ioc_owner();
@@ -178,24 +183,24 @@ hp_zx1_ioc_init (u64 hpa)
 }
 
 static int
-hp_zx1_lba_find_capability (volatile u8 *hpa, int cap)
+hp_zx1_lba_find_capability (volatile u8 __iomem *hpa, int cap)
 {
        u16 status;
        u8 pos, id;
        int ttl = 48;
 
-       status = INREG16(hpa, PCI_STATUS);
+       status = readw(hpa+PCI_STATUS);
        if (!(status & PCI_STATUS_CAP_LIST))
                return 0;
-       pos = INREG8(hpa, PCI_CAPABILITY_LIST);
+       pos = readb(hpa+PCI_CAPABILITY_LIST);
        while (ttl-- && pos >= 0x40) {
                pos &= ~3;
-               id = INREG8(hpa, pos + PCI_CAP_LIST_ID);
+               id = readb(hpa+pos+PCI_CAP_LIST_ID);
                if (id == 0xff)
                        break;
                if (id == cap)
                        return pos;
-               pos = INREG8(hpa, pos + PCI_CAP_LIST_NEXT);
+               pos = readb(hpa+pos+PCI_CAP_LIST_NEXT);
        }
        return 0;
 }
@@ -212,7 +217,7 @@ hp_zx1_lba_init (u64 hpa)
 
        hp->lba_cap_offset = hp_zx1_lba_find_capability(hp->lba_regs, PCI_CAP_ID_AGP);
 
-       cap = INREG32(hp->lba_regs, hp->lba_cap_offset) & 0xff;
+       cap = readl(hp->lba_regs+hp->lba_cap_offset) & 0xff;
        if (cap != PCI_CAP_ID_AGP) {
                printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
                       cap, hp->lba_cap_offset);
@@ -240,15 +245,19 @@ hp_zx1_configure (void)
 
        agp_bridge->gart_bus_addr = hp->gart_base;
        agp_bridge->capndx = hp->lba_cap_offset;
-       agp_bridge->mode = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
+       agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
 
        if (hp->io_pdir_owner) {
-               OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE, virt_to_phys(hp->io_pdir));
-               OUTREG64(hp->ioc_regs, HP_ZX1_TCNFG, hp->io_tlb_ps);
-               OUTREG64(hp->ioc_regs, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1));
-               OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, hp->iova_base | 0x1);
-               OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, hp->iova_base | log2(HP_ZX1_IOVA_SIZE));
-               INREG64(hp->ioc_regs, HP_ZX1_PCOM);
+               writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
+               readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
+               writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
+               readl(hp->ioc_regs+HP_ZX1_TCNFG);
+               writel((unsigned int)(~(HP_ZX1_IOVA_SIZE-1)), hp->ioc_regs+HP_ZX1_IMASK);
+               readl(hp->ioc_regs+HP_ZX1_IMASK);
+               writel(hp->iova_base|1, hp->ioc_regs+HP_ZX1_IBASE);
+               readl(hp->ioc_regs+HP_ZX1_IBASE);
+               writel(hp->iova_base|log2(HP_ZX1_IOVA_SIZE), hp->ioc_regs+HP_ZX1_PCOM);
+               readl(hp->ioc_regs+HP_ZX1_PCOM);
        }
 
        return 0;
@@ -260,12 +269,14 @@ hp_zx1_cleanup (void)
        struct _hp_private *hp = &hp_private;
 
        if (hp->ioc_regs) {
-               if (hp->io_pdir_owner)
-                       OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
-               iounmap((void *) hp->ioc_regs);
+               if (hp->io_pdir_owner) {
+                       writeq(0, hp->ioc_regs+HP_ZX1_IBASE);
+                       readq(hp->ioc_regs+HP_ZX1_IBASE);
+               }
+               iounmap(hp->ioc_regs);
        }
        if (hp->lba_regs)
-               iounmap((void *) hp->lba_regs);
+               iounmap(hp->lba_regs);
 }
 
 static void
@@ -273,12 +284,12 @@ hp_zx1_tlbflush (struct agp_memory *mem)
 {
        struct _hp_private *hp = &hp_private;
 
-       OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, hp->gart_base | log2(hp->gart_size));
-       INREG64(hp->ioc_regs, HP_ZX1_PCOM);
+       writeq(hp->gart_base | log2(hp->gart_size), hp->ioc_regs+HP_ZX1_PCOM);
+       readq(hp->ioc_regs+HP_ZX1_PCOM);
 }
 
 static int
-hp_zx1_create_gatt_table (void)
+hp_zx1_create_gatt_table (struct agp_bridge_data *bridge)
 {
        struct _hp_private *hp = &hp_private;
        int i;
@@ -289,7 +300,7 @@ hp_zx1_create_gatt_table (void)
                if (!hp->io_pdir) {
                        printk(KERN_ERR PFX "Couldn't allocate contiguous "
                                "memory for I/O PDIR\n");
-                       hp->gatt = 0;
+                       hp->gatt = NULL;
                        hp->gatt_entries = 0;
                        return -ENOMEM;
                }
@@ -306,7 +317,7 @@ hp_zx1_create_gatt_table (void)
 }
 
 static int
-hp_zx1_free_gatt_table (void)
+hp_zx1_free_gatt_table (struct agp_bridge_data *bridge)
 {
        struct _hp_private *hp = &hp_private;
 
@@ -356,7 +367,9 @@ hp_zx1_insert_memory (struct agp_memory *mem, off_t pg_start, int type)
                for (k = 0;
                     k < hp->io_pages_per_kpage;
                     k++, j++, paddr += hp->io_page_size) {
-                       hp->gatt[j] = agp_bridge->driver->mask_memory(paddr, type);
+                       hp->gatt[j] =
+                               agp_bridge->driver->mask_memory(agp_bridge,
+                                       paddr, type);
                }
        }
 
@@ -385,23 +398,23 @@ hp_zx1_remove_memory (struct agp_memory *mem, off_t pg_start, int type)
 }
 
 static unsigned long
-hp_zx1_mask_memory (unsigned long addr, int type)
+hp_zx1_mask_memory (struct agp_bridge_data *bridge,
+       unsigned long addr, int type)
 {
        return HP_ZX1_PDIR_VALID_BIT | addr;
 }
 
 static void
-hp_zx1_enable (u32 mode)
+hp_zx1_enable (struct agp_bridge_data *bridge, u32 mode)
 {
        struct _hp_private *hp = &hp_private;
        u32 command;
 
-       command = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
-
-       command = agp_collect_device_status(mode, command);
+       command = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
+       command = agp_collect_device_status(bridge, mode, command);
        command |= 0x00000100;
 
-       OUTREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_COMMAND, command);
+       writel(command, hp->lba_regs+hp->lba_cap_offset+PCI_AGP_COMMAND);
 
        agp_device_command(command, (mode & AGP8X_MODE) != 0);
 }
@@ -484,7 +497,7 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret)
                        info = buffer.pointer;
                        info->hardware_id.value[sizeof(info->hardware_id)-1] = '\0';
                        match = (strcmp(info->hardware_id.value, "HWP0001") == 0);
-                       ACPI_MEM_FREE(info);
+                       kfree(info);
                        if (match) {
                                status = hp_acpi_csr_space(handle, &sba_hpa, &length);
                                if (ACPI_SUCCESS(status))
@@ -514,6 +527,8 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret)
 static int __init
 agp_hp_init (void)
 {
+       if (agp_off)
+               return -EINVAL;
 
        acpi_get_devices("HWP0003", zx1_gart_probe, "HWP0003", NULL);
        if (hp_zx1_gart_found)