1 /*
2  *   Copyright (C) 2004 by Green Hills Software,Inc.
3  *
4  *  This program is the property of Green Hills Software, Inc,
5  *  its contents are proprietary information and no part of it
6  *  is to be disclosed to anyone except employees of Green Hills
7  *  Software, Inc., or as agreed in writing signed by the President
8  *  of Green Hills Software, Inc.
9  */
10 
11 #include <arm_ghs.h>
12 #if defined(__ghs_board_is_arm_edb7212)
13 
14 /***
15  * Timer-Driven Profiling for Cirrus Logic edb7xxx
16  */
17 
18 #ifdef HIGH_INTERRUPT_VECTOR
19 /* use high interrupt vectors */
20 #define BASE_INTERRUPT_VECTOR 0xFFFF0000
21 #else
22 #define BASE_INTERRUPT_VECTOR 0x00000000
23 #endif
24 
25 #define VECT_IRQ	(BASE_INTERRUPT_VECTOR + 0x18)
26 #define IRQ_POOL	(BASE_INTERRUPT_VECTOR + 0x38)
27 
28 typedef volatile unsigned int mm_reg;
29 
30 #define MM(x)		(*(mm_reg*)x)
31 
32 #define SYSCON1		MM(0x80000100)	/* system control register 1 */
33 
34 #define TC1D		MM(0x80000300)	/* decrementer 1 */
35 #define TC2D		MM(0x80000340)	/* decrementer 2 */
36 #define RTCDR		MM(0x80000380)	/* real time clock */
37 #define RTCMR		MM(0x800003C0)	/* real time clock match */
38 
39 /* clock source frequency for TC1: SYSCON1[5]
40  *  TC2: SYSCON1[7]	(clear: 2kHz, set 512kHz) */
41 
42 /* RTC at 1Hz */
43 
44 #define TC1OI		8
45 #define TC2OI		9
46 
47 #define TC1_MASK	(1 << TC1OI)
48 #define TC2_MASK	(1 << TC2OI)
49 
50 #define INTMR1		MM(0x80000280)	/* interrupt mask register */
51 #define INTSR1		MM(0x80000240)	/* interrupt status register */
52 
53 #define TC1EOI		MM(0x800006C0)	/* write for end of interrupt */
54 #define TC2EOI		MM(0x80000700)	/* write for end of interrupt */
55 
56 /* setup the IRQ vector */
57 /*  under PIC would want to adjust address word
58  *   at runtime, or place handler in ABS section */
59 #pragma asm
60 .org VECT_IRQ
61 ldr pc, IRQ_ISR_pool
62 .org IRQ_POOL
63 IRQ_ISR_pool:
64 .word __ghs_manprf_timer_handler
65 #pragma endasm
66 
67 #define TICKS_PER_SEC() 		(2*1000)
68 
69 /* set compare register C; reset count register */
70 #define TIMER_INIT(ti_count)						\
71    TC1D = ti_count;		/* set the decrementer value */
72 
73 #define GET_EPC() (address)__builtin_return_address(0)
74 
75 /* clear the timer interrupt with a read of status register */
76 #define CLEAR_TIMER_INTERRUPT()						\
77    TC1EOI = 0xffffffff;
78 
79 /* enable IRQ's */
80 #define ENABLE_IRQ() __SETSR(__GETSR()&~0x80)
81 
82 /* TC Interrup Enable: RC compare */
83 #define ENABLE_TIMER_INTERRUPT()					\
84    SYSCON1 = 0;								\
85    INTMR1 = TC1_MASK;	/* Int. Controller: enable timer interrupt */	\
86    ENABLE_IRQ();	/* enable IRQ interrupts */
87 
88 
89 #elif defined(__ghs_board_is_arm_at91eb40)
90 
91 /****
92  * Manual Profiling for Atmel AT91X40 series
93  *  (adjust above elif for your board)
94  */
95 
96 #include "at91_std_c.h"
97 #include "at91_tc.h"
98 #include "at91_aic.h"
99 
100 #define VECT_IRQ	0x00000018
101 
102 /*----------------------------*/
103 /* Advanced Interrupt Control */
104 /*----------------------------*/
105 
106 #define AIC_IECR	(AIC_BASE->AIC_IECR)
107 #define AIC_IDCR	(AIC_BASE->AIC_IDCR)
108 #define AIC_ICCR	(AIC_BASE->AIC_ICCR)
109 #define AIC_ISCR	(AIC_BASE->AIC_ISCR)
110 #define AIC_EOICR	(AIC_BASE->AIC_EOICR)
111 #define AIC_IVR		(AIC_BASE->AIC_IVR)
112 #define AIC_SVR		(AIC_BASE->AIC_SVR)
113 
114 /*---------------*/
115 /* Timer Counter */
116 /*---------------*/
117 
118 #define TC_BMR		(*(at91_reg*)0xFFFE00C4)
119 
120 #define TC0_BASE	((StructTC *)0xFFFE0000)
121 
122 #define TC0_CCR		(TC0_BASE->TC_CCR)
123 #define TC0_CMR     	(TC0_BASE->TC_CMR)
124 #define TC0_CV      	(TC0_BASE->TC_CV)
125 #define TC0_RA      	(TC0_BASE->TC_RA)
126 #define TC0_RB      	(TC0_BASE->TC_RB)
127 #define TC0_RC      	(TC0_BASE->TC_RC)
128 #define TC0_SR      	(TC0_BASE->TC_SR)
129 #define TC0_IER     	(TC0_BASE->TC_IER)
130 #define TC0_IDR     	(TC0_BASE->TC_IDR)
131 #define TC0_IMR     	(TC0_BASE->TC_IMR)
132 
133 #define TC0IRQ_ID	4
134 #define AIC_TC0IRQ	(1 << TC0IRQ_ID)
135 
136 #define TC_CMR_VAL 							\
137    (TC_WAVE		/* waveform mode */				\
138    | TC_CPCSTOP 	/* stop counter with RC compare */		\
139    | TC_CLKS_MCK128) 	/* MCK/128 */
140 
141 /*--------------*/
142 /* Master Clock */
143 /*--------------*/
144 
145 #define MCK         32768000
146 #define MCKKHz      (MCK/1000)
147 #define MCKMHz      (MCK/1000000)
148 
149 /* setup the IRQ vector */
150 /*  this will load the ISR address from IVR (which is set from appropriate SVR)*/
151 #pragma asm
152 .org VECT_IRQ
153 ldr pc, [pc, -0xf20]
154 #pragma endasm
155 
156 #define TICKS_PER_SEC() 		(MCK/128)
157 
158 /* set compare register C; reset count register */
159 #define TIMER_INIT(ti_count)						\
160    TC0_RC = ti_count;		/* set the RC compare value */
161 
162 
163 #define GET_EPC() (address)__builtin_return_address(0)
164 
165 /* clear the timer interrupt with a read of status register */
166 #define CLEAR_TIMER_INTERRUPT()						\
167    AIC_IVR = 0;			/* clear the vector register   */	\
168                                 /*  (can use to index AIC_SVR) */	\
169    AIC_ICCR = AIC_TC0IRQ;	/* clear TC0 IRQ */			\
170    TC0_CCR = TC_SWTRG;   	/* restart the counter */		\
171    AIC_EOICR  = TC0_SR; 	/* end of interrupt and reset TC0 interrupt */
172 
173 /* enable IRQ's */
174 
175 #define ENABLE_IRQ() __SETSR(__GETSR()&~0x80)
176 
177 /* TC Interrupt Enable: RC compare */
178 #define ENABLE_TIMER_INTERRUPT()					\
179    AIC_SVR[TC0IRQ_ID] = (at91_reg)&__ghs_manprf_timer_handler; 		\
180    /* set the appropriate source vector register */			\
181    TC0_CMR = TC_CMR_VAL;	/* set timer mode */			\
182    TC0_IER = TC_CPCS;		/* enable compare RC interrupt*/	\
183    TC0_CCR = TC_CLKEN;		/* enable the clock */			\
184    AIC_IECR = AIC_TC0IRQ;	/* AIC: enable timer interrupt */	\
185    ENABLE_IRQ();		/* enable IRQ interrupts */		\
186    TC0_CCR = TC_SWTRG;		/* reset and start the counter */
187 
188 /* #elif defined(__ghs_board_is_arm_at91rm9200) */
189 
190 #else	/* board type */
191 
192 /* You must implement these functions for your board */
193 void __ghs_manprf_timer_init(unsigned int);
194 void __ghs_manprf_timer_interrupt_enable(void);
195 void __ghs_manprf_timer_interrupt_clear(void);
196 unsigned int __ghs_manprf_timer_ticks_per_sec(void);
197 
198 
199 unsigned int TICKS_PER_SEC(void) { return __ghs_manprf_timer_ticks_per_sec(); }
200 
201 #define CLEAR_TIMER_INTERRUPT() __ghs_manprf_timer_interrupt_clear()
202 #define ENABLE_TIMER_INTERRUPT() __ghs_manprf_timer_interrupt_enable()
203 #define TIMER_INIT __ghs_manprf_timer_init
204 #define GET_EPC() (address)__builtin_return_address(0)
205 
206 #endif	/* board type */
207