Fixed tools/env utilities
[u-boot-openmoko/mini2440.git] / cpu / mpc824x / drivers / epic / epic1.c
blobf89deed538bd5becaa9c9afff7762013bc504b58
1 /**************************************************
3 * copyright @ motorola, 1999
5 *************************************************/
6 #include <mpc824x.h>
7 #include <common.h>
8 #include "epic.h"
11 #define PRINT(format, args...) printf(format , ## args)
13 typedef void (*VOIDFUNCPTR) (void); /* ptr to function returning void */
14 struct SrcVecTable SrcVecTable[MAXVEC] = /* Addr/Vector cross-reference tbl */
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"},
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"},
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"},
40 VOIDFUNCPTR intVecTbl[MAXVEC]; /* Interrupt vector table */
43 /****************************************************************************
44 * epicInit - Initialize the EPIC registers
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).
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
62 void epicInit
64 unsigned int IRQType, /* Direct or Serial */
65 unsigned int clkRatio /* Clk Ratio for Serial IRQs */
68 ULONG tmp;
70 tmp = sysEUMBBARRead(EPIC_GLOBAL_REG);
71 tmp |= 0xa0000000; /* Set the Global Conf. register */
72 sysEUMBBARWrite(EPIC_GLOBAL_REG, tmp);
74 * Wait for EPIC to reset - CLH
76 while( (sysEUMBBARRead(EPIC_GLOBAL_REG) & 0x80000000) == 1);
77 sysEUMBBARWrite(EPIC_GLOBAL_REG, 0x20000000);
78 tmp = sysEUMBBARRead(EPIC_INT_CONF_REG); /* Read interrupt conf. reg */
80 if (IRQType == EPIC_DIRECT_IRQ) /* direct mode */
81 sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp & 0xf7ffffff);
82 else /* Serial mode */
84 tmp = (clkRatio << 28) | 0x08000000; /* Set clock ratio */
85 sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp);
88 while (epicIntAck() != 0xff) /* Clear all pending interrupts */
89 epicEOI();
92 /****************************************************************************
93 * epicIntEnable - Enable an interrupt source
95 * This routine clears the mask bit of an external, an internal or
96 * a Timer register to enable the interrupt.
98 * RETURNS: None
100 void epicIntEnable(int intVec)
102 ULONG tmp;
103 ULONG srAddr;
105 srAddr = SrcVecTable[intVec].srcAddr; /* Retrieve src Vec/Prio register */
106 tmp = sysEUMBBARRead(srAddr);
107 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 */
110 sysEUMBBARWrite(srAddr, tmp);
112 return;
115 /****************************************************************************
116 * epicIntDisable - Disable an interrupt source
118 * This routine sets the mask bit of an external, an internal or
119 * a Timer register to disable the interrupt.
121 * RETURNS: OK or ERROR
125 void epicIntDisable
127 int intVec /* Interrupt vector number */
131 ULONG tmp, srAddr;
133 srAddr = SrcVecTable[intVec].srcAddr;
134 tmp = sysEUMBBARRead(srAddr);
135 tmp |= 0x80000000; /* Set the mask bit */
136 sysEUMBBARWrite(srAddr, tmp);
137 return;
140 /****************************************************************************
141 * epicIntSourceConfig - Set properties of an interrupt source
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).
149 * This function assumes that the Source Vector/Priority register (input)
150 * is a valid address.
152 * RETURNS: OK or ERROR
155 int epicIntSourceConfig
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 */
164 ULONG tmp, newVal;
165 ULONG actBit, srAddr;
167 srAddr = SrcVecTable[Vect].srcAddr;
168 tmp = sysEUMBBARRead(srAddr);
169 actBit = (tmp & 40000000) >> 30; /* retrieve activity bit - bit 30 */
170 if (actBit == 1)
171 return ERROR;
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);
179 /****************************************************************************
180 * epicIntAck - acknowledge an interrupt
182 * This function reads the Interrupt acknowldge register and return
183 * the vector number of the highest pending interrupt.
185 * RETURNS: Interrupt Vector number.
188 unsigned int epicIntAck(void)
190 return(sysEUMBBARRead( EPIC_PROC_INT_ACK_REG ));
193 /****************************************************************************
194 * epicEOI - signal an end of interrupt
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.
199 * RETURNS: None
202 void epicEOI(void)
204 sysEUMBBARWrite(EPIC_PROC_EOI_REG, 0x0);
207 /****************************************************************************
208 * epicCurTaskPrioSet - sets the priority of the Processor Current Task
210 * This function should be called after epicInit() to lower the priority
211 * of the processor current task.
213 * RETURNS: OK or ERROR
216 int epicCurTaskPrioSet
218 int prioNum /* New priority value */
222 if ( (prioNum < 0) || (prioNum > 0xF))
223 return ERROR;
224 sysEUMBBARWrite(EPIC_PROC_CTASK_PRI_REG, prioNum);
225 return OK;
229 /************************************************************************
230 * function: epicIntTaskGet
232 * description: Get value of processor current interrupt task priority register
234 * note:
235 ***********************************************************************/
236 unsigned char epicIntTaskGet()
238 /* get the interrupt task priority register */
239 ULONG reg;
240 unsigned char rec;
242 reg = sysEUMBBARRead( EPIC_PROC_CTASK_PRI_REG );
243 rec = ( reg & 0x0F );
244 return rec;
248 /**************************************************************
249 * function: epicISR
251 * description: EPIC service routine called by the core exception
252 * at 0x500
254 * note:
255 **************************************************************/
256 unsigned int epicISR(void)
258 return 0;
262 /************************************************************
263 * function: epicModeGet
265 * description: query EPIC mode, return 0 if pass through mode
266 * return 1 if mixed mode
268 * note:
269 *************************************************************/
270 unsigned int epicModeGet(void)
272 ULONG val;
274 val = sysEUMBBARRead( EPIC_GLOBAL_REG );
275 return (( val & 0x20000000 ) >> 29);
279 /*********************************************
280 * function: epicConfigGet
282 * description: Get the EPIC interrupt Configuration
283 * return 0 if not error, otherwise return 1
285 * note:
286 ********************************************/
287 void epicConfigGet( unsigned int *clkRatio, unsigned int *serEnable)
289 ULONG val;
291 val = sysEUMBBARRead( EPIC_INT_CONF_REG );
292 *clkRatio = ( val & 0x70000000 ) >> 28;
293 *serEnable = ( val & 0x8000000 ) >> 27;
297 /*******************************************************************
298 * sysEUMBBARRead - Read a 32-bit EUMBBAR register
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.
304 * RETURNS: The content of the specified EUMBBAR register.
307 ULONG sysEUMBBARRead
309 ULONG regNum
312 ULONG temp;
314 temp = *(ULONG *) (CFG_EUMB_ADDR + regNum);
315 return ( LONGSWAP(temp));
318 /*******************************************************************
319 * sysEUMBBARWrite - Write a 32-bit EUMBBAR register
321 * This routine swaps the value to little endian then writes it to
322 * a register in the Embedded Utilities Memory Block address space.
324 * RETURNS: N/A
327 void sysEUMBBARWrite
329 ULONG regNum, /* EUMBBAR register address */
330 ULONG regVal /* Value to be written */
334 *(ULONG *) (CFG_EUMB_ADDR + regNum) = LONGSWAP(regVal);
335 return ;
339 /********************************************************
340 * function: epicVendorId
342 * description: return the EPIC Vendor Identification
343 * register:
345 * siliccon version, device id, and vendor id
347 * note:
348 ********************************************************/
349 void epicVendorId
351 unsigned int *step,
352 unsigned int *devId,
353 unsigned int *venId
356 ULONG val;
357 val = sysEUMBBARRead( EPIC_VENDOR_ID_REG );
358 *step = ( val & 0x00FF0000 ) >> 16;
359 *devId = ( val & 0x0000FF00 ) >> 8;
360 *venId = ( val & 0x000000FF );
363 /**************************************************
364 * function: epicFeatures
366 * description: return the number of IRQ supported,
367 * number of CPU, and the version of the
368 * OpenEPIC
370 * note:
371 *************************************************/
372 void epicFeatures
374 unsigned int *noIRQs,
375 unsigned int *noCPUs,
376 unsigned int *verId
379 ULONG val;
381 val = sysEUMBBARRead( EPIC_FEATURES_REG );
382 *noIRQs = ( val & 0x07FF0000 ) >> 16;
383 *noCPUs = ( val & 0x00001F00 ) >> 8;
384 *verId = ( val & 0x000000FF );
388 /*********************************************************
389 * function: epciTmFrequncySet
391 * description: Set the timer frequency reporting register
392 ********************************************************/
393 void epicTmFrequencySet( unsigned int frq )
395 sysEUMBBARWrite(EPIC_TM_FREQ_REG, frq);
398 /*******************************************************
399 * function: epicTmFrequncyGet
401 * description: Get the current value of the Timer Frequency
402 * Reporting register
404 ******************************************************/
405 unsigned int epicTmFrequencyGet(void)
407 return( sysEUMBBARRead(EPIC_TM_FREQ_REG)) ;
411 /****************************************************
412 * function: epicTmBaseSet
414 * description: Set the #n global timer base count register
415 * return 0 if no error, otherwise return 1.
417 * note:
418 ****************************************************/
419 unsigned int epicTmBaseSet
421 ULONG srcAddr, /* Address of the Timer Base register */
422 unsigned int cnt, /* Base count */
423 unsigned int inhibit /* 1 - count inhibit */
427 unsigned int val = 0x80000000;
428 /* First inhibit counting the timer */
429 sysEUMBBARWrite(srcAddr, val) ;
431 /* set the new value */
432 val = (cnt & 0x7fffffff) | ((inhibit & 0x1) << 31);
433 sysEUMBBARWrite(srcAddr, val) ;
434 return 0;
437 /***********************************************************************
438 * function: epicTmBaseGet
440 * description: Get the current value of the global timer base count register
441 * return 0 if no error, otherwise return 1.
443 * note:
444 ***********************************************************************/
445 unsigned int epicTmBaseGet( ULONG srcAddr, unsigned int *val )
447 *val = sysEUMBBARRead( srcAddr );
448 *val = *val & 0x7fffffff;
449 return 0;
452 /***********************************************************
453 * function: epicTmCountGet
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 **********************************************************/
460 unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val )
462 *val = sysEUMBBARRead( srcAddr );
463 *val = *val & 0x7fffffff;
464 return 0;
468 /***********************************************************
469 * function: epicTmInhibit
471 * description: Stop counting of a given global timer
472 * return 0 if no error, otherwise return 1
474 * note:
475 ***********************************************************/
476 unsigned int epicTmInhibit( unsigned int srcAddr )
478 ULONG val;
480 val = sysEUMBBARRead( srcAddr );
481 val |= 0x80000000;
482 sysEUMBBARWrite( srcAddr, val );
483 return 0;
486 /******************************************************************
487 * function: epicTmEnable
489 * description: Enable counting of a given global timer
490 * return 0 if no error, otherwise return 1
492 * note:
493 *****************************************************************/
494 unsigned int epicTmEnable( ULONG srcAddr )
496 ULONG val;
498 val = sysEUMBBARRead( srcAddr );
499 val &= 0x7fffffff;
500 sysEUMBBARWrite( srcAddr, val );
501 return 0;
504 void epicSourcePrint(int Vect)
506 ULONG srcVal;
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);