]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/mpc824x/drivers/epic/epic1.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / arch / powerpc / cpu / mpc824x / drivers / epic / epic1.c
1 /**************************************************
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
13 typedef void (*VOIDFUNCPTR)  (void);  /* ptr to function returning void */
14 struct 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
40 VOIDFUNCPTR 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
62 void 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);
73         /*
74          * Wait for EPIC to reset - CLH
75          */
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 */
79
80     if (IRQType == EPIC_DIRECT_IRQ)             /* direct mode */
81         sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp & 0xf7ffffff);
82     else                                        /* Serial mode */
83         {
84         tmp = (clkRatio << 28) | 0x08000000;    /* Set clock ratio */
85         sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp);
86         }
87
88     while (epicIntAck() != 0xff)       /* Clear all pending interrupts */
89                 epicEOI();
90 }
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  */
100 void epicIntEnable(int intVec)
101 {
102     ULONG tmp;
103     ULONG srAddr;
104
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);
111
112     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
125 void 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
155 int 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)
171         return ERROR;
172
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
188 unsigned 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
202 void 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
216 int epicCurTaskPrioSet
217     (
218     int prioNum                 /* New priority value */
219     )
220     {
221
222     if ( (prioNum < 0) || (prioNum > 0xF))
223         return ERROR;
224     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  ***********************************************************************/
236 unsigned 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  **************************************************************/
256 unsigned 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  *************************************************************/
270 unsigned 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  ********************************************/
287 void 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
307 ULONG sysEUMBBARRead
308     (
309     ULONG regNum
310     )
311     {
312     ULONG temp;
313
314     temp = *(ULONG *) (CONFIG_SYS_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
327 void sysEUMBBARWrite
328     (
329     ULONG regNum,               /* EUMBBAR register address */
330     ULONG regVal                /* Value to be written */
331     )
332     {
333
334     *(ULONG *) (CONFIG_SYS_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  ********************************************************/
349 void 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  *************************************************/
372 void 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  ********************************************************/
393 void 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  ******************************************************/
405 unsigned 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  ****************************************************/
419 unsigned 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  ***********************************************************************/
445 unsigned 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  **********************************************************/
460 unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val )
461 {
462     *val = sysEUMBBARRead( srcAddr );
463     *val = *val & 0x7fffffff;
464     return 0;
465 }
466
467
468 /***********************************************************
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  ***********************************************************/
476 unsigned 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  *****************************************************************/
494 unsigned 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
504 void 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     }