diff options
author | Albert Lee <albertcc@tw.ibm.com> | 2007-07-03 16:28:36 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-07-03 16:28:36 -0400 |
commit | 8006bf56e360a4db71d304df778870a371a9e930 (patch) | |
tree | 9471ba5fd85ce42c8ec6253893520371762e513e /drivers/ide/pci/pdc202xx_new.c | |
parent | 52374f890c1d0d64148d55a20d995a0b3e0ae987 (diff) |
ide: pdc202xx_new PLL input clock fix
Recently the PLL input clock of Promise 2027x is sometimes detected
higher than expected (e.g. 20.027 MHz compared to 16.714 MHz).
It seems sometimes the mdelay() function is not as precise as it
used to be. Per Alan's advice, HT or power management might affect
the precision of mdelay().
This patch calls gettimeofday() to measure the time elapsed and
calculate the PLL input clock accordingly.
Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Bahadir Balban <bahadir.balban@gmail.com>
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/pci/pdc202xx_new.c')
-rw-r--r-- | drivers/ide/pci/pdc202xx_new.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index cc0bfdcf1f19..0765dce6948e 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c | |||
@@ -306,11 +306,13 @@ static long __devinit read_counter(u32 dma_base) | |||
306 | */ | 306 | */ |
307 | static long __devinit detect_pll_input_clock(unsigned long dma_base) | 307 | static long __devinit detect_pll_input_clock(unsigned long dma_base) |
308 | { | 308 | { |
309 | struct timeval start_time, end_time; | ||
309 | long start_count, end_count; | 310 | long start_count, end_count; |
310 | long pll_input; | 311 | long pll_input, usec_elapsed; |
311 | u8 scr1; | 312 | u8 scr1; |
312 | 313 | ||
313 | start_count = read_counter(dma_base); | 314 | start_count = read_counter(dma_base); |
315 | do_gettimeofday(&start_time); | ||
314 | 316 | ||
315 | /* Start the test mode */ | 317 | /* Start the test mode */ |
316 | outb(0x01, dma_base + 0x01); | 318 | outb(0x01, dma_base + 0x01); |
@@ -322,6 +324,7 @@ static long __devinit detect_pll_input_clock(unsigned long dma_base) | |||
322 | mdelay(10); | 324 | mdelay(10); |
323 | 325 | ||
324 | end_count = read_counter(dma_base); | 326 | end_count = read_counter(dma_base); |
327 | do_gettimeofday(&end_time); | ||
325 | 328 | ||
326 | /* Stop the test mode */ | 329 | /* Stop the test mode */ |
327 | outb(0x01, dma_base + 0x01); | 330 | outb(0x01, dma_base + 0x01); |
@@ -333,7 +336,10 @@ static long __devinit detect_pll_input_clock(unsigned long dma_base) | |||
333 | * Calculate the input clock in Hz | 336 | * Calculate the input clock in Hz |
334 | * (the clock counter is 30 bit wide and counts down) | 337 | * (the clock counter is 30 bit wide and counts down) |
335 | */ | 338 | */ |
336 | pll_input = ((start_count - end_count) & 0x3ffffff) * 100; | 339 | usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 + |
340 | (end_time.tv_usec - start_time.tv_usec); | ||
341 | pll_input = ((start_count - end_count) & 0x3ffffff) / 10 * | ||
342 | (10000000 / usec_elapsed); | ||
337 | 343 | ||
338 | DBG("start[%ld] end[%ld]\n", start_count, end_count); | 344 | DBG("start[%ld] end[%ld]\n", start_count, end_count); |
339 | 345 | ||