]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/pci/hpt366.c
hpt366: use correct enablebits for HPT36x
[linux-2.6-omap-h63xx.git] / drivers / ide / pci / hpt366.c
index cf9d344d19f828f73d92691e4740b35dde9b1ec4..c33d0b0f11c91896eb498bb1a5f030ad7ce6b51b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/hpt366.c              Version 1.03    May 4, 2007
+ * linux/drivers/ide/pci/hpt366.c              Version 1.06    Jun 27, 2007
  *
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
  *   switch  to calculating  PCI clock frequency based on the chip's base DPLL
  *   frequency
  * - switch to using the  DPLL clock and enable UltraATA/133 mode by default on
- *   anything  newer than HPT370/A
+ *   anything  newer than HPT370/A (except HPT374 that is not capable of this
+ *   mode according to the manual)
  * - fold PCI clock detection and DPLL setup code into init_chipset_hpt366(),
  *   also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips;
  *   unify HPT36x/37x timing setup code and the speedproc handlers by joining
@@ -181,6 +182,7 @@ static const char *bad_ata66_4[] = {
        "IC35L040AVER07-0",
        "IC35L060AVER07-0",
        "WDC AC310200R",
+       "MAXTOR STM3320620A",
        NULL
 };
 
@@ -365,7 +367,6 @@ static u32 sixty_six_base_hpt37x[] = {
 };
 
 #define HPT366_DEBUG_DRIVE_INFO                0
-#define HPT374_ALLOW_ATA133_6          1
 #define HPT371_ALLOW_ATA133_6          1
 #define HPT302_ALLOW_ATA133_6          1
 #define HPT372_ALLOW_ATA133_6          1
@@ -450,7 +451,7 @@ static struct hpt_info hpt370a __devinitdata = {
 
 static struct hpt_info hpt374 __devinitdata = {
        .chip_type      = HPT374,
-       .max_mode       = HPT374_ALLOW_ATA133_6 ? 4 : 3,
+       .max_mode       = 3,
        .dpll_clk       = 48,
        .settings       = hpt37x_settings
 };
@@ -514,43 +515,31 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list)
        return 0;
 }
 
-static u8 hpt3xx_ratemask(ide_drive_t *drive)
-{
-       struct hpt_info *info   = pci_get_drvdata(HWIF(drive)->pci_dev);
-       u8 mode                 = info->max_mode;
-
-       if (!eighty_ninty_three(drive) && mode)
-               mode = min(mode, (u8)1);
-       return mode;
-}
-
 /*
  *     Note for the future; the SATA hpt37x we must set
  *     either PIO or UDMA modes 0,4,5
  */
-static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed)
+
+static u8 hpt3xx_udma_filter(ide_drive_t *drive)
 {
        struct hpt_info *info   = pci_get_drvdata(HWIF(drive)->pci_dev);
        u8 chip_type            = info->chip_type;
-       u8 mode                 = hpt3xx_ratemask(drive);
-
-       if (drive->media != ide_disk)
-               return min(speed, (u8)XFER_PIO_4);
+       u8 mode                 = info->max_mode;
+       u8 mask;
 
        switch (mode) {
                case 0x04:
-                       speed = min_t(u8, speed, XFER_UDMA_6);
+                       mask = 0x7f;
                        break;
                case 0x03:
-                       speed = min_t(u8, speed, XFER_UDMA_5);
+                       mask = 0x3f;
                        if (chip_type >= HPT374)
                                break;
                        if (!check_in_drive_list(drive, bad_ata100_5))
                                goto check_bad_ata33;
                        /* fall thru */
                case 0x02:
-                       speed = min_t(u8, speed, XFER_UDMA_4);
+                       mask = 0x1f;
 
                        /*
                         * CHECK ME, Does this need to be changed to HPT374 ??
@@ -561,13 +550,13 @@ static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed)
                            !check_in_drive_list(drive, bad_ata66_4))
                                goto check_bad_ata33;
 
-                       speed = min_t(u8, speed, XFER_UDMA_3);
+                       mask = 0x0f;
                        if (HPT366_ALLOW_ATA66_3 &&
                            !check_in_drive_list(drive, bad_ata66_3))
                                goto check_bad_ata33;
                        /* fall thru */
                case 0x01:
-                       speed = min_t(u8, speed, XFER_UDMA_2);
+                       mask = 0x07;
 
                check_bad_ata33:
                        if (chip_type >= HPT370A)
@@ -577,10 +566,10 @@ static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed)
                        /* fall thru */
                case 0x00:
                default:
-                       speed = min_t(u8, speed, XFER_MW_DMA_2);
+                       mask = 0x00;
                        break;
        }
-       return speed;
+       return mask;
 }
 
 static u32 get_speed_setting(u8 speed, struct hpt_info *info)
@@ -608,12 +597,19 @@ static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed)
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev  *dev    = hwif->pci_dev;
        struct hpt_info *info   = pci_get_drvdata(dev);
