aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/au1000
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/au1000')
-rw-r--r--arch/mips/au1000/common/time.c98
1 files changed, 0 insertions, 98 deletions
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
index 6768638883ea..fa1c62f05515 100644
--- a/arch/mips/au1000/common/time.c
+++ b/arch/mips/au1000/common/time.c
@@ -53,9 +53,6 @@ static unsigned long r4k_cur; /* What counter should be at next timer irq */
53int no_au1xxx_32khz; 53int no_au1xxx_32khz;
54extern int allow_au1k_wait; /* default off for CP0 Counter */ 54extern int allow_au1k_wait; /* default off for CP0 Counter */
55 55
56/* Cycle counter value at the previous timer interrupt.. */
57static unsigned int timerhi = 0, timerlo = 0;
58
59#ifdef CONFIG_PM 56#ifdef CONFIG_PM
60#if HZ < 100 || HZ > 1000 57#if HZ < 100 || HZ > 1000
61#error "unsupported HZ value! Must be in [100,1000]" 58#error "unsupported HZ value! Must be in [100,1000]"
@@ -90,10 +87,6 @@ void mips_timer_interrupt(void)
90 goto null; 87 goto null;
91 88
92 do { 89 do {
93 count = read_c0_count();
94 timerhi += (count < timerlo); /* Wrap around */
95 timerlo = count;
96
97 kstat_this_cpu.irqs[irq]++; 90 kstat_this_cpu.irqs[irq]++;
98 do_timer(1); 91 do_timer(1);
99#ifndef CONFIG_SMP 92#ifndef CONFIG_SMP
@@ -297,88 +290,6 @@ unsigned long cal_r4koff(void)
297 return (cpu_speed / HZ); 290 return (cpu_speed / HZ);
298} 291}
299 292
300/* This is for machines which generate the exact clock. */
301#define USECS_PER_JIFFY (1000000/HZ)
302#define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff)
303
304static unsigned long
305div64_32(unsigned long v1, unsigned long v2, unsigned long v3)
306{
307 unsigned long r0;
308 do_div64_32(r0, v1, v2, v3);
309 return r0;
310}
311
312static unsigned long do_fast_cp0_gettimeoffset(void)
313{
314 u32 count;
315 unsigned long res, tmp;
316 unsigned long r0;
317
318 /* Last jiffy when do_fast_gettimeoffset() was called. */
319 static unsigned long last_jiffies=0;
320 unsigned long quotient;
321
322 /*
323 * Cached "1/(clocks per usec)*2^32" value.
324 * It has to be recalculated once each jiffy.
325 */
326 static unsigned long cached_quotient=0;
327
328 tmp = jiffies;
329
330 quotient = cached_quotient;
331
332 if (tmp && last_jiffies != tmp) {
333 last_jiffies = tmp;
334 if (last_jiffies != 0) {
335 r0 = div64_32(timerhi, timerlo, tmp);
336 quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0);
337 cached_quotient = quotient;
338 }
339 }
340
341 /* Get last timer tick in absolute kernel time */
342 count = read_c0_count();
343
344 /* .. relative to previous jiffy (32 bits is enough) */
345 count -= timerlo;
346
347 __asm__("multu\t%1,%2\n\t"
348 "mfhi\t%0"
349 : "=r" (res)
350 : "r" (count), "r" (quotient)
351 : "hi", "lo", GCC_REG_ACCUM);
352
353 /*
354 * Due to possible jiffies inconsistencies, we need to check
355 * the result so that we'll get a timer that is monotonic.
356 */
357 if (res >= USECS_PER_JIFFY)
358 res = USECS_PER_JIFFY-1;
359
360 return res;
361}
362
363#ifdef CONFIG_PM
364static unsigned long do_fast_pm_gettimeoffset(void)
365{
366 unsigned long pc0;
367 unsigned long offset;
368
369 pc0 = au_readl(SYS_TOYREAD);
370 au_sync();
371 offset = pc0 - last_pc0;
372 if (offset > 2*MATCH20_INC) {
373 printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n",
374 (unsigned)offset, (unsigned)last_pc0,
375 (unsigned)last_match20, (unsigned)pc0);
376 }
377 offset = (unsigned long)((offset * 305) / 10);
378 return offset;
379}
380#endif
381
382void __init plat_timer_setup(struct irqaction *irq) 293void __init plat_timer_setup(struct irqaction *irq)
383{ 294{
384 unsigned int est_freq; 295 unsigned int est_freq;
@@ -416,7 +327,6 @@ void __init plat_timer_setup(struct irqaction *irq)
416 unsigned int c0_status; 327 unsigned int c0_status;
417 328
418 printk("WARNING: no 32KHz clock found.\n"); 329 printk("WARNING: no 32KHz clock found.\n");
419 do_gettimeoffset = do_fast_cp0_gettimeoffset;
420 330
421 /* Ensure we get CPO_COUNTER interrupts. 331 /* Ensure we get CPO_COUNTER interrupts.
422 */ 332 */
@@ -441,19 +351,11 @@ void __init plat_timer_setup(struct irqaction *irq)
441 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); 351 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
442 startup_match20_interrupt(counter0_irq); 352 startup_match20_interrupt(counter0_irq);
443 353
444 do_gettimeoffset = do_fast_pm_gettimeoffset;
445
446 /* We can use the real 'wait' instruction. 354 /* We can use the real 'wait' instruction.
447 */ 355 */
448 allow_au1k_wait = 1; 356 allow_au1k_wait = 1;
449 } 357 }
450 358
451#else
452 /* We have to do this here instead of in timer_init because
453 * the generic code in arch/mips/kernel/time.c will write
454 * over our function pointer.
455 */
456 do_gettimeoffset = do_fast_cp0_gettimeoffset;
457#endif 359#endif
458} 360}
459 361