.. | .. |
---|
19 | 19 | #include <linux/mm.h> |
---|
20 | 20 | #include <linux/seq_file.h> |
---|
21 | 21 | #include <linux/tty.h> |
---|
| 22 | +#include <linux/clocksource.h> |
---|
22 | 23 | #include <linux/console.h> |
---|
23 | 24 | #include <linux/linkage.h> |
---|
24 | 25 | #include <linux/init.h> |
---|
.. | .. |
---|
31 | 32 | #include <asm/bootinfo.h> |
---|
32 | 33 | #include <asm/bootinfo-vme.h> |
---|
33 | 34 | #include <asm/byteorder.h> |
---|
34 | | -#include <asm/pgtable.h> |
---|
35 | 35 | #include <asm/setup.h> |
---|
36 | 36 | #include <asm/irq.h> |
---|
37 | 37 | #include <asm/traps.h> |
---|
.. | .. |
---|
44 | 44 | |
---|
45 | 45 | static void mvme16x_get_model(char *model); |
---|
46 | 46 | extern void mvme16x_sched_init(irq_handler_t handler); |
---|
47 | | -extern u32 mvme16x_gettimeoffset(void); |
---|
48 | 47 | extern int mvme16x_hwclk (int, struct rtc_time *); |
---|
49 | 48 | extern void mvme16x_reset (void); |
---|
50 | 49 | |
---|
.. | .. |
---|
115 | 114 | m68k_setup_user_interrupt(VEC_USER, 192); |
---|
116 | 115 | } |
---|
117 | 116 | |
---|
118 | | -#define pcc2chip ((volatile u_char *)0xfff42000) |
---|
119 | | -#define PccSCCMICR 0x1d |
---|
120 | | -#define PccSCCTICR 0x1e |
---|
121 | | -#define PccSCCRICR 0x1f |
---|
122 | | -#define PccTPIACKR 0x25 |
---|
| 117 | +#define PCC2CHIP (0xfff42000) |
---|
| 118 | +#define PCCSCCMICR (PCC2CHIP + 0x1d) |
---|
| 119 | +#define PCCSCCTICR (PCC2CHIP + 0x1e) |
---|
| 120 | +#define PCCSCCRICR (PCC2CHIP + 0x1f) |
---|
| 121 | +#define PCCTPIACKR (PCC2CHIP + 0x25) |
---|
123 | 122 | |
---|
124 | 123 | #ifdef CONFIG_EARLY_PRINTK |
---|
125 | 124 | |
---|
.. | .. |
---|
227 | 226 | base_addr[CyIER] = CyTxMpty; |
---|
228 | 227 | |
---|
229 | 228 | while (1) { |
---|
230 | | - if (pcc2chip[PccSCCTICR] & 0x20) |
---|
| 229 | + if (in_8(PCCSCCTICR) & 0x20) |
---|
231 | 230 | { |
---|
232 | 231 | /* We have a Tx int. Acknowledge it */ |
---|
233 | | - sink = pcc2chip[PccTPIACKR]; |
---|
| 232 | + sink = in_8(PCCTPIACKR); |
---|
234 | 233 | if ((base_addr[CyLICR] >> 2) == port) { |
---|
235 | 234 | if (i == count) { |
---|
236 | 235 | /* Last char of string is now output */ |
---|
.. | .. |
---|
272 | 271 | mach_max_dma_address = 0xffffffff; |
---|
273 | 272 | mach_sched_init = mvme16x_sched_init; |
---|
274 | 273 | mach_init_IRQ = mvme16x_init_IRQ; |
---|
275 | | - arch_gettimeoffset = mvme16x_gettimeoffset; |
---|
276 | 274 | mach_hwclk = mvme16x_hwclk; |
---|
277 | 275 | mach_reset = mvme16x_reset; |
---|
278 | 276 | mach_get_model = mvme16x_get_model; |
---|
.. | .. |
---|
345 | 343 | return IRQ_HANDLED; |
---|
346 | 344 | } |
---|
347 | 345 | |
---|
| 346 | +static u64 mvme16x_read_clk(struct clocksource *cs); |
---|
| 347 | + |
---|
| 348 | +static struct clocksource mvme16x_clk = { |
---|
| 349 | + .name = "pcc", |
---|
| 350 | + .rating = 250, |
---|
| 351 | + .read = mvme16x_read_clk, |
---|
| 352 | + .mask = CLOCKSOURCE_MASK(32), |
---|
| 353 | + .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
---|
| 354 | +}; |
---|
| 355 | + |
---|
| 356 | +static u32 clk_total; |
---|
| 357 | + |
---|
| 358 | +#define PCC_TIMER_CLOCK_FREQ 1000000 |
---|
| 359 | +#define PCC_TIMER_CYCLES (PCC_TIMER_CLOCK_FREQ / HZ) |
---|
| 360 | + |
---|
| 361 | +#define PCCTCMP1 (PCC2CHIP + 0x04) |
---|
| 362 | +#define PCCTCNT1 (PCC2CHIP + 0x08) |
---|
| 363 | +#define PCCTOVR1 (PCC2CHIP + 0x17) |
---|
| 364 | +#define PCCTIC1 (PCC2CHIP + 0x1b) |
---|
| 365 | + |
---|
| 366 | +#define PCCTOVR1_TIC_EN 0x01 |
---|
| 367 | +#define PCCTOVR1_COC_EN 0x02 |
---|
| 368 | +#define PCCTOVR1_OVR_CLR 0x04 |
---|
| 369 | + |
---|
| 370 | +#define PCCTIC1_INT_LEVEL 6 |
---|
| 371 | +#define PCCTIC1_INT_CLR 0x08 |
---|
| 372 | +#define PCCTIC1_INT_EN 0x10 |
---|
| 373 | + |
---|
348 | 374 | static irqreturn_t mvme16x_timer_int (int irq, void *dev_id) |
---|
349 | 375 | { |
---|
350 | 376 | irq_handler_t timer_routine = dev_id; |
---|
351 | 377 | unsigned long flags; |
---|
352 | 378 | |
---|
353 | 379 | local_irq_save(flags); |
---|
354 | | - *(volatile unsigned char *)0xfff4201b |= 8; |
---|
| 380 | + out_8(PCCTOVR1, PCCTOVR1_OVR_CLR | PCCTOVR1_TIC_EN | PCCTOVR1_COC_EN); |
---|
| 381 | + out_8(PCCTIC1, PCCTIC1_INT_EN | PCCTIC1_INT_CLR | PCCTIC1_INT_LEVEL); |
---|
| 382 | + clk_total += PCC_TIMER_CYCLES; |
---|
355 | 383 | timer_routine(0, NULL); |
---|
356 | 384 | local_irq_restore(flags); |
---|
357 | 385 | |
---|
.. | .. |
---|
364 | 392 | int irq; |
---|
365 | 393 | |
---|
366 | 394 | /* Using PCCchip2 or MC2 chip tick timer 1 */ |
---|
367 | | - *(volatile unsigned long *)0xfff42008 = 0; |
---|
368 | | - *(volatile unsigned long *)0xfff42004 = 10000; /* 10ms */ |
---|
369 | | - *(volatile unsigned char *)0xfff42017 |= 3; |
---|
370 | | - *(volatile unsigned char *)0xfff4201b = 0x16; |
---|
371 | | - if (request_irq(MVME16x_IRQ_TIMER, mvme16x_timer_int, 0, "timer", |
---|
| 395 | + if (request_irq(MVME16x_IRQ_TIMER, mvme16x_timer_int, IRQF_TIMER, "timer", |
---|
372 | 396 | timer_routine)) |
---|
373 | 397 | panic ("Couldn't register timer int"); |
---|
| 398 | + |
---|
| 399 | + out_be32(PCCTCNT1, 0); |
---|
| 400 | + out_be32(PCCTCMP1, PCC_TIMER_CYCLES); |
---|
| 401 | + out_8(PCCTOVR1, PCCTOVR1_OVR_CLR | PCCTOVR1_TIC_EN | PCCTOVR1_COC_EN); |
---|
| 402 | + out_8(PCCTIC1, PCCTIC1_INT_EN | PCCTIC1_INT_CLR | PCCTIC1_INT_LEVEL); |
---|
| 403 | + |
---|
| 404 | + clocksource_register_hz(&mvme16x_clk, PCC_TIMER_CLOCK_FREQ); |
---|
374 | 405 | |
---|
375 | 406 | if (brdno == 0x0162 || brdno == 0x172) |
---|
376 | 407 | irq = MVME162_IRQ_ABORT; |
---|
.. | .. |
---|
381 | 412 | panic ("Couldn't register abort int"); |
---|
382 | 413 | } |
---|
383 | 414 | |
---|
384 | | - |
---|
385 | | -/* This is always executed with interrupts disabled. */ |
---|
386 | | -u32 mvme16x_gettimeoffset(void) |
---|
| 415 | +static u64 mvme16x_read_clk(struct clocksource *cs) |
---|
387 | 416 | { |
---|
388 | | - return (*(volatile u32 *)0xfff42008) * 1000; |
---|
| 417 | + unsigned long flags; |
---|
| 418 | + u8 overflow, tmp; |
---|
| 419 | + u32 ticks; |
---|
| 420 | + |
---|
| 421 | + local_irq_save(flags); |
---|
| 422 | + tmp = in_8(PCCTOVR1) >> 4; |
---|
| 423 | + ticks = in_be32(PCCTCNT1); |
---|
| 424 | + overflow = in_8(PCCTOVR1) >> 4; |
---|
| 425 | + if (overflow != tmp) |
---|
| 426 | + ticks = in_be32(PCCTCNT1); |
---|
| 427 | + ticks += overflow * PCC_TIMER_CYCLES; |
---|
| 428 | + ticks += clk_total; |
---|
| 429 | + local_irq_restore(flags); |
---|
| 430 | + |
---|
| 431 | + return ticks; |
---|
389 | 432 | } |
---|
390 | 433 | |
---|
391 | 434 | int bcd2int (unsigned char b) |
---|