-       u8  speed               = hpt3xx_ratefilter(drive, xferspeed);
+       u8  speed               = ide_rate_filter(drive, xferspeed);
        u8  itr_addr            = drive->dn ? 0x44 : 0x40;
-       u32 itr_mask            = speed < XFER_MW_DMA_0 ? 0x30070000 :
-                                (speed < XFER_UDMA_0   ? 0xc0070000 : 0xc03800ff);
-       u32 new_itr             = get_speed_setting(speed, info);
        u32 old_itr             = 0;
+       u32 itr_mask, new_itr;
+
+       /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
+       if (drive->media != ide_disk)
+               speed = min_t(u8, speed, XFER_PIO_4);
+
+       itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 :
+                 (speed < XFER_UDMA_0   ? 0xc0070000 : 0xc03800ff);
+
+       new_itr = get_speed_setting(speed, info);
 
        /*
         * Disable on-chip PIO FIFO/buffer (and PIO MST mode as well)
@@ -633,12 +629,19 @@ static int hpt37x_tune_chipset(ide_drive_t *drive, u8 xferspeed)
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev  *dev    = hwif->pci_dev;
        struct hpt_info *info   = pci_get_drvdata(dev);
-       u8  speed               = hpt3xx_ratefilter(drive, xferspeed);
+       u8  speed               = ide_rate_filter(drive, xferspeed);
        u8  itr_addr            = 0x40 + (drive->dn * 4);
-       u32 itr_mask            = speed < XFER_MW_DMA_0 ? 0x303c0000 :
-                                (speed < XFER_UDMA_0   ? 0xc03c0000 : 0xc1c001ff);
-       u32 new_itr             = get_speed_setting(speed, info);
        u32 old_itr             = 0;
+       u32 itr_mask, new_itr;
+
+       /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
+       if (drive->media != ide_disk)
+               speed = min_t(u8, speed, XFER_PIO_4);
+
+       itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 :
+                 (speed < XFER_UDMA_0   ? 0xc03c0000 : 0xc1c001ff);
+
+       new_itr = get_speed_setting(speed, info);
 
        pci_read_config_dword(dev, itr_addr, &old_itr);
        new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask);
@@ -667,24 +670,6 @@ static void hpt3xx_tune_drive(ide_drive_t *drive, u8 pio)
        (void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio);
 }
 
-/*
- * This allows the configuration of ide_pci chipset registers
- * for cards that learn about the drive's UDMA, DMA, PIO capabilities
- * after the drive is reported by the OS.  Initially designed for
- * HPT366 UDMA chipset by HighPoint|Triones Technologies, Inc.
- *
- */
-static int config_chipset_for_dma(ide_drive_t *drive)
-{
-       u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive));
-
-       if (!speed)
-               return 0;
-
-       (void) hpt3xx_tune_chipset(drive, speed);
-       return ide_dma_enable(drive);
-}
-
 static int hpt3xx_quirkproc(ide_drive_t *drive)
 {
        struct hd_driveid *id   = drive->id;
@@ -739,7 +724,7 @@ static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
 {
        drive->init_speed = 0;
 
-       if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+       if (ide_tune_dma(drive))
                return 0;
 
        if (ide_use_fast_pio(drive))
@@ -1271,6 +1256,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
        hwif->intrproc                  = &hpt3xx_intrproc;
        hwif->maskproc                  = &hpt3xx_maskproc;
        hwif->busproc                   = &hpt3xx_busproc;
+       hwif->udma_filter               = &hpt3xx_udma_filter;
 
        /*
         * HPT3xxN chips have some complications:
@@ -1528,18 +1514,28 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
                goto init_single;
 
        /*
-        * HPT36x chips are single channel and
-        * do not seem to have the channel enable bit...
+        * HPT36x chips have one channel per function and have
+        * both channel enable bits located differently and visible
+        * to both functions -- really stupid design decision... :-(
+        * Bit 4 is for the primary channel, bit 5 for the secondary.
         */
        d->channels = 1;
-       d->enablebits[0].reg = 0;
+       d->enablebits[0].mask = d->enablebits[0].val = 0x10;
 
        if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
-               u8  pin1 = 0, pin2 = 0;
+               u8  mcr1 = 0, pin1 = 0, pin2 = 0;
                int ret;
 
                pci_set_drvdata(dev2, info[rev]);
 
+               /*
+                * Now we'll have to force both channels enabled if
+                * at least one of them has been enabled by BIOS...
+                */
+               pci_read_config_byte(dev, 0x50, &mcr1);
+               if (mcr1 & 0x30)
+                       pci_write_config_byte(dev, 0x50, mcr1 | 0x30);
+
                pci_read_config_byte(dev,  PCI_INTERRUPT_PIN, &pin1);
                pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
                if (pin1 != pin2 && dev->irq == dev2->irq) {