aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@snapgear.com>2006-06-25 20:33:10 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 20:43:33 -0400
commit0b7ac8e479f311f8ef15fbea3f849dded9f3ccd9 (patch)
treed84b81667b7db390d704137b40903e5079f05e53
parentc88b36e2c828c78c51e90002351f9d9068b75dec (diff)
[PATCH] m68knommu: read/write register access for ColdFire core timer
Modify the m68knommu/ColdFire core timer code to use register offsets with raw_read/raw_write access, instead of a mapped struct. Signed-off-by: Greg Ungerer <gerg@uclinux.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/m68knommu/platform/5307/timers.c49
-rw-r--r--include/asm-m68knommu/mcftimer.h30
2 files changed, 36 insertions, 43 deletions
diff --git a/arch/m68knommu/platform/5307/timers.c b/arch/m68knommu/platform/5307/timers.c
index ef49596aa09c..83b8b89dfa09 100644
--- a/arch/m68knommu/platform/5307/timers.c
+++ b/arch/m68knommu/platform/5307/timers.c
@@ -14,6 +14,7 @@
14#include <linux/param.h> 14#include <linux/param.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <asm/io.h>
17#include <asm/irq.h> 18#include <asm/irq.h>
18#include <asm/traps.h> 19#include <asm/traps.h>
19#include <asm/machdep.h> 20#include <asm/machdep.h>
@@ -24,6 +25,11 @@
24/***************************************************************************/ 25/***************************************************************************/
25 26
26/* 27/*
28 * By default use timer1 as the system clock timer.
29 */
30#define TA(a) (MCF_MBAR + MCFTIMER_BASE1 + (a))
31
32/*
27 * Default the timer and vector to use for ColdFire. Some ColdFire 33 * Default the timer and vector to use for ColdFire. Some ColdFire
28 * CPU's and some boards may want different. Their sub-architecture 34 * CPU's and some boards may want different. Their sub-architecture
29 * startup code (in config.c) can change these if they want. 35 * startup code (in config.c) can change these if they want.
@@ -32,8 +38,6 @@ unsigned int mcf_timervector = 29;
32unsigned int mcf_profilevector = 31; 38unsigned int mcf_profilevector = 31;
33unsigned int mcf_timerlevel = 5; 39unsigned int mcf_timerlevel = 5;
34 40
35static volatile struct mcftimer *mcf_timerp;
36
37/* 41/*
38 * These provide the underlying interrupt vector support. 42 * These provide the underlying interrupt vector support.
39 * Unfortunately it is a little different on each ColdFire. 43 * Unfortunately it is a little different on each ColdFire.
@@ -46,20 +50,17 @@ extern int mcf_timerirqpending(int timer);
46void coldfire_tick(void) 50void coldfire_tick(void)
47{ 51{
48 /* Reset the ColdFire timer */ 52 /* Reset the ColdFire timer */
49 mcf_timerp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF; 53 __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
50} 54}
51 55
52/***************************************************************************/ 56/***************************************************************************/
53 57
54void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) 58void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *))
55{ 59{
56 /* Set up an internal TIMER as poll clock */ 60 __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
57 mcf_timerp = (volatile struct mcftimer *) (MCF_MBAR + MCFTIMER_BASE1); 61 __raw_writew(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR));
58 mcf_timerp->tmr = MCFTIMER_TMR_DISABLE; 62 __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
59 63 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR));
60 mcf_timerp->trr = (unsigned short) ((MCF_BUSCLK / 16) / HZ);
61 mcf_timerp->tmr = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
62 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
63 64
64 request_irq(mcf_timervector, handler, SA_INTERRUPT, "timer", NULL); 65 request_irq(mcf_timervector, handler, SA_INTERRUPT, "timer", NULL);
65 mcf_settimericr(1, mcf_timerlevel); 66 mcf_settimericr(1, mcf_timerlevel);
@@ -75,13 +76,8 @@ unsigned long coldfire_timer_offset(void)
75{ 76{
76 unsigned long trr, tcn, offset; 77 unsigned long trr, tcn, offset;
77 78
78 /* 79 tcn = __raw_readw(TA(MCFTIMER_TCN));
79 * The change to pointer and de-reference is to force the compiler 80 trr = __raw_readw(TA(MCFTIMER_TRR));
80 * to read the registers with a single 16bit access. Otherwise it
81 * does some crazy 8bit read combining.
82 */
83 tcn = *(&mcf_timerp->tcn);
84 trr = *(&mcf_timerp->trr);
85 offset = (tcn * (1000000 / HZ)) / trr; 81 offset = (tcn * (1000000 / HZ)) / trr;
86 82
87 /* Check if we just wrapped the counters and maybe missed a tick */ 83 /* Check if we just wrapped the counters and maybe missed a tick */
@@ -95,21 +91,23 @@ unsigned long coldfire_timer_offset(void)
95/***************************************************************************/ 91/***************************************************************************/
96 92
97/* 93/*
94 * By default use timer2 as the profiler clock timer.
95 */
96#define PA(a) (MCF_MBAR + MCFTIMER_BASE2 + (a))
97
98/*
98 * Choose a reasonably fast profile timer. Make it an odd value to 99 * Choose a reasonably fast profile timer. Make it an odd value to
99 * try and get good coverage of kernal operations. 100 * try and get good coverage of kernal operations.
100 */ 101 */
101#define PROFILEHZ 1013 102#define PROFILEHZ 1013
102 103
103static volatile struct mcftimer *mcf_proftp;
104
105/* 104/*
106 * Use the other timer to provide high accuracy profiling info. 105 * Use the other timer to provide high accuracy profiling info.
107 */ 106 */
108
109void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs) 107void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs)
110{ 108{
111 /* Reset ColdFire timer2 */ 109 /* Reset ColdFire timer2 */
112 mcf_proftp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF; 110 __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER));
113 if (current->pid) 111 if (current->pid)
114 profile_tick(CPU_PROFILING, regs); 112 profile_tick(CPU_PROFILING, regs);
115} 113}
@@ -121,12 +119,11 @@ void coldfire_profile_init(void)
121 printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ); 119 printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ);
122 120
123 /* Set up TIMER 2 as high speed profile clock */ 121 /* Set up TIMER 2 as high speed profile clock */
124 mcf_proftp = (volatile struct mcftimer *) (MCF_MBAR + MCFTIMER_BASE2); 122 __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
125 mcf_proftp->tmr = MCFTIMER_TMR_DISABLE;
126 123
127 mcf_proftp->trr = (unsigned short) ((MCF_CLK / 16) / PROFILEHZ); 124 __raw_writew(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR));
128 mcf_proftp->tmr = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | 125 __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
129 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE; 126 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
130 127
131 request_irq(mcf_profilevector, coldfire_profile_tick, 128 request_irq(mcf_profilevector, coldfire_profile_tick,
132 (SA_INTERRUPT | IRQ_FLG_FAST), "profile timer", NULL); 129 (SA_INTERRUPT | IRQ_FLG_FAST), "profile timer", NULL);
diff --git a/include/asm-m68knommu/mcftimer.h b/include/asm-m68knommu/mcftimer.h
index 68bf33ac10d1..6f4d796e03db 100644
--- a/include/asm-m68knommu/mcftimer.h
+++ b/include/asm-m68knommu/mcftimer.h
@@ -3,7 +3,7 @@
3/* 3/*
4 * mcftimer.h -- ColdFire internal TIMER support defines. 4 * mcftimer.h -- ColdFire internal TIMER support defines.
5 * 5 *
6 * (C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com) 6 * (C) Copyright 1999-2006, Greg Ungerer <gerg@snapgear.com>
7 * (C) Copyright 2000, Lineo Inc. (www.lineo.com) 7 * (C) Copyright 2000, Lineo Inc. (www.lineo.com)
8 */ 8 */
9 9
@@ -27,6 +27,11 @@
27#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) 27#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
28#define MCFTIMER_BASE1 0x140 /* Base address of TIMER1 */ 28#define MCFTIMER_BASE1 0x140 /* Base address of TIMER1 */
29#define MCFTIMER_BASE2 0x180 /* Base address of TIMER2 */ 29#define MCFTIMER_BASE2 0x180 /* Base address of TIMER2 */
30#elif defined(CONFIG_M532x)
31#define MCFTIMER_BASE1 0xfc070000 /* Base address of TIMER1 */
32#define MCFTIMER_BASE2 0xfc074000 /* Base address of TIMER2 */
33#define MCFTIMER_BASE3 0xfc078000 /* Base address of TIMER3 */
34#define MCFTIMER_BASE4 0xfc07c000 /* Base address of TIMER4 */
30#endif 35#endif
31 36
32 37
@@ -34,23 +39,14 @@
34 * Define the TIMER register set addresses. 39 * Define the TIMER register set addresses.
35 */ 40 */
36#define MCFTIMER_TMR 0x00 /* Timer Mode reg (r/w) */ 41#define MCFTIMER_TMR 0x00 /* Timer Mode reg (r/w) */
37#define MCFTIMER_TRR 0x02 /* Timer Reference (r/w) */ 42#define MCFTIMER_TRR 0x04 /* Timer Reference (r/w) */
38#define MCFTIMER_TCR 0x04 /* Timer Capture reg (r/w) */ 43#define MCFTIMER_TCR 0x08 /* Timer Capture reg (r/w) */
39#define MCFTIMER_TCN 0x06 /* Timer Counter reg (r/w) */ 44#define MCFTIMER_TCN 0x0C /* Timer Counter reg (r/w) */
45#if defined(CONFIG_M532x)
46#define MCFTIMER_TER 0x03 /* Timer Event reg (r/w) */
47#else
40#define MCFTIMER_TER 0x11 /* Timer Event reg (r/w) */ 48#define MCFTIMER_TER 0x11 /* Timer Event reg (r/w) */
41 49#endif
42struct mcftimer {
43 unsigned short tmr; /* Timer Mode reg (r/w) */
44 unsigned short reserved1;
45 unsigned short trr; /* Timer Reference (r/w) */
46 unsigned short reserved2;
47 unsigned short tcr; /* Timer Capture reg (r/w) */
48 unsigned short reserved3;
49 unsigned short tcn; /* Timer Counter reg (r/w) */
50 unsigned short reserved4;
51 unsigned char reserved5;
52 unsigned char ter; /* Timer Event reg (r/w) */
53} __attribute__((packed));
54 50
55/* 51/*
56 * Bit definitions for the Timer Mode Register (TMR). 52 * Bit definitions for the Timer Mode Register (TMR).