Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / arch / powerpc / cpu / mpc824x / drivers / epic / epic1.c
diff --git a/qemu/roms/u-boot/arch/powerpc/cpu/mpc824x/drivers/epic/epic1.c b/qemu/roms/u-boot/arch/powerpc/cpu/mpc824x/drivers/epic/epic1.c
new file mode 100644 (file)
index 0000000..ecbb42d
--- /dev/null
@@ -0,0 +1,517 @@
+/**************************************************
+ *
+ * copyright @ motorola, 1999
+ *
+ *************************************************/
+#include <mpc824x.h>
+#include <common.h>
+#include "epic.h"
+
+
+#define PRINT(format, args...) printf(format , ## args)
+
+typedef void (*VOIDFUNCPTR)  (void);  /* ptr to function returning void */
+struct SrcVecTable SrcVecTable[MAXVEC] = /* Addr/Vector cross-reference tbl */
+    {
+    { EPIC_EX_INT0_VEC_REG,  "External Direct/Serial Source 0"},
+    { EPIC_EX_INT1_VEC_REG,  "External Direct/Serial Source 1"},
+    { EPIC_EX_INT2_VEC_REG,  "External Direct/Serial Source 2"},
+    { EPIC_EX_INT3_VEC_REG,  "External Direct/Serial Source 3"},
+    { EPIC_EX_INT4_VEC_REG,  "External Direct/Serial Source 4"},
+
+    { EPIC_SR_INT5_VEC_REG,  "External Serial Source 5"},
+    { EPIC_SR_INT6_VEC_REG,  "External Serial Source 6"},
+    { EPIC_SR_INT7_VEC_REG,  "External Serial Source 7"},
+    { EPIC_SR_INT8_VEC_REG,  "External Serial Source 8"},
+    { EPIC_SR_INT9_VEC_REG,  "External Serial Source 9"},
+    { EPIC_SR_INT10_VEC_REG, "External Serial Source 10"},
+    { EPIC_SR_INT11_VEC_REG, "External Serial Source 11"},
+    { EPIC_SR_INT12_VEC_REG, "External Serial Source 12"},
+    { EPIC_SR_INT13_VEC_REG, "External Serial Source 13"},
+    { EPIC_SR_INT14_VEC_REG, "External Serial Source 14"},
+    { EPIC_SR_INT15_VEC_REG, "External Serial Source 15"},
+
+    { EPIC_I2C_INT_VEC_REG,  "Internal I2C Source"},
+    { EPIC_DMA0_INT_VEC_REG, "Internal DMA0 Source"},
+    { EPIC_DMA1_INT_VEC_REG, "Internal DMA1 Source"},
+    { EPIC_MSG_INT_VEC_REG,  "Internal Message Source"},
+    };
+
+VOIDFUNCPTR intVecTbl[MAXVEC];    /* Interrupt vector table */
+
+
+/****************************************************************************
+*  epicInit - Initialize the EPIC registers
+*
+*  This routine resets the Global Configuration Register, thus it:
+*     -  Disables all interrupts
+*     -  Sets epic registers to reset values
+*     -  Sets the value of the Processor Current Task Priority to the
+*        highest priority (0xF).
+*  epicInit then sets the EPIC operation mode to Mixed Mode (vs. Pass
+*  Through or 8259 compatible mode).
+*
+*  If IRQType (input) is Direct IRQs:
+*     - IRQType is written to the SIE bit of the EPIC Interrupt
+*       Configuration register (ICR).
+*     - clkRatio is ignored.
+*  If IRQType is Serial IRQs:
+*     - both IRQType and clkRatio will be written to the ICR register
+*/
+
+void epicInit
+    (
+    unsigned int IRQType,      /* Direct or Serial */
+    unsigned int clkRatio      /* Clk Ratio for Serial IRQs */
+    )
+    {
+    ULONG tmp;
+
+    tmp = sysEUMBBARRead(EPIC_GLOBAL_REG);
+    tmp |= 0xa0000000;                  /* Set the Global Conf. register */
+    sysEUMBBARWrite(EPIC_GLOBAL_REG, tmp);
+       /*
+        * Wait for EPIC to reset - CLH
+        */
+    while( (sysEUMBBARRead(EPIC_GLOBAL_REG) & 0x80000000) == 1);
+    sysEUMBBARWrite(EPIC_GLOBAL_REG, 0x20000000);
+    tmp = sysEUMBBARRead(EPIC_INT_CONF_REG);    /* Read interrupt conf. reg */
+
+    if (IRQType == EPIC_DIRECT_IRQ)             /* direct mode */
+       sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp & 0xf7ffffff);
+    else                                        /* Serial mode */
+       {
+       tmp = (clkRatio << 28) | 0x08000000;    /* Set clock ratio */
+       sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp);
+       }
+
+    while (epicIntAck() != 0xff)       /* Clear all pending interrupts */
+               epicEOI();
+}
+
+/****************************************************************************
+ *  epicIntEnable - Enable an interrupt source
+ *
+ *  This routine clears the mask bit of an external, an internal or
+ *  a Timer register to enable the interrupt.
+ *
+ *  RETURNS:  None
+ */
+void epicIntEnable(int intVec)
+{
+    ULONG tmp;
+    ULONG srAddr;
+
+    srAddr = SrcVecTable[intVec].srcAddr;  /* Retrieve src Vec/Prio register */
+    tmp = sysEUMBBARRead(srAddr);
+    tmp &= ~EPIC_VEC_PRI_MASK;             /* Clear the mask bit */
+    tmp |= (EPIC_VEC_PRI_DFLT_PRI << 16);   /* Set priority to Default - CLH */
+    tmp |= intVec;                                        /* Set Vector number */
+    sysEUMBBARWrite(srAddr, tmp);
+
+    return;
+    }
+
+/****************************************************************************
+ *  epicIntDisable - Disable an interrupt source
+ *
+ *  This routine sets the mask bit of an external, an internal or
+ *  a Timer register to disable the interrupt.
+ *
+ *  RETURNS:  OK or ERROR
+ *
+ */
+
+void epicIntDisable
+    (
+    int intVec        /* Interrupt vector number */
+    )
+    {
+
+    ULONG tmp, srAddr;
+
+    srAddr = SrcVecTable[intVec].srcAddr;
+    tmp = sysEUMBBARRead(srAddr);
+    tmp |= 0x80000000;                      /* Set the mask bit */
+    sysEUMBBARWrite(srAddr, tmp);
+    return;
+    }
+
+/****************************************************************************
+ * epicIntSourceConfig - Set properties of an interrupt source
+ *
+ * This function sets interrupt properites (Polarity, Sense, Interrupt
+ * Prority, and Interrupt Vector) of an Interrupt Source.  The properties
+ * can be set when the current source is not in-request or in-service,
+ * which is determined by the Activity bit.  This routine return ERROR
+ * if the the Activity bit is 1 (in-request or in-service).
+ *
+ * This function assumes that the Source Vector/Priority register (input)
+ * is a valid address.
+ *
+ * RETURNS:  OK or ERROR
+ */
+
+int epicIntSourceConfig
+    (
+    int   Vect,                         /* interrupt source vector number */
+    int   Polarity,                     /* interrupt source polarity */
+    int   Sense,                        /* interrupt source Sense */
+    int   Prio                          /* interrupt source priority */
+    )
+
+    {
+    ULONG tmp, newVal;
+    ULONG actBit, srAddr;
+
+    srAddr = SrcVecTable[Vect].srcAddr;
+    tmp = sysEUMBBARRead(srAddr);
+    actBit = (tmp & 40000000) >> 30;    /* retrieve activity bit - bit 30 */
+    if (actBit == 1)
+       return ERROR;
+
+    tmp &= 0xff30ff00;     /* Erase previously set P,S,Prio,Vector bits */
+    newVal = (Polarity << 23) | (Sense << 22) | (Prio << 16) | Vect;
+    sysEUMBBARWrite(srAddr, tmp | newVal );
+    return (OK);
+    }
+
+/****************************************************************************
+ * epicIntAck - acknowledge an interrupt
+ *
+ * This function reads the Interrupt acknowldge register and return
+ * the vector number of the highest pending interrupt.
+ *
+ * RETURNS: Interrupt Vector number.
+ */
+
+unsigned int epicIntAck(void)
+{
+    return(sysEUMBBARRead( EPIC_PROC_INT_ACK_REG ));
+}
+
+/****************************************************************************
+ * epicEOI - signal an end of interrupt
+ *
+ * This function writes 0x0 to the EOI register to signal end of interrupt.
+ * It is usually called after an interrupt routine is served.
+ *
+ * RETURNS: None
+ */
+
+void epicEOI(void)
+    {
+    sysEUMBBARWrite(EPIC_PROC_EOI_REG, 0x0);
+    }
+
+/****************************************************************************
+ *  epicCurTaskPrioSet - sets the priority of the Processor Current Task
+ *
+ *  This function should be called after epicInit() to lower the priority
+ *  of the processor current task.
+ *
+ *  RETURNS:  OK or ERROR
+ */
+
+int epicCurTaskPrioSet
+    (
+    int prioNum                 /* New priority value */
+    )
+    {
+
+    if ( (prioNum < 0) || (prioNum > 0xF))
+       return ERROR;
+    sysEUMBBARWrite(EPIC_PROC_CTASK_PRI_REG, prioNum);
+    return OK;
+    }
+
+
+/************************************************************************
+ * function: epicIntTaskGet
+ *
+ * description: Get value of processor current interrupt task priority register
+ *
+ * note:
+ ***********************************************************************/
+unsigned char epicIntTaskGet()
+{
+  /* get the interrupt task priority register */
+    ULONG reg;
+    unsigned char rec;
+
+    reg = sysEUMBBARRead( EPIC_PROC_CTASK_PRI_REG );
+    rec = ( reg & 0x0F );
+    return rec;
+}
+
+
+/**************************************************************
+ * function: epicISR
+ *
+ * description: EPIC service routine called by the core exception
+ *              at 0x500
+ *
+ * note:
+ **************************************************************/
+unsigned int epicISR(void)
+{
+   return 0;
+}
+
+
+/************************************************************
+ * function: epicModeGet
+ *
+ * description: query EPIC mode, return 0 if pass through mode
+ *                               return 1 if mixed mode
+ *
+ * note:
+ *************************************************************/
+unsigned int epicModeGet(void)
+{
+    ULONG val;
+
+    val = sysEUMBBARRead( EPIC_GLOBAL_REG );
+    return (( val & 0x20000000 ) >> 29);
+}
+
+
+/*********************************************
+ * function: epicConfigGet
+ *
+ * description: Get the EPIC interrupt Configuration
+ *              return 0 if not error, otherwise return 1
+ *
+ * note:
+ ********************************************/
+void epicConfigGet( unsigned int *clkRatio, unsigned int *serEnable)
+{
+    ULONG val;
+
+    val = sysEUMBBARRead( EPIC_INT_CONF_REG );
+    *clkRatio = ( val & 0x70000000 ) >> 28;
+    *serEnable = ( val & 0x8000000 ) >> 27;
+}
+
+
+/*******************************************************************
+ *  sysEUMBBARRead - Read a 32-bit EUMBBAR register
+ *
+ *  This routine reads the content of a register in the Embedded
+ *  Utilities Memory Block, and swaps to big endian before returning
+ *  the value.
+ *
+ *  RETURNS:  The content of the specified EUMBBAR register.
+ */
+
+ULONG sysEUMBBARRead
+    (
+    ULONG regNum
+    )
+    {
+    ULONG temp;
+
+    temp = *(ULONG *) (CONFIG_SYS_EUMB_ADDR + regNum);
+    return ( LONGSWAP(temp));
+    }
+
+/*******************************************************************
+ *  sysEUMBBARWrite - Write a 32-bit EUMBBAR register
+ *
+ *  This routine swaps the value to little endian then writes it to
+ *  a register in the Embedded Utilities Memory Block address space.
+ *
+ *  RETURNS: N/A
+ */
+
+void sysEUMBBARWrite
+    (
+    ULONG regNum,               /* EUMBBAR register address */
+    ULONG regVal                /* Value to be written */
+    )
+    {
+
+    *(ULONG *) (CONFIG_SYS_EUMB_ADDR + regNum) = LONGSWAP(regVal);
+    return ;
+    }
+
+
+/********************************************************
+ * function: epicVendorId
+ *
+ * description: return the EPIC Vendor Identification
+ *              register:
+ *
+ *              siliccon version, device id, and vendor id
+ *
+ * note:
+ ********************************************************/
+void epicVendorId
+   (
+    unsigned int *step,
+    unsigned int *devId,
+    unsigned int *venId
+   )
+   {
+    ULONG val;
+    val = sysEUMBBARRead( EPIC_VENDOR_ID_REG );
+    *step  = ( val & 0x00FF0000 ) >> 16;
+    *devId = ( val & 0x0000FF00 ) >> 8;
+    *venId = ( val & 0x000000FF );
+    }
+
+/**************************************************
+ * function: epicFeatures
+ *
+ * description: return the number of IRQ supported,
+ *              number of CPU, and the version of the
+ *              OpenEPIC
+ *
+ * note:
+ *************************************************/
+void epicFeatures
+    (
+    unsigned int *noIRQs,
+    unsigned int *noCPUs,
+    unsigned int *verId
+    )
+    {
+    ULONG val;
+
+    val = sysEUMBBARRead( EPIC_FEATURES_REG );
+    *noIRQs  = ( val & 0x07FF0000 ) >> 16;
+    *noCPUs  = ( val & 0x00001F00 ) >> 8;
+    *verId   = ( val & 0x000000FF );
+}
+
+
+/*********************************************************
+ * function: epciTmFrequncySet
+ *
+ * description: Set the timer frequency reporting register
+ ********************************************************/
+void epicTmFrequencySet( unsigned int frq )
+{
+    sysEUMBBARWrite(EPIC_TM_FREQ_REG, frq);
+}
+
+/*******************************************************
+ * function: epicTmFrequncyGet
+ *
+ * description: Get the current value of the Timer Frequency
+ * Reporting register
+ *
+ ******************************************************/
+unsigned int epicTmFrequencyGet(void)
+{
+    return( sysEUMBBARRead(EPIC_TM_FREQ_REG)) ;
+}
+
+
+/****************************************************
+ * function: epicTmBaseSet
+ *
+ * description: Set the #n global timer base count register
+ *              return 0 if no error, otherwise return 1.
+ *
+ * note:
+ ****************************************************/
+unsigned int epicTmBaseSet
+    (
+    ULONG srcAddr,         /* Address of the Timer Base register */
+    unsigned int cnt,    /* Base count */
+    unsigned int inhibit   /* 1 - count inhibit */
+    )
+{
+
+    unsigned int val = 0x80000000;
+    /* First inhibit counting the timer */
+    sysEUMBBARWrite(srcAddr, val) ;
+
+    /* set the new value */
+    val = (cnt & 0x7fffffff) | ((inhibit & 0x1) << 31);
+    sysEUMBBARWrite(srcAddr, val) ;
+    return 0;
+}
+
+/***********************************************************************
+ * function: epicTmBaseGet
+ *
+ * description: Get the current value of the global timer base count register
+ *              return 0 if no error, otherwise return 1.
+ *
+ * note:
+ ***********************************************************************/
+unsigned int epicTmBaseGet( ULONG srcAddr, unsigned int *val )
+{
+    *val = sysEUMBBARRead( srcAddr );
+    *val = *val & 0x7fffffff;
+    return 0;
+}
+
+/***********************************************************
+ * function: epicTmCountGet
+ *
+ * description: Get the value of a given global timer
+ *              current count register
+ *              return 0 if no error, otherwise return 1
+ * note:
+ **********************************************************/
+unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val )
+{
+    *val = sysEUMBBARRead( srcAddr );
+    *val = *val & 0x7fffffff;
+    return 0;
+}
+
+
+/***********************************************************
+ * function: epicTmInhibit
+ *
+ * description: Stop counting of a given global timer
+ *              return 0 if no error, otherwise return 1
+ *
+ * note:
+ ***********************************************************/
+unsigned int epicTmInhibit( unsigned int srcAddr )
+{
+    ULONG val;
+
+    val = sysEUMBBARRead( srcAddr );
+    val |= 0x80000000;
+    sysEUMBBARWrite( srcAddr, val );
+    return 0;
+}
+
+/******************************************************************
+ * function: epicTmEnable
+ *
+ * description: Enable counting of a given global timer
+ *              return 0 if no error, otherwise return 1
+ *
+ * note:
+ *****************************************************************/
+unsigned int epicTmEnable( ULONG srcAddr )
+{
+    ULONG val;
+
+    val = sysEUMBBARRead( srcAddr );
+    val &= 0x7fffffff;
+    sysEUMBBARWrite( srcAddr, val );
+    return 0;
+}
+
+void epicSourcePrint(int Vect)
+    {
+    ULONG srcVal;
+
+    srcVal = sysEUMBBARRead(SrcVecTable[Vect].srcAddr);
+    PRINT("%s\n", SrcVecTable[Vect].srcName);
+    PRINT("Address   = 0x%lx\n", SrcVecTable[Vect].srcAddr);
+    PRINT("Vector    = %ld\n", (srcVal & 0x000000FF) );
+    PRINT("Mask      = %ld\n", srcVal >> 31);
+    PRINT("Activitiy = %ld\n", (srcVal & 40000000) >> 30);
+    PRINT("Polarity  = %ld\n", (srcVal & 0x00800000) >> 23);
+    PRINT("Sense     = %ld\n", (srcVal & 0x00400000) >> 22);
+    PRINT("Priority  = %ld\n", (srcVal & 0x000F0000) >> 16);
+    }