aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2007-04-26 03:19:25 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 15:16:39 -0400
commit28e21c8c0d44cd63bad4c62f94ef0c5a1cb8402c (patch)
tree76f511c2abc018b1836dad6afc1b0aba57f9704e /drivers
parentbd1d5ec64fff579e624b7c50c8a737da112efe5f (diff)
pata_hpt3x2n: Add HPT371N support and other bits
Yes its no longer 3x2n but 3xxn, I can rename it if you want Jeff - Don't reset both ports each time (Sergei) - If we can't get a DPLL then abort entirely - Use ioport access for clock (from drivers/ide) - Add HPT371N support (from drivers/ide) Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/pata_hpt3x2n.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 78323923143a..6a34521b9e01 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -8,10 +8,10 @@
8 * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> 8 * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
9 * Portions Copyright (C) 2001 Sun Microsystems, Inc. 9 * Portions Copyright (C) 2001 Sun Microsystems, Inc.
10 * Portions Copyright (C) 2003 Red Hat Inc 10 * Portions Copyright (C) 2003 Red Hat Inc
11 * Portions Copyright (C) 2005-2006 MontaVista Software, Inc.
11 * 12 *
12 * 13 *
13 * TODO 14 * TODO
14 * 371N
15 * Work out best PLL policy 15 * Work out best PLL policy
16 */ 16 */
17 17
@@ -142,6 +142,7 @@ static int hpt3x2n_cable_detect(struct ata_port *ap)
142/** 142/**
143 * hpt3x2n_pre_reset - reset the hpt3x2n bus 143 * hpt3x2n_pre_reset - reset the hpt3x2n bus
144 * @ap: ATA port to reset 144 * @ap: ATA port to reset
145 * @deadline: deadline jiffies for the operation
145 * 146 *
146 * Perform the initial reset handling for the 3x2n series controllers. 147 * Perform the initial reset handling for the 3x2n series controllers.
147 * Reset the hardware and state machine, 148 * Reset the hardware and state machine,
@@ -151,8 +152,7 @@ static int hpt3xn_pre_reset(struct ata_port *ap)
151{ 152{
152 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 153 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
153 /* Reset the state machine */ 154 /* Reset the state machine */
154 pci_write_config_byte(pdev, 0x50, 0x37); 155 pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
155 pci_write_config_byte(pdev, 0x54, 0x37);
156 udelay(100); 156 udelay(100);
157 return ata_std_prereset(ap); 157 return ata_std_prereset(ap);
158} 158}
@@ -433,8 +433,9 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev)
433{ 433{
434 unsigned long freq; 434 unsigned long freq;
435 u32 fcnt; 435 u32 fcnt;
436 unsigned long iobase = pci_resource_start(pdev, 4);
436 437
437 pci_read_config_dword(pdev, 0x70/*CHECKME*/, &fcnt); 438 fcnt = inl(iobase + 0x90); /* Not PCI readable for some chips */
438 if ((fcnt >> 12) != 0xABCDE) { 439 if ((fcnt >> 12) != 0xABCDE) {
439 printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n"); 440 printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n");
440 return 33; /* Not BIOS set */ 441 return 33; /* Not BIOS set */
@@ -503,6 +504,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
503 unsigned int pci_mhz; 504 unsigned int pci_mhz;
504 unsigned int f_low, f_high; 505 unsigned int f_low, f_high;
505 int adjust; 506 int adjust;
507 unsigned long iobase = pci_resource_start(dev, 4);
506 508
507 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); 509 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
508 class_rev &= 0xFF; 510 class_rev &= 0xFF;
@@ -512,6 +514,11 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
512 if (class_rev < 6) 514 if (class_rev < 6)
513 return -ENODEV; 515 return -ENODEV;
514 break; 516 break;
517 case PCI_DEVICE_ID_TTI_HPT371:
518 if (class_rev < 2)
519 return -ENODEV;
520 /* 371N if rev > 1 */
521 break;
515 case PCI_DEVICE_ID_TTI_HPT372: 522 case PCI_DEVICE_ID_TTI_HPT372:
516 /* 372N if rev >= 1*/ 523 /* 372N if rev >= 1*/
517 if (class_rev == 0) 524 if (class_rev == 0)
@@ -539,6 +546,19 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
539 irqmask &= ~0x10; 546 irqmask &= ~0x10;
540 pci_write_config_byte(dev, 0x5a, irqmask); 547 pci_write_config_byte(dev, 0x5a, irqmask);
541 548
549 /*
550 * HPT371 chips physically have only one channel, the secondary one,
551 * but the primary channel registers do exist! Go figure...
552 * So, we manually disable the non-existing channel here
553 * (if the BIOS hasn't done this already).
554 */
555 if (dev->device == PCI_DEVICE_ID_TTI_HPT371) {
556 u8 mcr1;
557 pci_read_config_byte(dev, 0x50, &mcr1);
558 mcr1 &= ~0x04;
559 pci_write_config_byte(dev, 0x50, mcr1);
560 }
561
542 /* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or 562 /* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or
543 50 for UDMA100. Right now we always use 66 */ 563 50 for UDMA100. Right now we always use 66 */
544 564
@@ -557,14 +577,24 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
557 break; 577 break;
558 pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); 578 pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
559 } 579 }
560 if (adjust == 8) 580 if (adjust == 8) {
561 printk(KERN_WARNING "hpt3xn: DPLL did not stabilize.\n"); 581 printk(KERN_WARNING "hpt3x2n: DPLL did not stabilize.\n");
582 return -ENODEV;
583 }
562 584
563 /* Set our private data up. We only need a few flags so we use 585 /* Set our private data up. We only need a few flags so we use
564 it directly */ 586 it directly */
565 port->private_data = NULL; 587 port->private_data = NULL;
566 if (pci_mhz > 60) 588 if (pci_mhz > 60) {
567 port->private_data = (void *)PCI66; 589 port->private_data = (void *)PCI66;
590 /*
591 * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in
592 * the MISC. register to stretch the UltraDMA Tss timing.
593 * NOTE: This register is only writeable via I/O space.
594 */
595 if (dev->device == PCI_DEVICE_ID_TTI_HPT371)
596 outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
597 }
568 598
569 /* Now kick off ATA set up */ 599 /* Now kick off ATA set up */
570 port_info[0] = port_info[1] = port; 600 port_info[0] = port_info[1] = port;
@@ -573,6 +603,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
573 603
574static const struct pci_device_id hpt3x2n[] = { 604static const struct pci_device_id hpt3x2n[] = {
575 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, 605 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
606 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), },
576 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), }, 607 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
577 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), }, 608 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
578 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), }, 609 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), },