diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2006-12-13 03:35:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-13 12:05:55 -0500 |
commit | 26c068daf089aa21844236c97d05049b9497cc0a (patch) | |
tree | 9ccc30ecb97c7df3cefd10f240c9fa524be9356d | |
parent | 73d1dd93c462b52512685fe118159eafc7eb9f7e (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.c | 46 |
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; |