EPIC support for PPC
This commit is contained in:
parent
b079059d48
commit
e600ebc698
1 changed files with 517 additions and 0 deletions
517
src/northbridge/motorola/mpc107/epic.c
Normal file
517
src/northbridge/motorola/mpc107/epic.c
Normal file
|
|
@ -0,0 +1,517 @@
|
|||
/**************************************************
|
||||
*
|
||||
* copyright @ motorola, 1999
|
||||
*
|
||||
*************************************************/
|
||||
#include <pci.h>
|
||||
#include <printk.h>
|
||||
#include <northbridge/motorola/mpc107/epic.h>
|
||||
|
||||
extern struct pci_ops pci_direct_ppc;
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
u32 temp;
|
||||
|
||||
pci_direct_ppc.read_dword(0, 0, regNum, &temp);
|
||||
return ( 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 */
|
||||
u32 regVal /* Value to be written */
|
||||
)
|
||||
{
|
||||
|
||||
pci_direct_ppc.read_dword(0, 0, regNum, ®Val);
|
||||
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);
|
||||
printk_info("%s\n", SrcVecTable[Vect].srcName);
|
||||
printk_info("Address = 0x%lx\n", SrcVecTable[Vect].srcAddr);
|
||||
printk_info("Vector = %ld\n", (srcVal & 0x000000FF) );
|
||||
printk_info("Mask = %ld\n", srcVal >> 31);
|
||||
printk_info("Activitiy = %ld\n", (srcVal & 40000000) >> 30);
|
||||
printk_info("Polarity = %ld\n", (srcVal & 0x00800000) >> 23);
|
||||
printk_info("Sense = %ld\n", (srcVal & 0x00400000) >> 22);
|
||||
printk_info("Priority = %ld\n", (srcVal & 0x000F0000) >> 16);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue