]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/mtd/maps/ck804xrom.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6-omap-h63xx.git] / drivers / mtd / maps / ck804xrom.c
index 238d42e88ec52eeb050276480d9dcc1e7759a003..59d8fb49270aa93a4d477d2fee8b7cb21ba9438a 100644 (file)
@@ -28,6 +28,9 @@
 
 #define ROM_PROBE_STEP_SIZE (64*1024)
 
+#define DEV_CK804 1
+#define DEV_MCP55 2
+
 struct ck804xrom_window {
        void __iomem *virt;
        unsigned long phys;
@@ -45,8 +48,9 @@ struct ck804xrom_map_info {
        char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN];
 };
 
-
-/* The 2 bits controlling the window size are often set to allow reading
+/*
+ * The following applies to ck804 only:
+ * The 2 bits controlling the window size are often set to allow reading
  * the BIOS, but too small to allow writing, since the lock registers are
  * 4MiB lower in the address space than the data.
  *
@@ -58,10 +62,17 @@ struct ck804xrom_map_info {
  * If only the 7 Bit is set, it is a 4MiB window.  Otherwise, a
  * 64KiB window.
  *
+ * The following applies to mcp55 only:
+ * The 15 bits controlling the window size are distributed as follows: 
+ * byte @0x88: bit 0..7
+ * byte @0x8c: bit 8..15
+ * word @0x90: bit 16..30
+ * If all bits are enabled, we have a 16? MiB window
+ * Please set win_size_bits to 0x7fffffff if you actually want to do something
  */
 static uint win_size_bits = 0;
 module_param(win_size_bits, uint, 0);
-MODULE_PARM_DESC(win_size_bits, "ROM window size bits override for 0x88 byte, normally set by BIOS.");
+MODULE_PARM_DESC(win_size_bits, "ROM window size bits override, normally set by BIOS.");
 
 static struct ck804xrom_window ck804xrom_window = {
        .maps = LIST_HEAD_INIT(ck804xrom_window.maps),
@@ -102,10 +113,11 @@ static void ck804xrom_cleanup(struct ck804xrom_window *window)
 
 
 static int __devinit ck804xrom_init_one (struct pci_dev *pdev,
-       const struct pci_device_id *ent)
+                                        const struct pci_device_id *ent)
 {
        static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
        u8 byte;
+       u16 word;
        struct ck804xrom_window *window = &ck804xrom_window;
        struct ck804xrom_map_info *map = NULL;
        unsigned long map_top;
@@ -113,26 +125,42 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev,
        /* Remember the pci dev I find the window in */
        window->pdev = pci_dev_get(pdev);
 
-       /* Enable the selected rom window.  This is often incorrectly
-        * set up by the BIOS, and the 4MiB offset for the lock registers
-        * requires the full 5MiB of window space.
-        *
-        * This 'write, then read' approach leaves the bits for
-        * other uses of the hardware info.
-        */
-        pci_read_config_byte(pdev, 0x88, &byte);
-        pci_write_config_byte(pdev, 0x88, byte | win_size_bits );
-
-
-       /* Assume the rom window is properly setup, and find it's size */
-       pci_read_config_byte(pdev, 0x88, &byte);
-
-       if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6)))
-               window->phys = 0xffb00000; /* 5MiB */
-       else if ((byte & (1<<7)) == (1<<7))
-               window->phys = 0xffc00000; /* 4MiB */
-       else
-               window->phys = 0xffff0000; /* 64KiB */
+       switch (ent->driver_data) {
+       case DEV_CK804:
+               /* Enable the selected rom window.  This is often incorrectly
+                * set up by the BIOS, and the 4MiB offset for the lock registers
+                * requires the full 5MiB of window space.
+                *
+                * This 'write, then read' approach leaves the bits for
+                * other uses of the hardware info.
+                */
+               pci_read_config_byte(pdev, 0x88, &byte);
+               pci_write_config_byte(pdev, 0x88, byte | win_size_bits );
+
+               /* Assume the rom window is properly setup, and find it's size */
+               pci_read_config_byte(pdev, 0x88, &byte);
+
+               if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6)))
+                       window->phys = 0xffb00000; /* 5MiB */
+               else if ((byte & (1<<7)) == (1<<7))
+                       window->phys = 0xffc00000; /* 4MiB */
+               else
+                       window->phys = 0xffff0000; /* 64KiB */
+               break;
+
+       case DEV_MCP55:
+               pci_read_config_byte(pdev, 0x88, &byte);
+               pci_write_config_byte(pdev, 0x88, byte | (win_size_bits & 0xff));
+
+               pci_read_config_byte(pdev, 0x8c, &byte);
+               pci_write_config_byte(pdev, 0x8c, byte | ((win_size_bits & 0xff00) >> 8));
+
+               pci_read_config_word(pdev, 0x90, &word);
+               pci_write_config_word(pdev, 0x90, word | ((win_size_bits & 0x7fff0000) >> 16));
+
+               window->phys = 0xff000000; /* 16MiB, hardcoded for now */
+               break;
+       }
 
        window->size = 0xffffffffUL - window->phys + 1UL;
 
@@ -207,8 +235,8 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev,
                        (((unsigned long)(window->virt)) + offset);
                map->map.size = 0xffffffffUL - map_top + 1UL;
                /* Set the name of the map to the address I am trying */
-               sprintf(map->map_name, "%s @%08lx",
-                       MOD_NAME, map->map.phys);
+               sprintf(map->map_name, "%s @%08Lx",
+                       MOD_NAME, (unsigned long long)map->map.phys);
 
                /* There is no generic VPP support */
                for(map->map.bankwidth = 32; map->map.bankwidth;
@@ -303,8 +331,15 @@ static void __devexit ck804xrom_remove_one (struct pci_dev *pdev)
 }
 
 static struct pci_device_id ck804xrom_pci_tbl[] = {
-       { PCI_VENDOR_ID_NVIDIA, 0x0051,
-        PCI_ANY_ID, PCI_ANY_ID, }, /* nvidia ck804 */
+       { PCI_VENDOR_ID_NVIDIA, 0x0051, PCI_ANY_ID, PCI_ANY_ID, DEV_CK804 },
+       { PCI_VENDOR_ID_NVIDIA, 0x0360, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 },
+       { PCI_VENDOR_ID_NVIDIA, 0x0361, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 },
+       { PCI_VENDOR_ID_NVIDIA, 0x0362, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 },
+       { PCI_VENDOR_ID_NVIDIA, 0x0363, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 },
+       { PCI_VENDOR_ID_NVIDIA, 0x0364, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 },
+       { PCI_VENDOR_ID_NVIDIA, 0x0365, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 },
+       { PCI_VENDOR_ID_NVIDIA, 0x0366, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 },
+       { PCI_VENDOR_ID_NVIDIA, 0x0367, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 },
        { 0, }
 };
 
@@ -327,18 +362,18 @@ static int __init init_ck804xrom(void)
        pdev = NULL;
 
        for(id = ck804xrom_pci_tbl; id->vendor; id++) {
-               pdev = pci_find_device(id->vendor, id->device, NULL);
+               pdev = pci_get_device(id->vendor, id->device, NULL);
                if (pdev)
                        break;
        }
        if (pdev) {
-               retVal = ck804xrom_init_one(pdev, &ck804xrom_pci_tbl[0]);
+               retVal = ck804xrom_init_one(pdev, id);
                pci_dev_put(pdev);
                return retVal;
        }
        return -ENXIO;
 #if 0
-       return pci_module_init(&ck804xrom_driver);
+       return pci_register_driver(&ck804xrom_driver);
 #endif
 }