aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/platforms/chrp_time.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-15 13:05:10 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-15 13:05:10 -0500
commitfc03da1ca1954f103ed57daf90611cefa57b07e0 (patch)
tree2b9b44b1a39f7743c1c3d7bc89654792686d7dbc /arch/ppc/platforms/chrp_time.c
parentcaf5b04c82f05c65843b2d7189845d6c3df5a41e (diff)
parente05b3b4adbaeea508bd1c195f1f2e22c8251176b (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
Diffstat (limited to 'arch/ppc/platforms/chrp_time.c')
-rw-r--r--arch/ppc/platforms/chrp_time.c64
1 files changed, 63 insertions, 1 deletions
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
index 29d074c305f0..57753a55b580 100644
--- a/arch/ppc/platforms/chrp_time.c
+++ b/arch/ppc/platforms/chrp_time.c
@@ -163,13 +163,75 @@ unsigned long chrp_get_rtc_time(void)
163 return mktime(year, mon, day, hour, min, sec); 163 return mktime(year, mon, day, hour, min, sec);
164} 164}
165 165
166/*
167 * Calibrate the decrementer frequency with the VIA timer 1.
168 */
169#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
170
171/* VIA registers */
172#define RS 0x200 /* skip between registers */
173#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
174#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
175#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
176#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
177#define ACR (11*RS) /* Auxiliary control register */
178#define IFR (13*RS) /* Interrupt flag register */
179
180/* Bits in ACR */
181#define T1MODE 0xc0 /* Timer 1 mode */
182#define T1MODE_CONT 0x40 /* continuous interrupts */
183
184/* Bits in IFR and IER */
185#define T1_INT 0x40 /* Timer 1 interrupt */
186
187static int __init chrp_via_calibrate_decr(void)
188{
189 struct device_node *vias;
190 volatile unsigned char __iomem *via;
191 int count = VIA_TIMER_FREQ_6 / 100;
192 unsigned int dstart, dend;
193
194 vias = find_devices("via-cuda");
195 if (vias == 0)
196 vias = find_devices("via");
197 if (vias == 0 || vias->n_addrs == 0)
198 return 0;
199 via = ioremap(vias->addrs[0].address, vias->addrs[0].size);
200
201 /* set timer 1 for continuous interrupts */
202 out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
203 /* set the counter to a small value */
204 out_8(&via[T1CH], 2);
205 /* set the latch to `count' */
206 out_8(&via[T1LL], count);
207 out_8(&via[T1LH], count >> 8);
208 /* wait until it hits 0 */
209 while ((in_8(&via[IFR]) & T1_INT) == 0)
210 ;
211 dstart = get_dec();
212 /* clear the interrupt & wait until it hits 0 again */
213 in_8(&via[T1CL]);
214 while ((in_8(&via[IFR]) & T1_INT) == 0)
215 ;
216 dend = get_dec();
217
218 tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100);
219 tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
220
221 printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",
222 tb_ticks_per_jiffy, dstart - dend);
223
224 iounmap(via);
225
226 return 1;
227}
166 228
167void __init chrp_calibrate_decr(void) 229void __init chrp_calibrate_decr(void)
168{ 230{
169 struct device_node *cpu; 231 struct device_node *cpu;
170 unsigned int freq, *fp; 232 unsigned int freq, *fp;
171 233
172 if (via_calibrate_decr()) 234 if (chrp_via_calibrate_decr())
173 return; 235 return;
174 236
175 /* 237 /*