1 // $Id: _profile_timer_hw.c,v 1.1.2.1 2011/05/17 04:37:56 sadanan Exp $
2 /******************************************************************************
4 * Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * Use of the Software is limited solely to applications:
17 * (a) running on a Xilinx device, or
18 * (b) that interact with a Xilinx device through a bus or interconnect.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 * Except as contained in this notice, the name of the Xilinx shall not be used
29 * in advertising or otherwise to promote the sale, use or other dealings in
30 * this Software without prior written authorization from Xilinx.
32 ******************************************************************************
34 * _program_timer_hw.c:
35 * Timer related functions
37 ******************************************************************************/
40 #include "_profile_timer_hw.h"
42 #include "xil_exception.h"
46 #include "xpseudo_asm.h"
49 #ifdef TIMER_CONNECT_INTC
52 #endif // TIMER_CONNECT_INTC
54 //#ifndef PPC_PIT_INTERRUPT
55 #if (!defined PPC_PIT_INTERRUPT && !defined PROC_CORTEXA9)
56 #include "xtmrctr_l.h"
59 extern unsigned int timer_clk_ticks ;
61 //--------------------------------------------------------------------
62 // PowerPC Target - Timer related functions
63 //--------------------------------------------------------------------
67 //--------------------------------------------------------------------
68 // PowerPC PIT Timer Init.
69 // Defined only if PIT Timer is used for Profiling
71 //--------------------------------------------------------------------
72 #ifdef PPC_PIT_INTERRUPT
73 int ppc_pit_init( void )
75 // 1. Register Profile_intr_handler as Interrupt handler
76 // 2. Set PIT Timer Interrupt and Enable it.
77 Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_PIT_INT,
78 (Xil_ExceptionHandler)profile_intr_handler,(void *)0);
79 XTime_PITSetInterval( timer_clk_ticks ) ;
80 XTime_PITEnableAutoReload() ;
86 //--------------------------------------------------------------------
87 // PowerPC Timer Initialization functions.
88 // For PowerPC, PIT and opb_timer can be used for Profiling. This
89 // is selected by the user in standalone BSP
91 //--------------------------------------------------------------------
95 Xil_ExceptionDisableMask( XIL_EXCEPTION_NON_CRITICAL ) ;
97 // Initialize the Timer.
98 // 1. If PowerPC PIT Timer has to be used, initialize PIT timer.
99 // 2. Else use opb_timer. It can be directly connected or thru intc to PowerPC
100 #ifdef PPC_PIT_INTERRUPT
103 #ifdef TIMER_CONNECT_INTC
104 Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT,
105 (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,(void *)0);
106 XIntc_RegisterHandler( INTC_BASEADDR, PROFILE_TIMER_INTR_ID,
107 (XInterruptHandler)profile_intr_handler,(void*)0);
109 Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT,
110 (Xil_ExceptionHandler)profile_intr_handler,(void *)0);
112 // Initialize the timer with Timer Ticks
116 // Enable Interrupts in the System, if Profile Timer is the only Interrupt
118 #ifdef ENABLE_SYS_INTR
119 #ifdef PPC_PIT_INTERRUPT
120 XTime_PITEnableInterrupt() ;
121 #elif TIMER_CONNECT_INTC
122 XIntc_MasterEnable( INTC_BASEADDR );
123 XIntc_SetIntrSvcOption( INTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION);
124 XIntc_EnableIntr( INTC_BASEADDR, PROFILE_TIMER_INTR_MASK );
126 Xil_ExceptionEnableMask( XIL_EXCEPTION_NON_CRITICAL ) ;
135 //--------------------------------------------------------------------
136 // PowerPC440 Target - Timer related functions
137 //--------------------------------------------------------------------
141 //--------------------------------------------------------------------
142 // PowerPC DEC Timer Init.
143 // Defined only if DEC Timer is used for Profiling
145 //--------------------------------------------------------------------
146 #ifdef PPC_PIT_INTERRUPT
147 int ppc_dec_init( void )
149 // 1. Register Profile_intr_handler as Interrupt handler
150 // 2. Set DEC Timer Interrupt and Enable it.
151 Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_DEC_INT,
152 (Xil_ExceptionHandler)profile_intr_handler,(void *)0);
153 XTime_DECSetInterval( timer_clk_ticks ) ;
154 XTime_DECEnableAutoReload() ;
160 //--------------------------------------------------------------------
161 // PowerPC Timer Initialization functions.
162 // For PowerPC, DEC and opb_timer can be used for Profiling. This
163 // is selected by the user in standalone BSP
165 //--------------------------------------------------------------------
166 int powerpc405_init(void)
169 Xil_ExceptionDisableMask( XIL_EXCEPTION_NON_CRITICAL ) ;
171 // Initialize the Timer.
172 // 1. If PowerPC DEC Timer has to be used, initialize DEC timer.
173 // 2. Else use opb_timer. It can be directly connected or thru intc to PowerPC
174 #ifdef PPC_PIT_INTERRUPT
177 #ifdef TIMER_CONNECT_INTC
178 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_NON_CRITICAL_INT,
179 (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,(void *)0);
181 XIntc_RegisterHandler( INTC_BASEADDR, PROFILE_TIMER_INTR_ID,
182 (XInterruptHandler)profile_intr_handler,(void*)0);
184 Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT,
185 (Xil_ExceptionHandler)profile_intr_handler,(void *)0);
186 Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT,
187 (Xil_ExceptionHandler)profile_intr_handler,(void *)0);
189 // Initialize the timer with Timer Ticks
193 // Enable Interrupts in the System, if Profile Timer is the only Interrupt
195 #ifdef ENABLE_SYS_INTR
196 #ifdef PPC_PIT_INTERRUPT
197 XTime_DECEnableInterrupt() ;
198 #elif TIMER_CONNECT_INTC
199 XIntc_MasterEnable( INTC_BASEADDR );
200 XIntc_SetIntrSvcOption( INTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION);
201 XIntc_EnableIntr( INTC_BASEADDR, PROFILE_TIMER_INTR_MASK );
203 Xil_ExceptionEnableMask( XEXC_NON_CRITICAL ) ;
208 #endif // PROC_PPC440
210 //--------------------------------------------------------------------
211 // opb_timer Initialization for PowerPC and MicroBlaze. This function
212 // is not needed if DEC timer is used in PowerPC
214 //--------------------------------------------------------------------
215 //#ifndef PPC_PIT_INTERRUPT
216 #if (!defined PPC_PIT_INTERRUPT && !defined PROC_CORTEXA9)
217 int opb_timer_init( void )
219 // set the number of cycles the timer counts before interrupting
220 XTmrCtr_SetLoadReg(PROFILE_TIMER_BASEADDR, 0, timer_clk_ticks);
222 // reset the timers, and clear interrupts
223 XTmrCtr_SetControlStatusReg(PROFILE_TIMER_BASEADDR, 0,
224 XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK );
227 XTmrCtr_SetControlStatusReg(PROFILE_TIMER_BASEADDR, 0, XTC_CSR_ENABLE_TMR_MASK
228 | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK);
234 //--------------------------------------------------------------------
235 // MicroBlaze Target - Timer related functions
236 //--------------------------------------------------------------------
237 #ifdef PROC_MICROBLAZE
239 //--------------------------------------------------------------------
240 // Initialize the Profile Timer for MicroBlaze Target.
241 // For MicroBlaze, opb_timer is used. The opb_timer can be directly
242 // connected to MicroBlaze or connected through Interrupt Controller.
244 //--------------------------------------------------------------------
245 int microblaze_init(void)
247 // Register profile_intr_handler
248 // 1. If timer is connected to Interrupt Controller, register the handler
249 // to Interrupt Controllers vector table.
250 // 2. If timer is directly connected to MicroBlaze, register the handler
251 // as Interrupt handler
254 #ifdef TIMER_CONNECT_INTC
255 XIntc_RegisterHandler( INTC_BASEADDR, PROFILE_TIMER_INTR_ID,
256 (XInterruptHandler)profile_intr_handler,(void*)0);
258 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
259 (Xil_ExceptionHandler)profile_intr_handler,
263 // Initialize the timer with Timer Ticks
266 // Enable Interrupts in the System, if Profile Timer is the only Interrupt
268 #ifdef ENABLE_SYS_INTR
269 #ifdef TIMER_CONNECT_INTC
270 XIntc_MasterEnable( INTC_BASEADDR );
271 XIntc_SetIntrSvcOption( INTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION);
272 XIntc_EnableIntr( INTC_BASEADDR, PROFILE_TIMER_INTR_MASK );
273 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
274 (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,(void *)0);
279 Xil_ExceptionEnable();
285 #endif // PROC_MICROBLAZE
289 //--------------------------------------------------------------------
290 // Cortex A9 Target - Timer related functions
291 //--------------------------------------------------------------------
294 //--------------------------------------------------------------------
295 // Initialize the Profile Timer for Cortex A9 Target.
296 // The scu private timer is connected to the Scu GIC controller.
298 //--------------------------------------------------------------------
299 int scu_timer_init( void )
301 // set the number of cycles the timer counts before interrupting
302 // scu timer runs at half the cpu clock
303 XScuTimer_SetLoadReg(PROFILE_TIMER_BASEADDR, timer_clk_ticks/2);
305 // clear any pending interrupts
306 XScuTimer_SetIntrReg(PROFILE_TIMER_BASEADDR, 1);
308 // enable interrupts, auto-reload mode and start the timer
309 XScuTimer_SetControlReg(PROFILE_TIMER_BASEADDR, XSCUTIMER_CONTROL_IRQ_ENABLE_MASK |
310 XSCUTIMER_CONTROL_AUTO_RELOAD_MASK | XSCUTIMER_CONTROL_ENABLE_MASK);
315 int cortexa9_init(void)
320 XScuGic_DeviceInitialize(0);
323 * Connect the interrupt controller interrupt handler to the hardware
324 * interrupt handling logic in the processor.
326 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
327 (Xil_ExceptionHandler)XScuGic_DeviceInterruptHandler,
331 * Connect the device driver handler that will be called when an
332 * interrupt for the device occurs, the handler defined above performs
333 * the specific interrupt processing for the device.
335 XScuGic_RegisterHandler(SCUGIC_CPU_BASEADDR,
336 PROFILE_TIMER_INTR_ID,
337 (Xil_ExceptionHandler)profile_intr_handler,
341 * Enable the interrupt for scu timer.
343 XScuGic_EnableIntr(SCUGIC_DIST_BASEADDR, PROFILE_TIMER_INTR_ID);
346 * Enable interrupts in the Processor.
348 Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
351 * Initialize the timer with Timer Ticks
355 Xil_ExceptionEnable();
360 #endif // PROC_CORTEXA9