[MIPS] Fixup migration to GENERIC_TIME

Since we already moved to GENERIC_TIME, we should implement alternatives
of old do_gettimeoffset routines to get sub-jiffies resolution from
gettimeofday(). This patch includes:

* MIPS clocksource support (based on works by Manish Lachwani).
* remove unused gettimeoffset routines and related codes.
* remove unised 64bit do_div64_32().
* simplify mips_hpt_init. (no argument needed, __init tag)
* simplify c0_hpt_timer_init. (no need to write to c0_count)
* remove some hpt_init routines.
* mips_hpt_mask variable to specify bitmask of hpt value.
* convert jmr3927_do_gettimeoffset to jmr3927_hpt_read.
* convert ip27_do_gettimeoffset to ip27_hpt_read.
* convert bcm1480_do_gettimeoffset to bcm1480_hpt_read.
* simplify sb1250 hpt functions. (no need to subtract and shift)

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by Atsushi Nemoto and committed by Ralf Baechle 16b7b2ac 70e46f48

+103 -522
+8 -31
Documentation/mips/time.README
··· 38 39 a) Implements functions required by Linux common code: 40 time_init 41 - do_gettimeofday 42 - do_settimeofday 43 44 b) provides an abstraction of RTC and null RTC implementation as default. 45 extern unsigned long (*rtc_get_time)(void); 46 extern int (*rtc_set_time)(unsigned long); 47 48 - c) a set of gettimeoffset functions for different CPUs and different 49 - needs. 50 - 51 - d) high-level and low-level timer interrupt routines where the timer 52 - interrupt source may or may not be the CPU timer. The high-level 53 - routine is dispatched through do_IRQ() while the low-level is 54 dispatched in assemably code (usually int-handler.S) 55 56 ··· 68 c) (optional) board-specific RTC routines. 69 70 d) (optional) mips_hpt_frequency - It must be definied if the board 71 - is using CPU counter for timer interrupt or it is using fixed rate 72 - gettimeoffset(). 73 74 75 PORTING GUIDE ··· 82 83 If the answer is no, you need a timer to provide the timer interrupt 84 at 100 HZ speed. 85 - 86 - You cannot use the fast gettimeoffset functions, i.e., 87 - 88 - unsigned long fixed_rate_gettimeoffset(void); 89 - unsigned long calibrate_div32_gettimeoffset(void); 90 - unsigned long calibrate_div64_gettimeoffset(void); 91 - 92 - You can use null_gettimeoffset() will gives the same time resolution as 93 - jiffy. Or you can implement your own gettimeoffset (probably based on 94 - some ad hoc hardware on your machine.) 95 96 c) The following sub steps assume your CPU has counter register. 97 Do you plan to use the CPU counter register as the timer interrupt ··· 107 board_time_init() - 108 a) (optional) set up RTC routines, 109 b) (optional) calibrate and set the mips_hpt_frequency 110 - (only needed if you intended to use fixed_rate_gettimeoffset 111 - or use cpu counter as timer interrupt source) 112 113 plat_timer_setup() - 114 a) (optional) over-write any choices made above by time_init(). ··· 138 For example, you may define your own timer interrupt routine, which does 139 some of its own processing and then calls timer_interrupt(). 140 141 - You can also over-ride any of the built-in functions (gettimeoffset, 142 - RTC routines and/or timer interrupt routine). 143 144 145 PORTING NOTES FOR SMP ··· 171 172 You can also do the low-level version of those interrupt routines, 173 following similar dispatching routes described above. 174 - 175 - Note about do_gettimeoffset(): 176 - 177 - It is very likely the CPU counter registers are not sync'ed up in a SMP box. 178 - Therefore you cannot really use the many of the existing routines that 179 - are based on CPU counter. You should wirte your own gettimeoffset rouinte 180 - if you want intra-jiffy resolution.
··· 38 39 a) Implements functions required by Linux common code: 40 time_init 41 42 b) provides an abstraction of RTC and null RTC implementation as default. 43 extern unsigned long (*rtc_get_time)(void); 44 extern int (*rtc_set_time)(unsigned long); 45 46 + c) high-level and low-level timer interrupt routines where the timer 47 + interrupt source may or may not be the CPU timer. The high-level 48 + routine is dispatched through do_IRQ() while the low-level is 49 dispatched in assemably code (usually int-handler.S) 50 51 ··· 73 c) (optional) board-specific RTC routines. 74 75 d) (optional) mips_hpt_frequency - It must be definied if the board 76 + is using CPU counter for timer interrupt. 77 78 79 PORTING GUIDE ··· 88 89 If the answer is no, you need a timer to provide the timer interrupt 90 at 100 HZ speed. 91 92 c) The following sub steps assume your CPU has counter register. 93 Do you plan to use the CPU counter register as the timer interrupt ··· 123 board_time_init() - 124 a) (optional) set up RTC routines, 125 b) (optional) calibrate and set the mips_hpt_frequency 126 + (only needed if you intended to use cpu counter as timer interrupt 127 + source) 128 129 plat_timer_setup() - 130 a) (optional) over-write any choices made above by time_init(). ··· 154 For example, you may define your own timer interrupt routine, which does 155 some of its own processing and then calls timer_interrupt(). 156 157 + You can also over-ride any of the built-in functions (RTC routines 158 + and/or timer interrupt routine). 159 160 161 PORTING NOTES FOR SMP ··· 187 188 You can also do the low-level version of those interrupt routines, 189 following similar dispatching routes described above.
-98
arch/mips/au1000/common/time.c
··· 53 int no_au1xxx_32khz; 54 extern int allow_au1k_wait; /* default off for CP0 Counter */ 55 56 - /* Cycle counter value at the previous timer interrupt.. */ 57 - static unsigned int timerhi = 0, timerlo = 0; 58 - 59 #ifdef CONFIG_PM 60 #if HZ < 100 || HZ > 1000 61 #error "unsupported HZ value! Must be in [100,1000]" ··· 87 goto null; 88 89 do { 90 - count = read_c0_count(); 91 - timerhi += (count < timerlo); /* Wrap around */ 92 - timerlo = count; 93 - 94 kstat_this_cpu.irqs[irq]++; 95 do_timer(1); 96 #ifndef CONFIG_SMP ··· 290 return (cpu_speed / HZ); 291 } 292 293 - /* This is for machines which generate the exact clock. */ 294 - #define USECS_PER_JIFFY (1000000/HZ) 295 - #define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff) 296 - 297 - static unsigned long 298 - div64_32(unsigned long v1, unsigned long v2, unsigned long v3) 299 - { 300 - unsigned long r0; 301 - do_div64_32(r0, v1, v2, v3); 302 - return r0; 303 - } 304 - 305 - static unsigned long do_fast_cp0_gettimeoffset(void) 306 - { 307 - u32 count; 308 - unsigned long res, tmp; 309 - unsigned long r0; 310 - 311 - /* Last jiffy when do_fast_gettimeoffset() was called. */ 312 - static unsigned long last_jiffies=0; 313 - unsigned long quotient; 314 - 315 - /* 316 - * Cached "1/(clocks per usec)*2^32" value. 317 - * It has to be recalculated once each jiffy. 318 - */ 319 - static unsigned long cached_quotient=0; 320 - 321 - tmp = jiffies; 322 - 323 - quotient = cached_quotient; 324 - 325 - if (tmp && last_jiffies != tmp) { 326 - last_jiffies = tmp; 327 - if (last_jiffies != 0) { 328 - r0 = div64_32(timerhi, timerlo, tmp); 329 - quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0); 330 - cached_quotient = quotient; 331 - } 332 - } 333 - 334 - /* Get last timer tick in absolute kernel time */ 335 - count = read_c0_count(); 336 - 337 - /* .. relative to previous jiffy (32 bits is enough) */ 338 - count -= timerlo; 339 - 340 - __asm__("multu\t%1,%2\n\t" 341 - "mfhi\t%0" 342 - : "=r" (res) 343 - : "r" (count), "r" (quotient) 344 - : "hi", "lo", GCC_REG_ACCUM); 345 - 346 - /* 347 - * Due to possible jiffies inconsistencies, we need to check 348 - * the result so that we'll get a timer that is monotonic. 349 - */ 350 - if (res >= USECS_PER_JIFFY) 351 - res = USECS_PER_JIFFY-1; 352 - 353 - return res; 354 - } 355 - 356 - #ifdef CONFIG_PM 357 - static unsigned long do_fast_pm_gettimeoffset(void) 358 - { 359 - unsigned long pc0; 360 - unsigned long offset; 361 - 362 - pc0 = au_readl(SYS_TOYREAD); 363 - au_sync(); 364 - offset = pc0 - last_pc0; 365 - if (offset > 2*MATCH20_INC) { 366 - printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", 367 - (unsigned)offset, (unsigned)last_pc0, 368 - (unsigned)last_match20, (unsigned)pc0); 369 - } 370 - offset = (unsigned long)((offset * 305) / 10); 371 - return offset; 372 - } 373 - #endif 374 - 375 void __init plat_timer_setup(struct irqaction *irq) 376 { 377 unsigned int est_freq; ··· 327 unsigned int c0_status; 328 329 printk("WARNING: no 32KHz clock found.\n"); 330 - do_gettimeoffset = do_fast_cp0_gettimeoffset; 331 332 /* Ensure we get CPO_COUNTER interrupts. 333 */ ··· 351 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); 352 startup_match20_interrupt(counter0_irq); 353 354 - do_gettimeoffset = do_fast_pm_gettimeoffset; 355 - 356 /* We can use the real 'wait' instruction. 357 */ 358 allow_au1k_wait = 1; 359 } 360 361 - #else 362 - /* We have to do this here instead of in timer_init because 363 - * the generic code in arch/mips/kernel/time.c will write 364 - * over our function pointer. 365 - */ 366 - do_gettimeoffset = do_fast_cp0_gettimeoffset; 367 #endif 368 } 369
··· 53 int no_au1xxx_32khz; 54 extern int allow_au1k_wait; /* default off for CP0 Counter */ 55 56 #ifdef CONFIG_PM 57 #if HZ < 100 || HZ > 1000 58 #error "unsupported HZ value! Must be in [100,1000]" ··· 90 goto null; 91 92 do { 93 kstat_this_cpu.irqs[irq]++; 94 do_timer(1); 95 #ifndef CONFIG_SMP ··· 297 return (cpu_speed / HZ); 298 } 299 300 void __init plat_timer_setup(struct irqaction *irq) 301 { 302 unsigned int est_freq; ··· 416 unsigned int c0_status; 417 418 printk("WARNING: no 32KHz clock found.\n"); 419 420 /* Ensure we get CPO_COUNTER interrupts. 421 */ ··· 441 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); 442 startup_match20_interrupt(counter0_irq); 443 444 /* We can use the real 'wait' instruction. 445 */ 446 allow_au1k_wait = 1; 447 } 448 449 #endif 450 } 451
+1 -8
arch/mips/dec/time.c
··· 160 return ioasic_read(IO_REG_FCTR); 161 } 162 163 - static void dec_ioasic_hpt_init(unsigned int count) 164 - { 165 - ioasic_write(IO_REG_FCTR, ioasic_read(IO_REG_FCTR) - count); 166 - } 167 - 168 169 void __init dec_time_init(void) 170 { ··· 169 mips_timer_state = dec_timer_state; 170 mips_timer_ack = dec_timer_ack; 171 172 - if (!cpu_has_counter && IOASIC) { 173 /* For pre-R4k systems we use the I/O ASIC's counter. */ 174 mips_hpt_read = dec_ioasic_hpt_read; 175 - mips_hpt_init = dec_ioasic_hpt_init; 176 - } 177 178 /* Set up the rate of periodic DS1287 interrupts. */ 179 CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A);
··· 160 return ioasic_read(IO_REG_FCTR); 161 } 162 163 164 void __init dec_time_init(void) 165 { ··· 174 mips_timer_state = dec_timer_state; 175 mips_timer_ack = dec_timer_ack; 176 177 + if (!cpu_has_counter && IOASIC) 178 /* For pre-R4k systems we use the I/O ASIC's counter. */ 179 mips_hpt_read = dec_ioasic_hpt_read; 180 181 /* Set up the rate of periodic DS1287 interrupts. */ 182 CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A);
+8 -32
arch/mips/jmr3927/rbhma3100/setup.c
··· 170 while (1); 171 } 172 173 #define USE_RTC_DS1742 174 #ifdef USE_RTC_DS1742 175 extern void rtc_ds1742_init(unsigned long base); 176 #endif 177 static void __init jmr3927_time_init(void) 178 { 179 #ifdef USE_RTC_DS1742 180 if (jmr3927_have_nvram()) { 181 rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR); ··· 191 #endif 192 } 193 194 - unsigned long jmr3927_do_gettimeoffset(void); 195 - 196 void __init plat_timer_setup(struct irqaction *irq) 197 { 198 - do_gettimeoffset = jmr3927_do_gettimeoffset; 199 - 200 jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; 201 jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; 202 jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; ··· 203 } 204 205 #define USECS_PER_JIFFY (1000000/HZ) 206 - 207 - unsigned long jmr3927_do_gettimeoffset(void) 208 - { 209 - unsigned long count; 210 - unsigned long res = 0; 211 - 212 - /* MUST read TRR before TISR. */ 213 - count = jmr3927_tmrptr->trr; 214 - 215 - if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) { 216 - /* timer interrupt is pending. use Max value. */ 217 - res = USECS_PER_JIFFY - 1; 218 - } else { 219 - /* convert to usec */ 220 - /* res = count / (JMR3927_TIMER_CLK / 1000000); */ 221 - res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000); 222 - 223 - /* 224 - * Due to possible jiffies inconsistencies, we need to check 225 - * the result so that we'll get a timer that is monotonic. 226 - */ 227 - if (res >= USECS_PER_JIFFY) 228 - res = USECS_PER_JIFFY-1; 229 - } 230 - 231 - return res; 232 - } 233 - 234 235 //#undef DO_WRITE_THROUGH 236 #define DO_WRITE_THROUGH
··· 170 while (1); 171 } 172 173 + static unsigned int jmr3927_hpt_read(void) 174 + { 175 + /* We assume this function is called xtime_lock held. */ 176 + return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr; 177 + } 178 + 179 #define USE_RTC_DS1742 180 #ifdef USE_RTC_DS1742 181 extern void rtc_ds1742_init(unsigned long base); 182 #endif 183 static void __init jmr3927_time_init(void) 184 { 185 + mips_hpt_read = jmr3927_hpt_read; 186 + mips_hpt_frequency = JMR3927_TIMER_CLK; 187 #ifdef USE_RTC_DS1742 188 if (jmr3927_have_nvram()) { 189 rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR); ··· 183 #endif 184 } 185 186 void __init plat_timer_setup(struct irqaction *irq) 187 { 188 jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; 189 jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; 190 jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; ··· 199 } 200 201 #define USECS_PER_JIFFY (1000000/HZ) 202 203 //#undef DO_WRITE_THROUGH 204 #define DO_WRITE_THROUGH
+53 -266
arch/mips/kernel/time.c
··· 11 * Free Software Foundation; either version 2 of the License, or (at your 12 * option) any later version. 13 */ 14 #include <linux/types.h> 15 #include <linux/kernel.h> 16 #include <linux/init.h> ··· 68 int (*rtc_mips_set_mmss)(unsigned long); 69 70 71 - /* usecs per counter cycle, shifted to left by 32 bits */ 72 - static unsigned int sll32_usecs_per_cycle; 73 - 74 /* how many counter cycles in a jiffy */ 75 static unsigned long cycles_per_jiffy __read_mostly; 76 - 77 - /* Cycle counter value at the previous timer interrupt.. */ 78 - static unsigned int timerhi, timerlo; 79 80 /* expirelo is the count value for next CPU timer interrupt */ 81 static unsigned int expirelo; ··· 88 return 0; 89 } 90 91 - static void null_hpt_init(unsigned int count) 92 { 93 /* nothing */ 94 } ··· 123 return read_c0_count(); 124 } 125 126 - /* For use solely as a high precision timer. */ 127 - static void c0_hpt_init(unsigned int count) 128 - { 129 - write_c0_count(read_c0_count() - count); 130 - } 131 - 132 /* For use both as a high precision timer and an interrupt source. */ 133 - static void c0_hpt_timer_init(unsigned int count) 134 { 135 - count = read_c0_count() - count; 136 - expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; 137 - write_c0_count(expirelo - cycles_per_jiffy); 138 write_c0_compare(expirelo); 139 - write_c0_count(count); 140 } 141 142 int (*mips_timer_state)(void); 143 void (*mips_timer_ack)(void); 144 unsigned int (*mips_hpt_read)(void); 145 - void (*mips_hpt_init)(unsigned int); 146 - 147 - /* 148 - * Gettimeoffset routines. These routines returns the time duration 149 - * since last timer interrupt in usecs. 150 - * 151 - * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset. 152 - * Otherwise use calibrate_gettimeoffset() 153 - * 154 - * If the CPU does not have the counter register, you can either supply 155 - * your own gettimeoffset() routine, or use null_gettimeoffset(), which 156 - * gives the same resolution as HZ. 157 - */ 158 - 159 - static unsigned long null_gettimeoffset(void) 160 - { 161 - return 0; 162 - } 163 - 164 - 165 - /* The function pointer to one of the gettimeoffset funcs. */ 166 - unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset; 167 - 168 - 169 - static unsigned long fixed_rate_gettimeoffset(void) 170 - { 171 - u32 count; 172 - unsigned long res; 173 - 174 - /* Get last timer tick in absolute kernel time */ 175 - count = mips_hpt_read(); 176 - 177 - /* .. relative to previous jiffy (32 bits is enough) */ 178 - count -= timerlo; 179 - 180 - __asm__("multu %1,%2" 181 - : "=h" (res) 182 - : "r" (count), "r" (sll32_usecs_per_cycle) 183 - : "lo", GCC_REG_ACCUM); 184 - 185 - /* 186 - * Due to possible jiffies inconsistencies, we need to check 187 - * the result so that we'll get a timer that is monotonic. 188 - */ 189 - if (res >= USECS_PER_JIFFY) 190 - res = USECS_PER_JIFFY - 1; 191 - 192 - return res; 193 - } 194 - 195 - 196 - /* 197 - * Cached "1/(clocks per usec) * 2^32" value. 198 - * It has to be recalculated once each jiffy. 199 - */ 200 - static unsigned long cached_quotient; 201 - 202 - /* Last jiffy when calibrate_divXX_gettimeoffset() was called. */ 203 - static unsigned long last_jiffies; 204 - 205 - /* 206 - * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej. 207 - */ 208 - static unsigned long calibrate_div32_gettimeoffset(void) 209 - { 210 - u32 count; 211 - unsigned long res, tmp; 212 - unsigned long quotient; 213 - 214 - tmp = jiffies; 215 - 216 - quotient = cached_quotient; 217 - 218 - if (last_jiffies != tmp) { 219 - last_jiffies = tmp; 220 - if (last_jiffies != 0) { 221 - unsigned long r0; 222 - do_div64_32(r0, timerhi, timerlo, tmp); 223 - do_div64_32(quotient, USECS_PER_JIFFY, 224 - USECS_PER_JIFFY_FRAC, r0); 225 - cached_quotient = quotient; 226 - } 227 - } 228 - 229 - /* Get last timer tick in absolute kernel time */ 230 - count = mips_hpt_read(); 231 - 232 - /* .. relative to previous jiffy (32 bits is enough) */ 233 - count -= timerlo; 234 - 235 - __asm__("multu %1,%2" 236 - : "=h" (res) 237 - : "r" (count), "r" (quotient) 238 - : "lo", GCC_REG_ACCUM); 239 - 240 - /* 241 - * Due to possible jiffies inconsistencies, we need to check 242 - * the result so that we'll get a timer that is monotonic. 243 - */ 244 - if (res >= USECS_PER_JIFFY) 245 - res = USECS_PER_JIFFY - 1; 246 - 247 - return res; 248 - } 249 - 250 - static unsigned long calibrate_div64_gettimeoffset(void) 251 - { 252 - u32 count; 253 - unsigned long res, tmp; 254 - unsigned long quotient; 255 - 256 - tmp = jiffies; 257 - 258 - quotient = cached_quotient; 259 - 260 - if (last_jiffies != tmp) { 261 - last_jiffies = tmp; 262 - if (last_jiffies) { 263 - unsigned long r0; 264 - __asm__(".set push\n\t" 265 - ".set mips3\n\t" 266 - "lwu %0,%3\n\t" 267 - "dsll32 %1,%2,0\n\t" 268 - "or %1,%1,%0\n\t" 269 - "ddivu $0,%1,%4\n\t" 270 - "mflo %1\n\t" 271 - "dsll32 %0,%5,0\n\t" 272 - "or %0,%0,%6\n\t" 273 - "ddivu $0,%0,%1\n\t" 274 - "mflo %0\n\t" 275 - ".set pop" 276 - : "=&r" (quotient), "=&r" (r0) 277 - : "r" (timerhi), "m" (timerlo), 278 - "r" (tmp), "r" (USECS_PER_JIFFY), 279 - "r" (USECS_PER_JIFFY_FRAC) 280 - : "hi", "lo", GCC_REG_ACCUM); 281 - cached_quotient = quotient; 282 - } 283 - } 284 - 285 - /* Get last timer tick in absolute kernel time */ 286 - count = mips_hpt_read(); 287 - 288 - /* .. relative to previous jiffy (32 bits is enough) */ 289 - count -= timerlo; 290 - 291 - __asm__("multu %1,%2" 292 - : "=h" (res) 293 - : "r" (count), "r" (quotient) 294 - : "lo", GCC_REG_ACCUM); 295 - 296 - /* 297 - * Due to possible jiffies inconsistencies, we need to check 298 - * the result so that we'll get a timer that is monotonic. 299 - */ 300 - if (res >= USECS_PER_JIFFY) 301 - res = USECS_PER_JIFFY - 1; 302 - 303 - return res; 304 - } 305 - 306 307 /* last time when xtime and rtc are sync'ed up */ 308 static long last_rtc_update; ··· 161 */ 162 irqreturn_t timer_interrupt(int irq, void *dev_id) 163 { 164 - unsigned long j; 165 - unsigned int count; 166 - 167 write_seqlock(&xtime_lock); 168 169 - count = mips_hpt_read(); 170 mips_timer_ack(); 171 - 172 - /* Update timerhi/timerlo for intra-jiffy calibration. */ 173 - timerhi += count < timerlo; /* Wrap around */ 174 - timerlo = count; 175 176 /* 177 * call the generic timer interrupt handling ··· 184 } else { 185 /* do it again in 60 s */ 186 last_rtc_update = xtime.tv_sec - 600; 187 - } 188 - } 189 - 190 - /* 191 - * If jiffies has overflown in this timer_interrupt, we must 192 - * update the timer[hi]/[lo] to make fast gettimeoffset funcs 193 - * quotient calc still valid. -arca 194 - * 195 - * The first timer interrupt comes late as interrupts are 196 - * enabled long after timers are initialized. Therefore the 197 - * high precision timer is fast, leading to wrong gettimeoffset() 198 - * calculations. We deal with it by setting it based on the 199 - * number of its ticks between the second and the third interrupt. 200 - * That is still somewhat imprecise, but it's a good estimate. 201 - * --macro 202 - */ 203 - j = jiffies; 204 - if (j < 4) { 205 - static unsigned int prev_count; 206 - static int hpt_initialized; 207 - 208 - switch (j) { 209 - case 0: 210 - timerhi = timerlo = 0; 211 - mips_hpt_init(count); 212 - break; 213 - case 2: 214 - prev_count = count; 215 - break; 216 - case 3: 217 - if (!hpt_initialized) { 218 - unsigned int c3 = 3 * (count - prev_count); 219 - 220 - timerhi = 0; 221 - timerlo = c3; 222 - mips_hpt_init(count - c3); 223 - hpt_initialized = 1; 224 - } 225 - break; 226 - default: 227 - break; 228 } 229 } 230 ··· 254 * 1) board_time_init() - 255 * a) (optional) set up RTC routines, 256 * b) (optional) calibrate and set the mips_hpt_frequency 257 - * (only needed if you intended to use fixed_rate_gettimeoffset 258 - * or use cpu counter as timer interrupt source) 259 * 2) setup xtime based on rtc_mips_get_time(). 260 - * 3) choose a appropriate gettimeoffset routine. 261 - * 4) calculate a couple of cached variables for later usage 262 - * 5) plat_timer_setup() - 263 * a) (optional) over-write any choices made above by time_init(). 264 * b) machine specific code should setup the timer irqaction. 265 * c) enable the timer interrupt ··· 310 } while (--i); 311 hpt_end = mips_hpt_read(); 312 313 - hpt_count = hpt_end - hpt_start; 314 hz = HZ; 315 frequency = (u64)hpt_count * (u64)hz; 316 317 return frequency >> log_2_loops; 318 } 319 320 void __init time_init(void) ··· 367 -xtime.tv_sec, -xtime.tv_nsec); 368 369 /* Choose appropriate high precision timer routines. */ 370 - if (!cpu_has_counter && !mips_hpt_read) { 371 /* No high precision timer -- sorry. */ 372 mips_hpt_read = null_hpt_read; 373 - mips_hpt_init = null_hpt_init; 374 - } else if (!mips_hpt_frequency && !mips_timer_state) { 375 /* A high precision timer of unknown frequency. */ 376 - if (!mips_hpt_read) { 377 /* No external high precision timer -- use R4k. */ 378 mips_hpt_read = c0_hpt_read; 379 - mips_hpt_init = c0_hpt_init; 380 - } 381 - 382 - if (cpu_has_mips32r1 || cpu_has_mips32r2 || 383 - (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || 384 - (current_cpu_data.isa_level == MIPS_CPU_ISA_II)) 385 - /* 386 - * We need to calibrate the counter but we don't have 387 - * 64-bit division. 388 - */ 389 - do_gettimeoffset = calibrate_div32_gettimeoffset; 390 - else 391 - /* 392 - * We need to calibrate the counter but we *do* have 393 - * 64-bit division. 394 - */ 395 - do_gettimeoffset = calibrate_div64_gettimeoffset; 396 } else { 397 /* We know counter frequency. Or we can get it. */ 398 if (!mips_hpt_read) { 399 /* No external high precision timer -- use R4k. */ 400 mips_hpt_read = c0_hpt_read; 401 402 - if (mips_timer_state) 403 - mips_hpt_init = c0_hpt_init; 404 - else { 405 /* No external timer interrupt -- use R4k. */ 406 mips_hpt_init = c0_hpt_timer_init; 407 mips_timer_ack = c0_timer_ack; ··· 390 if (!mips_hpt_frequency) 391 mips_hpt_frequency = calibrate_hpt(); 392 393 - do_gettimeoffset = fixed_rate_gettimeoffset; 394 - 395 /* Calculate cache parameters. */ 396 cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; 397 - 398 - /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ 399 - do_div64_32(sll32_usecs_per_cycle, 400 - 1000000, mips_hpt_frequency / 2, 401 - mips_hpt_frequency); 402 403 /* Report the high precision timer rate for a reference. */ 404 printk("Using %u.%03u MHz high precision timer.\n", ··· 404 mips_timer_ack = null_timer_ack; 405 406 /* This sets up the high precision timer for the first interrupt. */ 407 - mips_hpt_init(mips_hpt_read()); 408 409 /* 410 * Call board specific timer interrupt setup. ··· 418 * is not invoked accidentally. 419 */ 420 plat_timer_setup(&timer_irqaction); 421 } 422 423 #define FEBRUARY 2
··· 11 * Free Software Foundation; either version 2 of the License, or (at your 12 * option) any later version. 13 */ 14 + #include <linux/clocksource.h> 15 #include <linux/types.h> 16 #include <linux/kernel.h> 17 #include <linux/init.h> ··· 67 int (*rtc_mips_set_mmss)(unsigned long); 68 69 70 /* how many counter cycles in a jiffy */ 71 static unsigned long cycles_per_jiffy __read_mostly; 72 73 /* expirelo is the count value for next CPU timer interrupt */ 74 static unsigned int expirelo; ··· 93 return 0; 94 } 95 96 + static void __init null_hpt_init(void) 97 { 98 /* nothing */ 99 } ··· 128 return read_c0_count(); 129 } 130 131 /* For use both as a high precision timer and an interrupt source. */ 132 + static void __init c0_hpt_timer_init(void) 133 { 134 + expirelo = read_c0_count() + cycles_per_jiffy; 135 write_c0_compare(expirelo); 136 } 137 138 int (*mips_timer_state)(void); 139 void (*mips_timer_ack)(void); 140 unsigned int (*mips_hpt_read)(void); 141 + void (*mips_hpt_init)(void) __initdata = null_hpt_init; 142 + unsigned int mips_hpt_mask = 0xffffffff; 143 144 /* last time when xtime and rtc are sync'ed up */ 145 static long last_rtc_update; ··· 334 */ 335 irqreturn_t timer_interrupt(int irq, void *dev_id) 336 { 337 write_seqlock(&xtime_lock); 338 339 mips_timer_ack(); 340 341 /* 342 * call the generic timer interrupt handling ··· 365 } else { 366 /* do it again in 60 s */ 367 last_rtc_update = xtime.tv_sec - 600; 368 } 369 } 370 ··· 476 * 1) board_time_init() - 477 * a) (optional) set up RTC routines, 478 * b) (optional) calibrate and set the mips_hpt_frequency 479 + * (only needed if you intended to use cpu counter as timer interrupt 480 + * source) 481 * 2) setup xtime based on rtc_mips_get_time(). 482 + * 3) calculate a couple of cached variables for later usage 483 + * 4) plat_timer_setup() - 484 * a) (optional) over-write any choices made above by time_init(). 485 * b) machine specific code should setup the timer irqaction. 486 * c) enable the timer interrupt ··· 533 } while (--i); 534 hpt_end = mips_hpt_read(); 535 536 + hpt_count = (hpt_end - hpt_start) & mips_hpt_mask; 537 hz = HZ; 538 frequency = (u64)hpt_count * (u64)hz; 539 540 return frequency >> log_2_loops; 541 + } 542 + 543 + static cycle_t read_mips_hpt(void) 544 + { 545 + return (cycle_t)mips_hpt_read(); 546 + } 547 + 548 + static struct clocksource clocksource_mips = { 549 + .name = "MIPS", 550 + .read = read_mips_hpt, 551 + .is_continuous = 1, 552 + }; 553 + 554 + static void __init init_mips_clocksource(void) 555 + { 556 + u64 temp; 557 + u32 shift; 558 + 559 + if (!mips_hpt_frequency || mips_hpt_read == null_hpt_read) 560 + return; 561 + 562 + /* Calclate a somewhat reasonable rating value */ 563 + clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; 564 + /* Find a shift value */ 565 + for (shift = 32; shift > 0; shift--) { 566 + temp = (u64) NSEC_PER_SEC << shift; 567 + do_div(temp, mips_hpt_frequency); 568 + if ((temp >> 32) == 0) 569 + break; 570 + } 571 + clocksource_mips.shift = shift; 572 + clocksource_mips.mult = (u32)temp; 573 + clocksource_mips.mask = mips_hpt_mask; 574 + 575 + clocksource_register(&clocksource_mips); 576 } 577 578 void __init time_init(void) ··· 555 -xtime.tv_sec, -xtime.tv_nsec); 556 557 /* Choose appropriate high precision timer routines. */ 558 + if (!cpu_has_counter && !mips_hpt_read) 559 /* No high precision timer -- sorry. */ 560 mips_hpt_read = null_hpt_read; 561 + else if (!mips_hpt_frequency && !mips_timer_state) { 562 /* A high precision timer of unknown frequency. */ 563 + if (!mips_hpt_read) 564 /* No external high precision timer -- use R4k. */ 565 mips_hpt_read = c0_hpt_read; 566 } else { 567 /* We know counter frequency. Or we can get it. */ 568 if (!mips_hpt_read) { 569 /* No external high precision timer -- use R4k. */ 570 mips_hpt_read = c0_hpt_read; 571 572 + if (!mips_timer_state) { 573 /* No external timer interrupt -- use R4k. */ 574 mips_hpt_init = c0_hpt_timer_init; 575 mips_timer_ack = c0_timer_ack; ··· 598 if (!mips_hpt_frequency) 599 mips_hpt_frequency = calibrate_hpt(); 600 601 /* Calculate cache parameters. */ 602 cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; 603 604 /* Report the high precision timer rate for a reference. */ 605 printk("Using %u.%03u MHz high precision timer.\n", ··· 619 mips_timer_ack = null_timer_ack; 620 621 /* This sets up the high precision timer for the first interrupt. */ 622 + mips_hpt_init(); 623 624 /* 625 * Call board specific timer interrupt setup. ··· 633 * is not invoked accidentally. 634 */ 635 plat_timer_setup(&timer_irqaction); 636 + 637 + init_mips_clocksource(); 638 } 639 640 #define FEBRUARY 2
+2 -2
arch/mips/philips/pnx8550/common/time.c
··· 41 * 1) board_time_init() - 42 * a) (optional) set up RTC routines, 43 * b) (optional) calibrate and set the mips_hpt_frequency 44 - * (only needed if you intended to use fixed_rate_gettimeoffset 45 - * or use cpu counter as timer interrupt source) 46 */ 47 48 void pnx8550_time_init(void)
··· 41 * 1) board_time_init() - 42 * a) (optional) set up RTC routines, 43 * b) (optional) calibrate and set the mips_hpt_frequency 44 + * (only needed if you intended to use cpu counter as timer interrupt 45 + * source) 46 */ 47 48 void pnx8550_time_init(void)
+2 -4
arch/mips/pmc-sierra/yosemite/smp.c
··· 3 4 #include <asm/pmon.h> 5 #include <asm/titan_dep.h> 6 - 7 - extern unsigned int (*mips_hpt_read)(void); 8 - extern void (*mips_hpt_init)(unsigned int); 9 10 #define LAUNCHSTACK_SIZE 256 11 ··· 99 */ 100 void prom_init_secondary(void) 101 { 102 - mips_hpt_init(mips_hpt_read()); 103 104 set_c0_status(ST0_CO | ST0_IE | ST0_IM); 105 }
··· 3 4 #include <asm/pmon.h> 5 #include <asm/titan_dep.h> 6 + #include <asm/time.h> 7 8 #define LAUNCHSTACK_SIZE 256 9 ··· 101 */ 102 void prom_init_secondary(void) 103 { 104 + mips_hpt_init(); 105 106 set_c0_status(ST0_CO | ST0_IE | ST0_IM); 107 }
+7 -9
arch/mips/sgi-ip27/ip27-timer.c
··· 134 irq_exit(); 135 } 136 137 - unsigned long ip27_do_gettimeoffset(void) 138 - { 139 - unsigned long ct_cur1; 140 - ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY; 141 - return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000; 142 - } 143 - 144 /* Includes for ioc3_init(). */ 145 #include <asm/sn/types.h> 146 #include <asm/sn/sn0/addrs.h> ··· 241 setup_irq(irqno, &rt_irqaction); 242 } 243 244 void __init ip27_time_init(void) 245 { 246 xtime.tv_sec = get_m48t35_time(); 247 xtime.tv_nsec = 0; 248 - 249 - do_gettimeoffset = ip27_do_gettimeoffset; 250 } 251 252 void __init cpu_time_init(void)
··· 134 irq_exit(); 135 } 136 137 /* Includes for ioc3_init(). */ 138 #include <asm/sn/types.h> 139 #include <asm/sn/sn0/addrs.h> ··· 248 setup_irq(irqno, &rt_irqaction); 249 } 250 251 + static unsigned int ip27_hpt_read(void) 252 + { 253 + return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT); 254 + } 255 + 256 void __init ip27_time_init(void) 257 { 258 + mips_hpt_read = ip27_hpt_read; 259 + mips_hpt_frequency = CYCLES_PER_SEC; 260 xtime.tv_sec = get_m48t35_time(); 261 xtime.tv_nsec = 0; 262 } 263 264 void __init cpu_time_init(void)
+15 -18
arch/mips/sibyte/bcm1480/time.c
··· 47 #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 48 #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 49 50 extern int bcm1480_steal_irq(int irq); 51 52 void bcm1480_time_init(void) ··· 65 BUG(); 66 } 67 68 - if (!cpu) { 69 - /* Use our own gettimeoffset() routine */ 70 - do_gettimeoffset = bcm1480_gettimeoffset; 71 - } 72 - 73 bcm1480_mask_irq(cpu, irq); 74 75 /* Map the timer interrupt to ip[4] of this cpu */ ··· 75 /* Disable the timer and set up the count */ 76 __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); 77 __raw_writeq( 78 - #ifndef CONFIG_SIMULATION 79 - 1000000/HZ 80 - #else 81 - 50000/HZ 82 - #endif 83 , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); 84 85 /* Set the timer running */ ··· 119 } 120 } 121 122 - /* 123 - * We use our own do_gettimeoffset() instead of the generic one, 124 - * because the generic one does not work for SMP case. 125 - * In addition, since we use general timer 0 for system time, 126 - * we can get accurate intra-jiffy offset without calibration. 127 - */ 128 - unsigned long bcm1480_gettimeoffset(void) 129 { 130 unsigned long count = 131 __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); 132 133 - return 1000000/HZ - count; 134 }
··· 47 #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 48 #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 49 50 + #ifdef CONFIG_SIMULATION 51 + #define BCM1480_HPT_VALUE 50000 52 + #else 53 + #define BCM1480_HPT_VALUE 1000000 54 + #endif 55 + 56 extern int bcm1480_steal_irq(int irq); 57 58 void bcm1480_time_init(void) ··· 59 BUG(); 60 } 61 62 bcm1480_mask_irq(cpu, irq); 63 64 /* Map the timer interrupt to ip[4] of this cpu */ ··· 74 /* Disable the timer and set up the count */ 75 __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); 76 __raw_writeq( 77 + BCM1480_HPT_VALUE/HZ 78 , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); 79 80 /* Set the timer running */ ··· 122 } 123 } 124 125 + static unsigned int bcm1480_hpt_read(void) 126 { 127 + /* We assume this function is called xtime_lock held. */ 128 unsigned long count = 129 __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); 130 + return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count; 131 + } 132 133 + void __init bcm1480_hpt_setup(void) 134 + { 135 + mips_hpt_read = bcm1480_hpt_read; 136 + mips_hpt_frequency = BCM1480_HPT_VALUE; 137 }
+4 -24
arch/mips/sibyte/sb1250/time.c
··· 47 48 #define SB1250_HPT_NUM 3 49 #define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ 50 - #define SB1250_HPT_SHIFT ((sizeof(unsigned int)*8)-V_SCD_TIMER_WIDTH) 51 52 53 extern int sb1250_steal_irq(int irq); 54 55 static unsigned int sb1250_hpt_read(void); 56 - static void sb1250_hpt_init(unsigned int); 57 - 58 - static unsigned int hpt_offset; 59 60 void __init sb1250_hpt_setup(void) 61 { ··· 65 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, 66 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG))); 67 68 - /* 69 - * we need to fill 32 bits, so just use the upper 23 bits and pretend 70 - * the timer is going 512Mhz instead of 1Mhz 71 - */ 72 - mips_hpt_frequency = V_SCD_TIMER_FREQ << SB1250_HPT_SHIFT; 73 - mips_hpt_init = sb1250_hpt_init; 74 mips_hpt_read = sb1250_hpt_read; 75 } 76 } 77 ··· 141 142 /* 143 * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over 144 - * again. There's no easy way to set to a specific value so store init value 145 - * in hpt_offset and subtract each time. 146 - * 147 - * Note: Timer isn't full 32bits so shift it into the upper part making 148 - * it appear to run at a higher frequency. 149 */ 150 static unsigned int sb1250_hpt_read(void) 151 { ··· 149 150 count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT)))); 151 152 - count = (SB1250_HPT_VALUE - count) << SB1250_HPT_SHIFT; 153 - 154 - return count - hpt_offset; 155 - } 156 - 157 - static void sb1250_hpt_init(unsigned int count) 158 - { 159 - hpt_offset = count; 160 - return; 161 }
··· 47 48 #define SB1250_HPT_NUM 3 49 #define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ 50 51 52 extern int sb1250_steal_irq(int irq); 53 54 static unsigned int sb1250_hpt_read(void); 55 56 void __init sb1250_hpt_setup(void) 57 { ··· 69 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, 70 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG))); 71 72 + mips_hpt_frequency = V_SCD_TIMER_FREQ; 73 mips_hpt_read = sb1250_hpt_read; 74 + mips_hpt_mask = M_SCD_TIMER_INIT; 75 } 76 } 77 ··· 149 150 /* 151 * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over 152 + * again. 153 */ 154 static unsigned int sb1250_hpt_read(void) 155 { ··· 161 162 count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT)))); 163 164 + return SB1250_HPT_VALUE - count; 165 }
-21
include/asm-mips/div64.h
··· 83 #if (_MIPS_SZLONG == 64) 84 85 /* 86 - * Don't use this one in new code 87 - */ 88 - #define do_div64_32(res, high, low, base) ({ \ 89 - unsigned int __quot, __mod; \ 90 - unsigned long __div; \ 91 - unsigned int __low, __high, __base; \ 92 - \ 93 - __high = (high); \ 94 - __low = (low); \ 95 - __div = __high; \ 96 - __div = __div << 32 | __low; \ 97 - __base = (base); \ 98 - \ 99 - __mod = __div % __base; \ 100 - __div = __div / __base; \ 101 - \ 102 - __quot = __div; \ 103 - (res) = __quot; \ 104 - __mod; }) 105 - 106 - /* 107 * Hey, we're already 64-bit, no 108 * need to play games.. 109 */
··· 83 #if (_MIPS_SZLONG == 64) 84 85 /* 86 * Hey, we're already 64-bit, no 87 * need to play games.. 88 */
+1 -1
include/asm-mips/sibyte/sb1250.h
··· 51 extern void sb1250_unmask_irq(int cpu, int irq); 52 extern void sb1250_smp_finish(void); 53 54 extern void bcm1480_time_init(void); 55 - extern unsigned long bcm1480_gettimeoffset(void); 56 extern void bcm1480_mask_irq(int cpu, int irq); 57 extern void bcm1480_unmask_irq(int cpu, int irq); 58 extern void bcm1480_smp_finish(void);
··· 51 extern void sb1250_unmask_irq(int cpu, int irq); 52 extern void sb1250_smp_finish(void); 53 54 + extern void bcm1480_hpt_setup(void); 55 extern void bcm1480_time_init(void); 56 extern void bcm1480_mask_irq(int cpu, int irq); 57 extern void bcm1480_unmask_irq(int cpu, int irq); 58 extern void bcm1480_smp_finish(void);
+2 -8
include/asm-mips/time.h
··· 48 * If mips_hpt_read is NULL, an R4k-compatible timer setup is attempted. 49 */ 50 extern unsigned int (*mips_hpt_read)(void); 51 - extern void (*mips_hpt_init)(unsigned int); 52 53 /* 54 * to_tm() converts system time back to (year, mon, day, hour, min, sec). ··· 57 * Copied from PPC implementation. 58 */ 59 extern void to_tm(unsigned long tim, struct rtc_time *tm); 60 - 61 - /* 62 - * do_gettimeoffset(). By default, this func pointer points to 63 - * do_null_gettimeoffset(), which leads to the same resolution as HZ. 64 - * Higher resolution versions are available, which give ~1us resolution. 65 - */ 66 - extern unsigned long (*do_gettimeoffset)(void); 67 68 /* 69 * high-level timer interrupt routines.
··· 48 * If mips_hpt_read is NULL, an R4k-compatible timer setup is attempted. 49 */ 50 extern unsigned int (*mips_hpt_read)(void); 51 + extern void (*mips_hpt_init)(void); 52 + extern unsigned int mips_hpt_mask; 53 54 /* 55 * to_tm() converts system time back to (year, mon, day, hour, min, sec). ··· 56 * Copied from PPC implementation. 57 */ 58 extern void to_tm(unsigned long tim, struct rtc_time *tm); 59 60 /* 61 * high-level timer interrupt routines.