aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2006-12-13 03:35:52 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-13 12:05:55 -0500
commit26c068daf089aa21844236c97d05049b9497cc0a (patch)
tree9ccc30ecb97c7df3cefd10f240c9fa524be9356d
parent73d1dd93c462b52512685fe118159eafc7eb9f7e (diff)
[PATCH] ide: HPT3xx: fix PCI clock detection
Use the f_CNT value saved by the HighPoint BIOS if available as reading it directly would give us a wrong PCI frequency after DPLL has already been calibrated by BIOS. Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/ide/pci/hpt366.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 4968b16fa307..9fd50801d382 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -70,6 +70,8 @@
70 * - fix/remove bad/unused timing tables and use one set of tables for the whole 70 * - fix/remove bad/unused timing tables and use one set of tables for the whole
71 * HPT37x chip family; save space by introducing the separate transfer mode 71 * HPT37x chip family; save space by introducing the separate transfer mode
72 * table in which the mode lookup is done 72 * table in which the mode lookup is done
73 * - use f_CNT value saved by the HighPoint BIOS as reading it directly gives
74 * the wrong PCI frequency since DPLL has already been calibrated by BIOS
73 * - fix the hotswap code: it caused RESET- to glitch when tristating the bus, 75 * - fix the hotswap code: it caused RESET- to glitch when tristating the bus,
74 * and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead 76 * and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead
75 * - pass to init_chipset() handlers a copy of the IDE PCI device structure as 77 * - pass to init_chipset() handlers a copy of the IDE PCI device structure as
@@ -1010,8 +1012,8 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
1010 struct hpt_info *info = ide_get_hwifdata(hwif); 1012 struct hpt_info *info = ide_get_hwifdata(hwif);
1011 struct pci_dev *dev = hwif->pci_dev; 1013 struct pci_dev *dev = hwif->pci_dev;
1012 int adjust, i; 1014 int adjust, i;
1013 u16 freq; 1015 u16 freq = 0;
1014 u32 pll; 1016 u32 pll, temp = 0;
1015 u8 reg5bh = 0, mcr1 = 0; 1017 u8 reg5bh = 0, mcr1 = 0;
1016 1018
1017 /* 1019 /*
@@ -1025,15 +1027,34 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
1025 pci_write_config_byte(dev, 0x5b, 0x23); 1027 pci_write_config_byte(dev, 0x5b, 0x23);
1026 1028
1027 /* 1029 /*
1028 * set up the PLL. we need to adjust it so that it's stable. 1030 * We'll have to read f_CNT value in order to determine
1029 * freq = Tpll * 192 / Tpci 1031 * the PCI clock frequency according to the following ratio:
1030 * 1032 *
1031 * Todo. For non x86 should probably check the dword is 1033 * f_CNT = Fpci * 192 / Fdpll
1032 * set to 0xABCDExxx indicating the BIOS saved f_CNT 1034 *
1035 * First try reading the register in which the HighPoint BIOS
1036 * saves f_CNT value before reprogramming the DPLL from its
1037 * default setting (which differs for the various chips).
1038 * In case the signature check fails, we'll have to resort to
1039 * reading the f_CNT register itself in hopes that nobody has
1040 * touched the DPLL yet...
1033 */ 1041 */
1034 pci_read_config_word(dev, 0x78, &freq); 1042 pci_read_config_dword(dev, 0x70, &temp);
1035 freq &= 0x1FF; 1043 if ((temp & 0xFFFFF000) != 0xABCDE000) {
1036 1044 int i;
1045
1046 printk(KERN_WARNING "HPT37X: no clock data saved by BIOS\n");
1047
1048 /* Calculate the average value of f_CNT */
1049 for (temp = i = 0; i < 128; i++) {
1050 pci_read_config_word(dev, 0x78, &freq);
1051 temp += freq & 0x1ff;
1052 mdelay(1);
1053 }
1054 freq = temp / 128;
1055 } else
1056 freq = temp & 0x1ff;
1057
1037 /* 1058 /*
1038 * HPT3xxN chips use different PCI clock information. 1059 * HPT3xxN chips use different PCI clock information.
1039 * Currently we always set up the PLL for them. 1060 * Currently we always set up the PLL for them.
@@ -1095,11 +1116,8 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
1095 info->flags |= PLL_MODE; 1116 info->flags |= PLL_MODE;
1096 1117
1097 /* 1118 /*
1098 * FIXME: make this work correctly, esp with 372N as per 1119 * Adjust the PLL based upon the PCI clock, enable it, and
1099 * reference driver code. 1120 * wait for stabilization...
1100 *
1101 * adjust PLL based upon PCI clock, enable it, and wait for
1102 * stabilization.
1103 */ 1121 */
1104 adjust = 0; 1122 adjust = 0;
1105 freq = (pll < F_LOW_PCI_50) ? 2 : 4; 1123 freq = (pll < F_LOW_PCI_50) ? 2 : 4;