diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-06-15 15:00:22 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-06-15 15:00:22 -0400 |
commit | 21bd33a656a60daadc475ce330272f4410ae27b7 (patch) | |
tree | 863d48760628ee3b599e9843307cb4e4efd81ce1 /drivers/ide | |
parent | f361037631ba547ea88adf8d2359d810c1b2605a (diff) |
opti621: use PCI clock value provided by controller
Use PCI clock value provided by controller instead of depending on
a default (or user supplied) value.
Based on a bugreport from Juergen Kosel & inspired by pata_opti.c code.
Tested-by: Juergen Kosel <juergen.kosel@gmx.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/pci/opti621.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index 65f180738947..7547fa2d83ac 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c | |||
@@ -193,11 +193,10 @@ typedef struct pio_clocks_s { | |||
193 | int recovery_time; /* Recovery time (clocks) */ | 193 | int recovery_time; /* Recovery time (clocks) */ |
194 | } pio_clocks_t; | 194 | } pio_clocks_t; |
195 | 195 | ||
196 | static void compute_clocks(int pio, pio_clocks_t *clks) | 196 | static void compute_clocks(int pio, pio_clocks_t *clks, int bus_speed) |
197 | { | 197 | { |
198 | if (pio != PIO_NOT_EXIST) { | 198 | if (pio != PIO_NOT_EXIST) { |
199 | int adr_setup, data_pls; | 199 | int adr_setup, data_pls; |
200 | int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock(); | ||
201 | 200 | ||
202 | adr_setup = ide_pio_timings[pio].setup_time; | 201 | adr_setup = ide_pio_timings[pio].setup_time; |
203 | data_pls = ide_pio_timings[pio].active_time; | 202 | data_pls = ide_pio_timings[pio].active_time; |
@@ -234,7 +233,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
234 | u8 pio1 = 0, pio2 = 0; | 233 | u8 pio1 = 0, pio2 = 0; |
235 | pio_clocks_t first, second; | 234 | pio_clocks_t first, second; |
236 | int ax, drdy; | 235 | int ax, drdy; |
237 | u8 cycle1, cycle2, misc; | 236 | u8 cycle1, cycle2, misc, clk; |
238 | ide_hwif_t *hwif = HWIF(drive); | 237 | ide_hwif_t *hwif = HWIF(drive); |
239 | 238 | ||
240 | /* sets drive->drive_data for both drives */ | 239 | /* sets drive->drive_data for both drives */ |
@@ -242,8 +241,26 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
242 | pio1 = hwif->drives[0].drive_data; | 241 | pio1 = hwif->drives[0].drive_data; |
243 | pio2 = hwif->drives[1].drive_data; | 242 | pio2 = hwif->drives[1].drive_data; |
244 | 243 | ||
245 | compute_clocks(pio1, &first); | 244 | spin_lock_irqsave(&opti621_lock, flags); |
246 | compute_clocks(pio2, &second); | 245 | |
246 | reg_base = hwif->io_ports.data_addr; | ||
247 | |||
248 | /* allow Register-B */ | ||
249 | outb(0xc0, reg_base + CNTRL_REG); | ||
250 | /* hmm, setupvic.exe does this ;-) */ | ||
251 | outb(0xff, reg_base + 5); | ||
252 | /* if reads 0xff, adapter not exist? */ | ||
253 | (void)inb(reg_base + CNTRL_REG); | ||
254 | /* if reads 0xc0, no interface exist? */ | ||
255 | read_reg(CNTRL_REG); | ||
256 | |||
257 | /* check CLK speed */ | ||
258 | clk = read_reg(STRAP_REG) & 1; | ||
259 | |||
260 | printk(KERN_INFO "%s: CLK = %d MHz\n", hwif->name, clk ? 25 : 33); | ||
261 | |||
262 | compute_clocks(pio1, &first, clk ? 25 : 33); | ||
263 | compute_clocks(pio2, &second, clk ? 25 : 33); | ||
247 | 264 | ||
248 | /* ax = max(a1,a2) */ | 265 | /* ax = max(a1,a2) */ |
249 | ax = (first.address_time < second.address_time) ? second.address_time : first.address_time; | 266 | ax = (first.address_time < second.address_time) ? second.address_time : first.address_time; |
@@ -266,21 +283,6 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
266 | second.recovery_time, drdy); | 283 | second.recovery_time, drdy); |
267 | #endif | 284 | #endif |
268 | 285 | ||
269 | spin_lock_irqsave(&opti621_lock, flags); | ||
270 | |||
271 | reg_base = hwif->io_ports.data_addr; | ||
272 | |||
273 | /* allow Register-B */ | ||
274 | outb(0xc0, reg_base + CNTRL_REG); | ||
275 | /* hmm, setupvic.exe does this ;-) */ | ||
276 | outb(0xff, reg_base + 5); | ||
277 | /* if reads 0xff, adapter not exist? */ | ||
278 | (void)inb(reg_base + CNTRL_REG); | ||
279 | /* if reads 0xc0, no interface exist? */ | ||
280 | read_reg(CNTRL_REG); | ||
281 | /* read version, probably 0 */ | ||
282 | read_reg(STRAP_REG); | ||
283 | |||
284 | /* program primary drive */ | 286 | /* program primary drive */ |
285 | /* select Index-0 for Register-A */ | 287 | /* select Index-0 for Register-A */ |
286 | write_reg(0, MISC_REG); | 288 | write_reg(0, MISC_REG); |