Pull events into release branch
[cascardo/linux.git] / drivers / ata / pata_hpt37x.c
index a54c174..c5ddd93 100644 (file)
@@ -8,12 +8,10 @@
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
  * Portions Copyright (C) 2003         Red Hat Inc
- * Portions Copyright (C) 2005-2006    MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2007    MontaVista Software, Inc.
  *
  * TODO
- *     PLL mode
- *     Look into engine reset on timeout errors. Should not be
- *             required.
+ *     Look into engine reset on timeout errors. Should not be required.
  */
 
 #include <linux/kernel.h>
@@ -26,7 +24,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt37x"
-#define DRV_VERSION    "0.6.5"
+#define DRV_VERSION    "0.6.9"
 
 struct hpt_clock {
        u8      xfer_speed;
@@ -889,25 +887,25 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        /* HPT370 - UDMA100 */
        static const struct ata_port_info info_hpt370 = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &hpt370_port_ops
        };
        /* HPT370A - UDMA100 */
        static const struct ata_port_info info_hpt370a = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &hpt370a_port_ops
        };
        /* HPT370 - UDMA100 */
        static const struct ata_port_info info_hpt370_33 = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x0f,
@@ -916,7 +914,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        /* HPT370A - UDMA100 */
        static const struct ata_port_info info_hpt370a_33 = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x0f,
@@ -925,28 +923,19 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        /* HPT371, 372 and friends - UDMA133 */
        static const struct ata_port_info info_hpt372 = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x7f,
+               .udma_mask = ATA_UDMA6,
                .port_ops = &hpt372_port_ops
        };
-       /* HPT371, 372 and friends - UDMA100 at 50MHz clock */
-       static const struct ata_port_info info_hpt372_50 = {
-               .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
-               .pio_mask = 0x1f,
-               .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
-               .port_ops = &hpt372_port_ops
-       };
-       /* HPT374 - UDMA133 */
+       /* HPT374 - UDMA100 */
        static const struct ata_port_info info_hpt374 = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x7f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &hpt374_port_ops
        };
 
@@ -1098,38 +1087,41 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                 *      use a 50MHz DPLL by choice
                 */
                unsigned int f_low, f_high;
-               int adjust;
+               int dpll, adjust;
 
-               clock_slot = 2;
-               if (port->udma_mask & 0xE0)
-                       clock_slot = 3;
+               /* Compute DPLL */
+               dpll = (port->udma_mask & 0xC0) ? 3 : 2;
 
-               f_low = (MHz[clock_slot] * chip_table->base) / 192;
+               f_low = (MHz[clock_slot] * 48) / MHz[dpll];
                f_high = f_low + 2;
+               if (clock_slot > 1)
+                       f_high += 2;
 
                /* Select the DPLL clock. */
                pci_write_config_byte(dev, 0x5b, 0x21);
+               pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
 
                for(adjust = 0; adjust < 8; adjust++) {
                        if (hpt37x_calibrate_dpll(dev))
                                break;
                        /* See if it'll settle at a fractionally different clock */
-                       if ((adjust & 3) == 3) {
-                               f_low --;
-                               f_high ++;
-                       }
-                       pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
+                       if (adjust & 1)
+                               f_low -= adjust >> 1;
+                       else
+                               f_high += adjust >> 1;
+                       pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
                }
                if (adjust == 8) {
-                       printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
+                       printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n");
                        return -ENODEV;
                }
-               if (clock_slot == 3)
+               if (dpll == 3)
                        private_data = (void *)hpt37x_timings_66;
                else
                        private_data = (void *)hpt37x_timings_50;
 
-               printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
+               printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n",
+                      MHz[clock_slot], MHz[dpll]);
        } else {
                private_data = (void *)chip_table->clocks[clock_slot];
                /*
@@ -1142,7 +1134,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        port = &info_hpt370_33;
                if (clock_slot < 2 && port == &info_hpt370a)
                        port = &info_hpt370a_33;
-               printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]);
+               printk(KERN_INFO "pata_hpt37x: %s using %dMHz bus clock.\n",
+                      chip_table->name, MHz[clock_slot]);
        }
 
        /* Now kick off ATA set up */