aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/time.c')
-rw-r--r--arch/mips/kernel/time.c87
1 files changed, 33 insertions, 54 deletions
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 3284b9b4ecac..d7d52efff51f 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -91,48 +91,6 @@ static struct clocksource clocksource_mips = {
91 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 91 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
92}; 92};
93 93
94static unsigned int __init calibrate_hpt(void)
95{
96 cycle_t frequency, hpt_start, hpt_end, hpt_count, hz;
97
98 const int loops = HZ / 10;
99 int log_2_loops = 0;
100 int i;
101
102 /*
103 * We want to calibrate for 0.1s, but to avoid a 64-bit
104 * division we round the number of loops up to the nearest
105 * power of 2.
106 */
107 while (loops > 1 << log_2_loops)
108 log_2_loops++;
109 i = 1 << log_2_loops;
110
111 /*
112 * Wait for a rising edge of the timer interrupt.
113 */
114 while (mips_timer_state());
115 while (!mips_timer_state());
116
117 /*
118 * Now see how many high precision timer ticks happen
119 * during the calculated number of periods between timer
120 * interrupts.
121 */
122 hpt_start = clocksource_mips.read();
123 do {
124 while (mips_timer_state());
125 while (!mips_timer_state());
126 } while (--i);
127 hpt_end = clocksource_mips.read();
128
129 hpt_count = (hpt_end - hpt_start) & clocksource_mips.mask;
130 hz = HZ;
131 frequency = hpt_count * hz;
132
133 return frequency >> log_2_loops;
134}
135
136void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock) 94void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
137{ 95{
138 u64 temp; 96 u64 temp;
@@ -194,21 +152,42 @@ void __init plat_timer_setup(void)
194 BUG(); 152 BUG();
195} 153}
196 154
155static __init int cpu_has_mfc0_count_bug(void)
156{
157 switch (current_cpu_type()) {
158 case CPU_R4000PC:
159 case CPU_R4000SC:
160 case CPU_R4000MC:
161 /*
162 * V3.0 is documented as suffering from the mfc0 from count bug.
163 * Afaik this is the last version of the R4000. Later versions
164 * were marketed as R4400.
165 */
166 return 1;
167
168 case CPU_R4400PC:
169 case CPU_R4400SC:
170 case CPU_R4400MC:
171 /*
172 * The published errata for the R4400 upto 3.0 say the CPU
173 * has the mfc0 from count bug.
174 */
175 if ((current_cpu_data.processor_id & 0xff) <= 0x30)
176 return 1;
177
178 /*
179 * I don't have erratas for newer R4400 so be paranoid.
180 */
181 return 1;
182 }
183
184 return 0;
185}
186
197void __init time_init(void) 187void __init time_init(void)
198{ 188{
199 plat_time_init(); 189 plat_time_init();
200 190
201 if (cpu_has_counter && (mips_hpt_frequency || mips_timer_state)) { 191 if (mips_clockevent_init() || !cpu_has_mfc0_count_bug())
202 /* We know counter frequency. Or we can get it. */
203 if (!mips_hpt_frequency)
204 mips_hpt_frequency = calibrate_hpt();
205
206 /* Report the high precision timer rate for a reference. */
207 printk("Using %u.%03u MHz high precision timer.\n",
208 ((mips_hpt_frequency + 500) / 1000) / 1000,
209 ((mips_hpt_frequency + 500) / 1000) % 1000);
210 init_mips_clocksource(); 192 init_mips_clocksource();
211 }
212
213 mips_clockevent_init();
214} 193}