blob: f89deed538bd5becaa9c9afff7762013bc504b58 [file] [log] [blame]
wdenkaffae2b2002-08-17 09:36:01 +00001/**************************************************
2 *
3 * copyright @ motorola, 1999
4 *
5 *************************************************/
6#include <mpc824x.h>
7#include <common.h>
8#include "epic.h"
9
10
11#define PRINT(format, args...) printf(format , ## args)
12
13typedef void (*VOIDFUNCPTR) (void); /* ptr to function returning void */
14struct SrcVecTable SrcVecTable[MAXVEC] = /* Addr/Vector cross-reference tbl */
15 {
16 { EPIC_EX_INT0_VEC_REG, "External Direct/Serial Source 0"},
17 { EPIC_EX_INT1_VEC_REG, "External Direct/Serial Source 1"},
18 { EPIC_EX_INT2_VEC_REG, "External Direct/Serial Source 2"},
19 { EPIC_EX_INT3_VEC_REG, "External Direct/Serial Source 3"},
20 { EPIC_EX_INT4_VEC_REG, "External Direct/Serial Source 4"},
21
22 { EPIC_SR_INT5_VEC_REG, "External Serial Source 5"},
23 { EPIC_SR_INT6_VEC_REG, "External Serial Source 6"},
24 { EPIC_SR_INT7_VEC_REG, "External Serial Source 7"},
25 { EPIC_SR_INT8_VEC_REG, "External Serial Source 8"},
26 { EPIC_SR_INT9_VEC_REG, "External Serial Source 9"},
27 { EPIC_SR_INT10_VEC_REG, "External Serial Source 10"},
28 { EPIC_SR_INT11_VEC_REG, "External Serial Source 11"},
29 { EPIC_SR_INT12_VEC_REG, "External Serial Source 12"},
30 { EPIC_SR_INT13_VEC_REG, "External Serial Source 13"},
31 { EPIC_SR_INT14_VEC_REG, "External Serial Source 14"},
32 { EPIC_SR_INT15_VEC_REG, "External Serial Source 15"},
33
34 { EPIC_I2C_INT_VEC_REG, "Internal I2C Source"},
35 { EPIC_DMA0_INT_VEC_REG, "Internal DMA0 Source"},
36 { EPIC_DMA1_INT_VEC_REG, "Internal DMA1 Source"},
37 { EPIC_MSG_INT_VEC_REG, "Internal Message Source"},
38 };
39
40VOIDFUNCPTR intVecTbl[MAXVEC]; /* Interrupt vector table */
41
42
43/****************************************************************************
44* epicInit - Initialize the EPIC registers
45*
46* This routine resets the Global Configuration Register, thus it:
47* - Disables all interrupts
48* - Sets epic registers to reset values
49* - Sets the value of the Processor Current Task Priority to the
50* highest priority (0xF).
51* epicInit then sets the EPIC operation mode to Mixed Mode (vs. Pass
52* Through or 8259 compatible mode).
53*
54* If IRQType (input) is Direct IRQs:
55* - IRQType is written to the SIE bit of the EPIC Interrupt
56* Configuration register (ICR).
57* - clkRatio is ignored.
58* If IRQType is Serial IRQs:
59* - both IRQType and clkRatio will be written to the ICR register
60*/
61
62void epicInit
63 (
64 unsigned int IRQType, /* Direct or Serial */
65 unsigned int clkRatio /* Clk Ratio for Serial IRQs */
66 )
67 {
68 ULONG tmp;
69
70 tmp = sysEUMBBARRead(EPIC_GLOBAL_REG);
71 tmp |= 0xa0000000; /* Set the Global Conf. register */
72 sysEUMBBARWrite(EPIC_GLOBAL_REG, tmp);
wdenk7c7a23b2002-12-07 00:20:59 +000073 /*
74 * Wait for EPIC to reset - CLH
75 */
76 while( (sysEUMBBARRead(EPIC_GLOBAL_REG) & 0x80000000) == 1);
wdenkaffae2b2002-08-17 09:36:01 +000077 sysEUMBBARWrite(EPIC_GLOBAL_REG, 0x20000000);
78 tmp = sysEUMBBARRead(EPIC_INT_CONF_REG); /* Read interrupt conf. reg */
79
80 if (IRQType == EPIC_DIRECT_IRQ) /* direct mode */
wdenk8bde7f72003-06-27 21:31:46 +000081 sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp & 0xf7ffffff);
wdenkaffae2b2002-08-17 09:36:01 +000082 else /* Serial mode */
wdenk8bde7f72003-06-27 21:31:46 +000083 {
84 tmp = (clkRatio << 28) | 0x08000000; /* Set clock ratio */
85 sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp);
86 }
wdenkaffae2b2002-08-17 09:36:01 +000087
wdenk7c7a23b2002-12-07 00:20:59 +000088 while (epicIntAck() != 0xff) /* Clear all pending interrupts */
89 epicEOI();
wdenkaffae2b2002-08-17 09:36:01 +000090}
91
92/****************************************************************************
93 * epicIntEnable - Enable an interrupt source
94 *
95 * This routine clears the mask bit of an external, an internal or
96 * a Timer register to enable the interrupt.
97 *
98 * RETURNS: None
99 */
wdenk7c7a23b2002-12-07 00:20:59 +0000100void epicIntEnable(int intVec)
101{
wdenkaffae2b2002-08-17 09:36:01 +0000102 ULONG tmp;
103 ULONG srAddr;
104
105 srAddr = SrcVecTable[intVec].srcAddr; /* Retrieve src Vec/Prio register */
106 tmp = sysEUMBBARRead(srAddr);
wdenk7c7a23b2002-12-07 00:20:59 +0000107 tmp &= ~EPIC_VEC_PRI_MASK; /* Clear the mask bit */
108 tmp |= (EPIC_VEC_PRI_DFLT_PRI << 16); /* Set priority to Default - CLH */
109 tmp |= intVec; /* Set Vector number */
wdenkaffae2b2002-08-17 09:36:01 +0000110 sysEUMBBARWrite(srAddr, tmp);
wdenk7c7a23b2002-12-07 00:20:59 +0000111
wdenkaffae2b2002-08-17 09:36:01 +0000112 return;
113 }
114
115/****************************************************************************
116 * epicIntDisable - Disable an interrupt source
117 *
118 * This routine sets the mask bit of an external, an internal or
119 * a Timer register to disable the interrupt.
120 *
121 * RETURNS: OK or ERROR
122 *
123 */
124
125void epicIntDisable
126 (
127 int intVec /* Interrupt vector number */
128 )
129 {
130
131 ULONG tmp, srAddr;
132
133 srAddr = SrcVecTable[intVec].srcAddr;
134 tmp = sysEUMBBARRead(srAddr);
135 tmp |= 0x80000000; /* Set the mask bit */
136 sysEUMBBARWrite(srAddr, tmp);
137 return;
138 }
139
140/****************************************************************************
141 * epicIntSourceConfig - Set properties of an interrupt source
142 *
143 * This function sets interrupt properites (Polarity, Sense, Interrupt
144 * Prority, and Interrupt Vector) of an Interrupt Source. The properties
145 * can be set when the current source is not in-request or in-service,
146 * which is determined by the Activity bit. This routine return ERROR
147 * if the the Activity bit is 1 (in-request or in-service).
148 *
149 * This function assumes that the Source Vector/Priority register (input)
150 * is a valid address.
151 *
152 * RETURNS: OK or ERROR
153 */
154
155int epicIntSourceConfig
156 (
157 int Vect, /* interrupt source vector number */
158 int Polarity, /* interrupt source polarity */
159 int Sense, /* interrupt source Sense */
160 int Prio /* interrupt source priority */
161 )
162
163 {
164 ULONG tmp, newVal;
165 ULONG actBit, srAddr;
166
167 srAddr = SrcVecTable[Vect].srcAddr;
168 tmp = sysEUMBBARRead(srAddr);
169 actBit = (tmp & 40000000) >> 30; /* retrieve activity bit - bit 30 */
170 if (actBit == 1)
wdenk8bde7f72003-06-27 21:31:46 +0000171 return ERROR;
wdenkaffae2b2002-08-17 09:36:01 +0000172
173 tmp &= 0xff30ff00; /* Erase previously set P,S,Prio,Vector bits */
174 newVal = (Polarity << 23) | (Sense << 22) | (Prio << 16) | Vect;
175 sysEUMBBARWrite(srAddr, tmp | newVal );
176 return (OK);
177 }
178
179/****************************************************************************
180 * epicIntAck - acknowledge an interrupt
181 *
182 * This function reads the Interrupt acknowldge register and return
183 * the vector number of the highest pending interrupt.
184 *
185 * RETURNS: Interrupt Vector number.
186 */
187
188unsigned int epicIntAck(void)
189{
190 return(sysEUMBBARRead( EPIC_PROC_INT_ACK_REG ));
191}
192
193/****************************************************************************
194 * epicEOI - signal an end of interrupt
195 *
196 * This function writes 0x0 to the EOI register to signal end of interrupt.
197 * It is usually called after an interrupt routine is served.
198 *
199 * RETURNS: None
200 */
201
202void epicEOI(void)
203 {
204 sysEUMBBARWrite(EPIC_PROC_EOI_REG, 0x0);
205 }
206
207/****************************************************************************
208 * epicCurTaskPrioSet - sets the priority of the Processor Current Task
209 *
210 * This function should be called after epicInit() to lower the priority
211 * of the processor current task.
212 *
213 * RETURNS: OK or ERROR
214 */
215
216int epicCurTaskPrioSet
217 (
218 int prioNum /* New priority value */
219 )
220 {
221
222 if ( (prioNum < 0) || (prioNum > 0xF))
wdenk8bde7f72003-06-27 21:31:46 +0000223 return ERROR;
wdenkaffae2b2002-08-17 09:36:01 +0000224 sysEUMBBARWrite(EPIC_PROC_CTASK_PRI_REG, prioNum);
225 return OK;
226 }
227
228
229/************************************************************************
230 * function: epicIntTaskGet
231 *
232 * description: Get value of processor current interrupt task priority register
233 *
234 * note:
235 ***********************************************************************/
236unsigned char epicIntTaskGet()
237{
238 /* get the interrupt task priority register */
239 ULONG reg;
240 unsigned char rec;
241
242 reg = sysEUMBBARRead( EPIC_PROC_CTASK_PRI_REG );
243 rec = ( reg & 0x0F );
244 return rec;
245}
246
247
248/**************************************************************
249 * function: epicISR
250 *
251 * description: EPIC service routine called by the core exception
252 * at 0x500
253 *
254 * note:
255 **************************************************************/
256unsigned int epicISR(void)
257{
258 return 0;
259}
260
261
262/************************************************************
263 * function: epicModeGet
264 *
265 * description: query EPIC mode, return 0 if pass through mode
266 * return 1 if mixed mode
267 *
268 * note:
269 *************************************************************/
270unsigned int epicModeGet(void)
271{
272 ULONG val;
273
274 val = sysEUMBBARRead( EPIC_GLOBAL_REG );
275 return (( val & 0x20000000 ) >> 29);
276}
277
278
279/*********************************************
280 * function: epicConfigGet
281 *
282 * description: Get the EPIC interrupt Configuration
283 * return 0 if not error, otherwise return 1
284 *
285 * note:
286 ********************************************/
287void epicConfigGet( unsigned int *clkRatio, unsigned int *serEnable)
288{
289 ULONG val;
290
291 val = sysEUMBBARRead( EPIC_INT_CONF_REG );
292 *clkRatio = ( val & 0x70000000 ) >> 28;
293 *serEnable = ( val & 0x8000000 ) >> 27;
294}
295
296
297/*******************************************************************
298 * sysEUMBBARRead - Read a 32-bit EUMBBAR register
299 *
300 * This routine reads the content of a register in the Embedded
301 * Utilities Memory Block, and swaps to big endian before returning
302 * the value.
303 *
304 * RETURNS: The content of the specified EUMBBAR register.
305 */
306
307ULONG sysEUMBBARRead
308 (
309 ULONG regNum
310 )
311 {
312 ULONG temp;
313
314 temp = *(ULONG *) (CFG_EUMB_ADDR + regNum);
315 return ( LONGSWAP(temp));
316 }
317
318/*******************************************************************
319 * sysEUMBBARWrite - Write a 32-bit EUMBBAR register
320 *
321 * This routine swaps the value to little endian then writes it to
322 * a register in the Embedded Utilities Memory Block address space.
323 *
324 * RETURNS: N/A
325 */
326
327void sysEUMBBARWrite
328 (
329 ULONG regNum, /* EUMBBAR register address */
330 ULONG regVal /* Value to be written */
331 )
332 {
333
334 *(ULONG *) (CFG_EUMB_ADDR + regNum) = LONGSWAP(regVal);
335 return ;
336 }
337
338
339/********************************************************
340 * function: epicVendorId
341 *
342 * description: return the EPIC Vendor Identification
343 * register:
344 *
345 * siliccon version, device id, and vendor id
346 *
347 * note:
348 ********************************************************/
349void epicVendorId
350 (
351 unsigned int *step,
352 unsigned int *devId,
353 unsigned int *venId
354 )
355 {
356 ULONG val;
357 val = sysEUMBBARRead( EPIC_VENDOR_ID_REG );
358 *step = ( val & 0x00FF0000 ) >> 16;
359 *devId = ( val & 0x0000FF00 ) >> 8;
360 *venId = ( val & 0x000000FF );
361 }
362
363/**************************************************
364 * function: epicFeatures
365 *
366 * description: return the number of IRQ supported,
367 * number of CPU, and the version of the
368 * OpenEPIC
369 *
370 * note:
371 *************************************************/
372void epicFeatures
373 (
374 unsigned int *noIRQs,
375 unsigned int *noCPUs,
376 unsigned int *verId
377 )
378 {
379 ULONG val;
380
381 val = sysEUMBBARRead( EPIC_FEATURES_REG );
382 *noIRQs = ( val & 0x07FF0000 ) >> 16;
383 *noCPUs = ( val & 0x00001F00 ) >> 8;
384 *verId = ( val & 0x000000FF );
385}
386
387
388/*********************************************************
389 * function: epciTmFrequncySet
390 *
391 * description: Set the timer frequency reporting register
392 ********************************************************/
393void epicTmFrequencySet( unsigned int frq )
394{
395 sysEUMBBARWrite(EPIC_TM_FREQ_REG, frq);
396}
397
398/*******************************************************
399 * function: epicTmFrequncyGet
400 *
401 * description: Get the current value of the Timer Frequency
402 * Reporting register
403 *
404 ******************************************************/
405unsigned int epicTmFrequencyGet(void)
406{
407 return( sysEUMBBARRead(EPIC_TM_FREQ_REG)) ;
408}
409
410
411/****************************************************
412 * function: epicTmBaseSet
413 *
414 * description: Set the #n global timer base count register
415 * return 0 if no error, otherwise return 1.
416 *
417 * note:
418 ****************************************************/
419unsigned int epicTmBaseSet
420 (
421 ULONG srcAddr, /* Address of the Timer Base register */
422 unsigned int cnt, /* Base count */
423 unsigned int inhibit /* 1 - count inhibit */
424 )
425{
426
427 unsigned int val = 0x80000000;
428 /* First inhibit counting the timer */
429 sysEUMBBARWrite(srcAddr, val) ;
430
431 /* set the new value */
432 val = (cnt & 0x7fffffff) | ((inhibit & 0x1) << 31);
433 sysEUMBBARWrite(srcAddr, val) ;
434 return 0;
435}
436
437/***********************************************************************
438 * function: epicTmBaseGet
439 *
440 * description: Get the current value of the global timer base count register
441 * return 0 if no error, otherwise return 1.
442 *
443 * note:
444 ***********************************************************************/
445unsigned int epicTmBaseGet( ULONG srcAddr, unsigned int *val )
446{
447 *val = sysEUMBBARRead( srcAddr );
448 *val = *val & 0x7fffffff;
449 return 0;
450}
451
452/***********************************************************
453 * function: epicTmCountGet
454 *
455 * description: Get the value of a given global timer
456 * current count register
457 * return 0 if no error, otherwise return 1
458 * note:
459 **********************************************************/
460unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val )
461{
462 *val = sysEUMBBARRead( srcAddr );
463 *val = *val & 0x7fffffff;
464 return 0;
465}
466
467
wdenkaffae2b2002-08-17 09:36:01 +0000468/***********************************************************
469 * function: epicTmInhibit
470 *
471 * description: Stop counting of a given global timer
472 * return 0 if no error, otherwise return 1
473 *
474 * note:
475 ***********************************************************/
476unsigned int epicTmInhibit( unsigned int srcAddr )
477{
478 ULONG val;
479
480 val = sysEUMBBARRead( srcAddr );
481 val |= 0x80000000;
482 sysEUMBBARWrite( srcAddr, val );
483 return 0;
484}
485
486/******************************************************************
487 * function: epicTmEnable
488 *
489 * description: Enable counting of a given global timer
490 * return 0 if no error, otherwise return 1
491 *
492 * note:
493 *****************************************************************/
494unsigned int epicTmEnable( ULONG srcAddr )
495{
496 ULONG val;
497
498 val = sysEUMBBARRead( srcAddr );
499 val &= 0x7fffffff;
500 sysEUMBBARWrite( srcAddr, val );
501 return 0;
502}
503
504void epicSourcePrint(int Vect)
505 {
506 ULONG srcVal;
507
508 srcVal = sysEUMBBARRead(SrcVecTable[Vect].srcAddr);
509 PRINT("%s\n", SrcVecTable[Vect].srcName);
510 PRINT("Address = 0x%lx\n", SrcVecTable[Vect].srcAddr);
511 PRINT("Vector = %ld\n", (srcVal & 0x000000FF) );
512 PRINT("Mask = %ld\n", srcVal >> 31);
513 PRINT("Activitiy = %ld\n", (srcVal & 40000000) >> 30);
514 PRINT("Polarity = %ld\n", (srcVal & 0x00800000) >> 23);
515 PRINT("Sense = %ld\n", (srcVal & 0x00400000) >> 22);
516 PRINT("Priority = %ld\n", (srcVal & 0x000F0000) >> 16);
517 }