aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/pci
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2007-09-11 16:28:35 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-09-11 16:28:35 -0400
commit7293136810936bbde403bcb67ac1b4dbae4dd790 (patch)
treebdbb37d76378bd9e96ef716130c253211ea0c46d /drivers/ide/pci
parent35198234a26fdc0f858774e3ba143796323059a0 (diff)
hpt366: fix PCI clock detection for HPT374 (take 4)
HPT374 BIOS seems to only save f_CNT register value for the function #0 before re-tuning DPLL (that causes the driver to report obviously distorted f_CNT for the function #1) -- fix this by always reading the saved f_CNT register value from the function #0 in the driver's init_chipset() method. While at it, introduce 'chip_type' for holding the 'struct hpt_info' field of the same name and replace the structure assignment with memcpy()... Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/pci')
-rw-r--r--drivers/ide/pci/hpt366.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 2cd74c345a6c..f87eec970574 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/ide/pci/hpt366.c Version 1.10 Jun 29, 2007 2 * linux/drivers/ide/pci/hpt366.c Version 1.11 Aug 11, 2007
3 * 3 *
4 * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> 4 * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
5 * Portions Copyright (C) 2001 Sun Microsystems, Inc. 5 * Portions Copyright (C) 2001 Sun Microsystems, Inc.
@@ -68,7 +68,8 @@
68 * HPT37x chip family; save space by introducing the separate transfer mode 68 * HPT37x chip family; save space by introducing the separate transfer mode
69 * table in which the mode lookup is done 69 * table in which the mode lookup is done
70 * - use f_CNT value saved by the HighPoint BIOS as reading it directly gives 70 * - use f_CNT value saved by the HighPoint BIOS as reading it directly gives
71 * the wrong PCI frequency since DPLL has already been calibrated by BIOS 71 * the wrong PCI frequency since DPLL has already been calibrated by BIOS;
72 * read it only from the function 0 of HPT374 chips
72 * - fix the hotswap code: it caused RESET- to glitch when tristating the bus, 73 * - fix the hotswap code: it caused RESET- to glitch when tristating the bus,
73 * and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead 74 * and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead
74 * - pass to init_chipset() handlers a copy of the IDE PCI device structure as 75 * - pass to init_chipset() handlers a copy of the IDE PCI device structure as
@@ -981,6 +982,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
981 struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL); 982 struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL);
982 unsigned long io_base = pci_resource_start(dev, 4); 983 unsigned long io_base = pci_resource_start(dev, 4);
983 u8 pci_clk, dpll_clk = 0; /* PCI and DPLL clock in MHz */ 984 u8 pci_clk, dpll_clk = 0; /* PCI and DPLL clock in MHz */
985 u8 chip_type;
984 enum ata_clock clock; 986 enum ata_clock clock;
985 987
986 if (info == NULL) { 988 if (info == NULL) {
@@ -992,7 +994,8 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
992 * Copy everything from a static "template" structure 994 * Copy everything from a static "template" structure
993 * to just allocated per-chip hpt_info structure. 995 * to just allocated per-chip hpt_info structure.
994 */ 996 */
995 *info = *(struct hpt_info *)pci_get_drvdata(dev); 997 memcpy(info, pci_get_drvdata(dev), sizeof(struct hpt_info));
998 chip_type = info->chip_type;
996 999
997 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); 1000 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
998 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); 1001 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
@@ -1002,7 +1005,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
1002 /* 1005 /*
1003 * First, try to estimate the PCI clock frequency... 1006 * First, try to estimate the PCI clock frequency...
1004 */ 1007 */
1005 if (info->chip_type >= HPT370) { 1008 if (chip_type >= HPT370) {
1006 u8 scr1 = 0; 1009 u8 scr1 = 0;
1007 u16 f_cnt = 0; 1010 u16 f_cnt = 0;
1008 u32 temp = 0; 1011 u32 temp = 0;
@@ -1016,7 +1019,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
1016 * HighPoint does this for HPT372A. 1019 * HighPoint does this for HPT372A.
1017 * NOTE: This register is only writeable via I/O space. 1020 * NOTE: This register is only writeable via I/O space.
1018 */ 1021 */
1019 if (info->chip_type == HPT372A) 1022 if (chip_type == HPT372A)
1020 outb(0x0e, io_base + 0x9c); 1023 outb(0x0e, io_base + 0x9c);
1021 1024
1022 /* 1025 /*
@@ -1034,13 +1037,28 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
1034 * First try reading the register in which the HighPoint BIOS 1037 * First try reading the register in which the HighPoint BIOS
1035 * saves f_CNT value before reprogramming the DPLL from its 1038 * saves f_CNT value before reprogramming the DPLL from its
1036 * default setting (which differs for the various chips). 1039 * default setting (which differs for the various chips).
1037 * NOTE: This register is only accessible via I/O space.
1038 * 1040 *
1039 * In case the signature check fails, we'll have to resort to 1041 * NOTE: This register is only accessible via I/O space;
1040 * reading the f_CNT register itself in hopes that nobody has 1042 * HPT374 BIOS only saves it for the function 0, so we have to
1041 * touched the DPLL yet... 1043 * always read it from there -- no need to check the result of
1044 * pci_get_slot() for the function 0 as the whole device has
1045 * been already "pinned" (via function 1) in init_setup_hpt374()
1046 */
1047 if (chip_type == HPT374 && (PCI_FUNC(dev->devfn) & 1)) {
1048 struct pci_dev *dev1 = pci_get_slot(dev->bus,
1049 dev->devfn - 1);
1050 unsigned long io_base = pci_resource_start(dev1, 4);
1051
1052 temp = inl(io_base + 0x90);
1053 pci_dev_put(dev1);
1054 } else
1055 temp = inl(io_base + 0x90);
1056
1057 /*
1058 * In case the signature check fails, we'll have to
1059 * resort to reading the f_CNT register itself in hopes
1060 * that nobody has touched the DPLL yet...
1042 */ 1061 */
1043 temp = inl(io_base + 0x90);
1044 if ((temp & 0xFFFFF000) != 0xABCDE000) { 1062 if ((temp & 0xFFFFF000) != 0xABCDE000) {
1045 int i; 1063 int i;
1046 1064
@@ -1120,7 +1138,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
1120 * We also don't like using the DPLL because this causes glitches 1138 * We also don't like using the DPLL because this causes glitches
1121 * on PRST-/SRST- when the state engine gets reset... 1139 * on PRST-/SRST- when the state engine gets reset...
1122 */ 1140 */
1123 if (info->chip_type >= HPT374 || info->settings[clock] == NULL) { 1141 if (chip_type >= HPT374 || info->settings[clock] == NULL) {
1124 u16 f_low, delta = pci_clk < 50 ? 2 : 4; 1142 u16 f_low, delta = pci_clk < 50 ? 2 : 4;
1125 int adjust; 1143 int adjust;
1126 1144
@@ -1190,7 +1208,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
1190 /* Point to this chip's own instance of the hpt_info structure. */ 1208 /* Point to this chip's own instance of the hpt_info structure. */
1191 pci_set_drvdata(dev, info); 1209 pci_set_drvdata(dev, info);
1192 1210
1193 if (info->chip_type >= HPT370) { 1211 if (chip_type >= HPT370) {
1194 u8 mcr1, mcr4; 1212 u8 mcr1, mcr4;
1195 1213
1196 /* 1214 /*
@@ -1209,7 +1227,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
1209 * the MISC. register to stretch the UltraDMA Tss timing. 1227 * the MISC. register to stretch the UltraDMA Tss timing.
1210 * NOTE: This register is only writeable via I/O space. 1228 * NOTE: This register is only writeable via I/O space.
1211 */ 1229 */
1212 if (info->chip_type == HPT371N && clock == ATA_CLOCK_66MHZ) 1230 if (chip_type == HPT371N && clock == ATA_CLOCK_66MHZ)
1213 1231
1214 outb(inb(io_base + 0x9c) | 0x04, io_base + 0x9c); 1232 outb(inb(io_base + 0x9c) | 0x04, io_base + 0x9c);
1215 1233