forked from Imagelibrary/rtems
2005-12-02 Till Straumann <strauman@slac.stanford.edu>
* shared/irq/irq_init.c, shared/openpic/openpic.h
shared/openpic/openpic.c: The 8240's EPIC has a 'serial'
mode of operation for multiplexing 16 interrupt lines.
This introduces a pipeline delay which can cause
spurious interrupts unless ending the interrupt cycle
(EOI) is delayed accordingly.
This commit is contained in:
@@ -1,3 +1,11 @@
|
|||||||
|
2005-12-02 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
* shared/irq/irq_init.c, shared/openpic/openpic.h
|
||||||
|
shared/openpic/openpic.c: The 8240's EPIC has a 'serial'
|
||||||
|
mode of operation for multiplexing 16 interrupt lines.
|
||||||
|
This introduces a pipeline delay which can cause
|
||||||
|
spurious interrupts unless ending the interrupt cycle
|
||||||
|
(EOI) is delayed accordingly.
|
||||||
|
|
||||||
2005-12-01 Till Straumann <strauman@slac.stanford.edu>
|
2005-12-01 Till Straumann <strauman@slac.stanford.edu>
|
||||||
* shared/vectors/vectors.h, shared/vectors/vectors.S,
|
* shared/vectors/vectors.h, shared/vectors/vectors.S,
|
||||||
shared/vectors/vectors_init.c: Reduced size of default
|
shared/vectors/vectors_init.c: Reduced size of default
|
||||||
|
|||||||
@@ -270,6 +270,39 @@ void BSP_rtems_irq_mng_init(unsigned cpuId)
|
|||||||
printk("Going to initialize EPIC interrupt controller (openpic compliant)\n");
|
printk("Going to initialize EPIC interrupt controller (openpic compliant)\n");
|
||||||
#endif
|
#endif
|
||||||
openpic_init(1, mvme2100_openpic_initpolarities, mvme2100_openpic_initsenses);
|
openpic_init(1, mvme2100_openpic_initpolarities, mvme2100_openpic_initsenses);
|
||||||
|
/* Speed up the serial interface; if it is too slow then we might get spurious
|
||||||
|
* interrupts:
|
||||||
|
* After an ISR clears the interrupt condition at the source/device, the wire
|
||||||
|
* remains asserted during the propagation delay introduced by the serial interface
|
||||||
|
* (something really stupid). If the ISR returns while the wire is not released
|
||||||
|
* yet, then a spurious interrupt happens.
|
||||||
|
* The book says we should be careful if the serial clock is > 33MHz.
|
||||||
|
* Empirically, it seems that running it at 33MHz is fast enough. Otherwise,
|
||||||
|
* we should introduce a delay in openpic_eoi().
|
||||||
|
* The maximal delay are 16 (serial) clock cycles. If the divisor is 8
|
||||||
|
* [power-up default] then the lag is 2us [66MHz SDRAM clock; I assume this
|
||||||
|
* is equal to the bus frequency].
|
||||||
|
* FIXME: This should probably be a 8240-specific piece in 'openpic.c'
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
uint32_t eicr_val, ratio;
|
||||||
|
/* On the 8240 this is the EICR register */
|
||||||
|
eicr_val = in_le32( &OpenPIC->Global.Global_Configuration1 ) & ~(7<<28);
|
||||||
|
if ( (1<<27) & eicr_val ) {
|
||||||
|
/* serial interface mode enabled */
|
||||||
|
|
||||||
|
/* round to nearest integer:
|
||||||
|
* round(Bus_freq/33000000) = floor( 2*(Bus_freq/33e6) + 1 ) / 2
|
||||||
|
*/
|
||||||
|
ratio = BSP_bus_frequency / 16500000 + 1;
|
||||||
|
ratio >>= 2; /* EICR value is half actual divisor */
|
||||||
|
if ( 0==ratio )
|
||||||
|
ratio = 1;
|
||||||
|
out_le32(&OpenPIC->Global.Global_Configuration1, eicr_val | ((ratio &7) << 28));
|
||||||
|
/* Delay in TB cycles (assuming TB runs at 1/4 of the bus frequency) */
|
||||||
|
openpic_set_eoi_delay( 16 * (2*ratio) / 4 );
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#ifdef TRACE_IRQ_INIT
|
#ifdef TRACE_IRQ_INIT
|
||||||
printk("Going to initialize raven interrupt controller (openpic compliant)\n");
|
printk("Going to initialize raven interrupt controller (openpic compliant)\n");
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ volatile struct OpenPIC *OpenPIC = NULL;
|
|||||||
static unsigned int NumProcessors;
|
static unsigned int NumProcessors;
|
||||||
static unsigned int NumSources;
|
static unsigned int NumSources;
|
||||||
|
|
||||||
|
#if defined(mpc8240) || defined(mpc8245)
|
||||||
|
static unsigned int openpic_eoi_delay = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accesses to the current processor's registers
|
* Accesses to the current processor's registers
|
||||||
*/
|
*/
|
||||||
@@ -312,9 +316,20 @@ unsigned int openpic_irq(unsigned int cpu)
|
|||||||
void openpic_eoi(unsigned int cpu)
|
void openpic_eoi(unsigned int cpu)
|
||||||
{
|
{
|
||||||
check_arg_cpu(cpu);
|
check_arg_cpu(cpu);
|
||||||
|
#if defined(mpc8240) || defined(mpc8245)
|
||||||
|
if ( openpic_eoi_delay )
|
||||||
|
rtems_bsp_delay_in_bus_cycles(openpic_eoi_delay);
|
||||||
|
#endif
|
||||||
openpic_write(&OpenPIC->THIS_CPU.EOI, 0);
|
openpic_write(&OpenPIC->THIS_CPU.EOI, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(mpc8240) || defined(mpc8245)
|
||||||
|
void openpic_set_eoi_delay(unsigned tb_cycles)
|
||||||
|
{
|
||||||
|
openpic_eoi_delay = tb_cycles;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get/set the current task priority
|
* Get/set the current task priority
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -43,6 +43,13 @@
|
|||||||
|
|
||||||
#if defined(mpc8240) || defined(mpc8245)
|
#if defined(mpc8240) || defined(mpc8245)
|
||||||
#define OPENPIC_MAX_SOURCES (2048 - 16)
|
#define OPENPIC_MAX_SOURCES (2048 - 16)
|
||||||
|
/* If the BSP uses the serial interrupt mode / 'multiplexer' then
|
||||||
|
* EOI must be delayed by at least 16 SRAM_CLK cycles to avoid
|
||||||
|
* spurious interrupts.
|
||||||
|
* It is the BSP's responsibility to set up an appropriate delay
|
||||||
|
* (in timebase-clock cycles) at init time.
|
||||||
|
*/
|
||||||
|
extern void openpic_set_eoi_delay(unsigned tb_cycles);
|
||||||
#else
|
#else
|
||||||
#define OPENPIC_MAX_SOURCES 2048
|
#define OPENPIC_MAX_SOURCES 2048
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user