hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/arch/m68k/mvme16x/config.c
....@@ -19,6 +19,7 @@
1919 #include <linux/mm.h>
2020 #include <linux/seq_file.h>
2121 #include <linux/tty.h>
22
+#include <linux/clocksource.h>
2223 #include <linux/console.h>
2324 #include <linux/linkage.h>
2425 #include <linux/init.h>
....@@ -31,7 +32,6 @@
3132 #include <asm/bootinfo.h>
3233 #include <asm/bootinfo-vme.h>
3334 #include <asm/byteorder.h>
34
-#include <asm/pgtable.h>
3535 #include <asm/setup.h>
3636 #include <asm/irq.h>
3737 #include <asm/traps.h>
....@@ -44,7 +44,6 @@
4444
4545 static void mvme16x_get_model(char *model);
4646 extern void mvme16x_sched_init(irq_handler_t handler);
47
-extern u32 mvme16x_gettimeoffset(void);
4847 extern int mvme16x_hwclk (int, struct rtc_time *);
4948 extern void mvme16x_reset (void);
5049
....@@ -115,11 +114,11 @@
115114 m68k_setup_user_interrupt(VEC_USER, 192);
116115 }
117116
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)
123122
124123 #ifdef CONFIG_EARLY_PRINTK
125124
....@@ -227,10 +226,10 @@
227226 base_addr[CyIER] = CyTxMpty;
228227
229228 while (1) {
230
- if (pcc2chip[PccSCCTICR] & 0x20)
229
+ if (in_8(PCCSCCTICR) & 0x20)
231230 {
232231 /* We have a Tx int. Acknowledge it */
233
- sink = pcc2chip[PccTPIACKR];
232
+ sink = in_8(PCCTPIACKR);
234233 if ((base_addr[CyLICR] >> 2) == port) {
235234 if (i == count) {
236235 /* Last char of string is now output */
....@@ -272,7 +271,6 @@
272271 mach_max_dma_address = 0xffffffff;
273272 mach_sched_init = mvme16x_sched_init;
274273 mach_init_IRQ = mvme16x_init_IRQ;
275
- arch_gettimeoffset = mvme16x_gettimeoffset;
276274 mach_hwclk = mvme16x_hwclk;
277275 mach_reset = mvme16x_reset;
278276 mach_get_model = mvme16x_get_model;
....@@ -345,13 +343,43 @@
345343 return IRQ_HANDLED;
346344 }
347345
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
+
348374 static irqreturn_t mvme16x_timer_int (int irq, void *dev_id)
349375 {
350376 irq_handler_t timer_routine = dev_id;
351377 unsigned long flags;
352378
353379 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;
355383 timer_routine(0, NULL);
356384 local_irq_restore(flags);
357385
....@@ -364,13 +392,16 @@
364392 int irq;
365393
366394 /* 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",
372396 timer_routine))
373397 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);
374405
375406 if (brdno == 0x0162 || brdno == 0x172)
376407 irq = MVME162_IRQ_ABORT;
....@@ -381,11 +412,23 @@
381412 panic ("Couldn't register abort int");
382413 }
383414
384
-
385
-/* This is always executed with interrupts disabled. */
386
-u32 mvme16x_gettimeoffset(void)
415
+static u64 mvme16x_read_clk(struct clocksource *cs)
387416 {
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;
389432 }
390433
391434 int bcd2int (unsigned char b)