mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-27 05:23:34 +00:00
a47a12becf
As discussed on the list, move "arch/ppc" to "arch/powerpc" to better match the Linux directory structure. Please note that this patch also changes the "ppc" target in MAKEALL to "powerpc" to match this new infrastructure. But "ppc" is kept as an alias for now, to not break compatibility with scripts using this name. Signed-off-by: Stefan Roese <sr@denx.de> Acked-by: Wolfgang Denk <wd@denx.de> Acked-by: Detlev Zundel <dzu@denx.de> Acked-by: Kim Phillips <kim.phillips@freescale.com> Cc: Peter Tyser <ptyser@xes-inc.com> Cc: Anatolij Gustschin <agust@denx.de>
517 lines
15 KiB
C
517 lines
15 KiB
C
/**************************************************
|
|
*
|
|
* 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);
|
|
}
|