aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-18 02:33:07 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-23 05:24:12 -0500
commitce54d1616302117fa98513ae916bb3333e1c02ea (patch)
tree408a33e3857188287e1ba240d82d0518eff7ffd7
parent021ee9a6da1cfc57f6a6c769c3c898bdd4753108 (diff)
pata_amd: update mode selection for NV PATAs
Cable detection on NV PATA hosts isn't implemented and the CBLID- cable isn't wired according to the sepc either, so both host-side and generic drive-side cable detections are broken. Till now, nv_cable_detect() relied on peeking BIOS and ACPI configurations to upgrade to 80C but this often results in misdetection of 40C cable as 80C. Also, the original implementation was broken in that by the time BIOS configuration is read it has already been cleared by programming PIO0 during reset. This patch reimplements NV mode selection such that... * BIOS configuration value is stored during driver attach and restored on detach. * Cable type is fixed to ATA_CBL_PATA_IGN and mode selection is soley done by nv_mode_filter() which peeks both BIOS and ACPI configurations and filter accordingly. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/pata_amd.c129
1 files changed, 93 insertions, 36 deletions
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index e71125a4bd9b..761a66608d7b 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -220,6 +220,62 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev)
220 timing_setup(ap, adev, 0x40, adev->dma_mode, 4); 220 timing_setup(ap, adev, 0x40, adev->dma_mode, 4);
221} 221}
222 222
223/* Both host-side and drive-side detection results are worthless on NV
224 * PATAs. Ignore them and just follow what BIOS configured. Both the
225 * current configuration in PCI config reg and ACPI GTM result are
226 * cached during driver attach and are consulted to select transfer
227 * mode.
228 */
229static unsigned long nv_mode_filter(struct ata_device *dev,
230 unsigned long xfer_mask)
231{
232 static const unsigned int udma_mask_map[] =
233 { ATA_UDMA2, ATA_UDMA1, ATA_UDMA0, 0,
234 ATA_UDMA3, ATA_UDMA4, ATA_UDMA5, ATA_UDMA6 };
235 struct ata_port *ap = dev->link->ap;
236 char acpi_str[32] = "";
237 u32 saved_udma, udma;
238 const struct ata_acpi_gtm *gtm;
239 unsigned long bios_limit = 0, acpi_limit = 0, limit;
240
241 /* find out what BIOS configured */
242 udma = saved_udma = (unsigned long)ap->host->private_data;
243
244 if (ap->port_no == 0)
245 udma >>= 16;
246 if (dev->devno == 0)
247 udma >>= 8;
248
249 if ((udma & 0xc0) == 0xc0)
250 bios_limit = ata_pack_xfermask(0, 0, udma_mask_map[udma & 0x7]);
251
252 /* consult ACPI GTM too */
253 gtm = ata_acpi_init_gtm(ap);
254 if (gtm) {
255 acpi_limit = ata_acpi_gtm_xfermask(dev, gtm);
256
257 snprintf(acpi_str, sizeof(acpi_str), " (%u:%u:0x%x)",
258 gtm->drive[0].dma, gtm->drive[1].dma, gtm->flags);
259 }
260
261 /* be optimistic, EH can take care of things if something goes wrong */
262 limit = bios_limit | acpi_limit;
263
264 /* If PIO or DMA isn't configured at all, don't limit. Let EH
265 * handle it.
266 */
267 if (!(limit & ATA_MASK_PIO))
268 limit |= ATA_MASK_PIO;
269 if (!(limit & (ATA_MASK_MWDMA | ATA_MASK_UDMA)))
270 limit |= ATA_MASK_MWDMA | ATA_MASK_UDMA;
271
272 ata_port_printk(ap, KERN_DEBUG, "nv_mode_filter: 0x%lx&0x%lx->0x%lx, "
273 "BIOS=0x%lx (0x%x) ACPI=0x%lx%s\n",
274 xfer_mask, limit, xfer_mask & limit, bios_limit,
275 saved_udma, acpi_limit, acpi_str);
276
277 return xfer_mask & limit;
278}
223 279
224/** 280/**
225 * nv_probe_init - cable detection 281 * nv_probe_init - cable detection
@@ -252,32 +308,6 @@ static void nv_error_handler(struct ata_port *ap)
252 ata_std_postreset); 308 ata_std_postreset);
253} 309}
254 310
255static int nv_cable_detect(struct ata_port *ap)
256{
257 static const u8 bitmask[2] = {0x03, 0x0C};
258 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
259 u8 ata66;
260 u16 udma;
261 int cbl;
262
263 pci_read_config_byte(pdev, 0x52, &ata66);
264 if (ata66 & bitmask[ap->port_no])
265 cbl = ATA_CBL_PATA80;
266 else
267 cbl = ATA_CBL_PATA40;
268
269 /* We now have to double check because the Nvidia boxes BIOS
270 doesn't always set the cable bits but does set mode bits */
271 pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma);
272 if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400)
273 cbl = ATA_CBL_PATA80;
274 /* And a triple check across suspend/resume with ACPI around */
275 if (ata_acpi_init_gtm(ap) &&
276 ata_acpi_cbl_80wire(ap, ata_acpi_init_gtm(ap)))
277 cbl = ATA_CBL_PATA80;
278 return cbl;
279}
280
281/** 311/**
282 * nv100_set_piomode - set initial PIO mode data 312 * nv100_set_piomode - set initial PIO mode data
283 * @ap: ATA interface 313 * @ap: ATA interface
@@ -315,6 +345,14 @@ static void nv133_set_dmamode(struct ata_port *ap, struct ata_device *adev)
315 timing_setup(ap, adev, 0x50, adev->dma_mode, 4); 345 timing_setup(ap, adev, 0x50, adev->dma_mode, 4);
316} 346}
317 347
348static void nv_host_stop(struct ata_host *host)
349{
350 u32 udma = (unsigned long)host->private_data;
351
352 /* restore PCI config register 0x60 */
353 pci_write_config_dword(to_pci_dev(host->dev), 0x60, udma);
354}
355
318static struct scsi_host_template amd_sht = { 356static struct scsi_host_template amd_sht = {
319 .module = THIS_MODULE, 357 .module = THIS_MODULE,
320 .name = DRV_NAME, 358 .name = DRV_NAME,
@@ -479,7 +517,8 @@ static struct ata_port_operations nv100_port_ops = {
479 .thaw = ata_bmdma_thaw, 517 .thaw = ata_bmdma_thaw,
480 .error_handler = nv_error_handler, 518 .error_handler = nv_error_handler,
481 .post_internal_cmd = ata_bmdma_post_internal_cmd, 519 .post_internal_cmd = ata_bmdma_post_internal_cmd,
482 .cable_detect = nv_cable_detect, 520 .cable_detect = ata_cable_ignore,
521 .mode_filter = nv_mode_filter,
483 522
484 .bmdma_setup = ata_bmdma_setup, 523 .bmdma_setup = ata_bmdma_setup,
485 .bmdma_start = ata_bmdma_start, 524 .bmdma_start = ata_bmdma_start,
@@ -496,6 +535,7 @@ static struct ata_port_operations nv100_port_ops = {
496 .irq_on = ata_irq_on, 535 .irq_on = ata_irq_on,
497 536
498 .port_start = ata_sff_port_start, 537 .port_start = ata_sff_port_start,
538 .host_stop = nv_host_stop,
499}; 539};
500 540
501static struct ata_port_operations nv133_port_ops = { 541static struct ata_port_operations nv133_port_ops = {
@@ -512,7 +552,8 @@ static struct ata_port_operations nv133_port_ops = {
512 .thaw = ata_bmdma_thaw, 552 .thaw = ata_bmdma_thaw,
513 .error_handler = nv_error_handler, 553 .error_handler = nv_error_handler,
514 .post_internal_cmd = ata_bmdma_post_internal_cmd, 554 .post_internal_cmd = ata_bmdma_post_internal_cmd,
515 .cable_detect = nv_cable_detect, 555 .cable_detect = ata_cable_ignore,
556 .mode_filter = nv_mode_filter,
516 557
517 .bmdma_setup = ata_bmdma_setup, 558 .bmdma_setup = ata_bmdma_setup,
518 .bmdma_start = ata_bmdma_start, 559 .bmdma_start = ata_bmdma_start,
@@ -529,6 +570,7 @@ static struct ata_port_operations nv133_port_ops = {
529 .irq_on = ata_irq_on, 570 .irq_on = ata_irq_on,
530 571
531 .port_start = ata_sff_port_start, 572 .port_start = ata_sff_port_start,
573 .host_stop = nv_host_stop,
532}; 574};
533 575
534static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) 576static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -615,7 +657,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
615 .port_ops = &amd100_port_ops 657 .port_ops = &amd100_port_ops
616 } 658 }
617 }; 659 };
618 const struct ata_port_info *ppi[] = { NULL, NULL }; 660 struct ata_port_info pi;
661 const struct ata_port_info *ppi[] = { &pi, NULL };
619 static int printed_version; 662 static int printed_version;
620 int type = id->driver_data; 663 int type = id->driver_data;
621 u8 fifo; 664 u8 fifo;
@@ -629,6 +672,19 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
629 if (type == 1 && pdev->revision > 0x7) 672 if (type == 1 && pdev->revision > 0x7)
630 type = 2; 673 type = 2;
631 674
675 /* Serenade ? */
676 if (type == 5 && pdev->subsystem_vendor == PCI_VENDOR_ID_AMD &&
677 pdev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE)
678 type = 6; /* UDMA 100 only */
679
680 /*
681 * Okay, type is determined now. Apply type-specific workarounds.
682 */
683 pi = info[type];
684
685 if (type < 3)
686 ata_pci_clear_simplex(pdev);
687
632 /* Check for AMD7411 */ 688 /* Check for AMD7411 */
633 if (type == 3) 689 if (type == 3)
634 /* FIFO is broken */ 690 /* FIFO is broken */
@@ -636,16 +692,17 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
636 else 692 else
637 pci_write_config_byte(pdev, 0x41, fifo | 0xF0); 693 pci_write_config_byte(pdev, 0x41, fifo | 0xF0);
638 694
639 /* Serenade ? */ 695 /* Cable detection on Nvidia chips doesn't work too well,
640 if (type == 5 && pdev->subsystem_vendor == PCI_VENDOR_ID_AMD && 696 * cache BIOS programmed UDMA mode.
641 pdev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) 697 */
642 type = 6; /* UDMA 100 only */ 698 if (type == 7 || type == 8) {
699 u32 udma;
643 700
644 if (type < 3) 701 pci_read_config_dword(pdev, 0x60, &udma);
645 ata_pci_clear_simplex(pdev); 702 pi.private_data = (void *)(unsigned long)udma;
703 }
646 704
647 /* And fire it up */ 705 /* And fire it up */
648 ppi[0] = &info[type];
649 return ata_pci_init_one(pdev, ppi); 706 return ata_pci_init_one(pdev, ppi);
650} 707}
651 708