summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2005-12-02 20:45:57 +0000
committerTill Straumann <strauman@slac.stanford.edu>2005-12-02 20:45:57 +0000
commit0ed348f4b81faafd8f0f8606170375375831212d (patch)
treeca0b38aed4c48a540483ca8dea7ae4b3a67ee174 /c
parent2005-12-01 Till Straumann <strauman@slac.stanford.edu> (diff)
downloadrtems-0ed348f4b81faafd8f0f8606170375375831212d.tar.bz2
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.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/powerpc/ChangeLog8
-rw-r--r--c/src/lib/libbsp/powerpc/shared/irq/irq_init.c33
-rw-r--r--c/src/lib/libbsp/powerpc/shared/openpic/openpic.c15
-rw-r--r--c/src/lib/libbsp/powerpc/shared/openpic/openpic.h7
4 files changed, 63 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/ChangeLog b/c/src/lib/libbsp/powerpc/ChangeLog
index f90411188e..9cfa146a43 100644
--- a/c/src/lib/libbsp/powerpc/ChangeLog
+++ b/c/src/lib/libbsp/powerpc/ChangeLog
@@ -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>
* shared/vectors/vectors.h, shared/vectors/vectors.S,
shared/vectors/vectors_init.c: Reduced size of default
diff --git a/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c b/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c
index 231edab695..fb70847918 100644
--- a/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c
+++ b/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c
@@ -270,6 +270,39 @@ void BSP_rtems_irq_mng_init(unsigned cpuId)
printk("Going to initialize EPIC interrupt controller (openpic compliant)\n");
#endif
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
#ifdef TRACE_IRQ_INIT
printk("Going to initialize raven interrupt controller (openpic compliant)\n");
diff --git a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c
index 80af4d897b..ab9b8c49da 100644
--- a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c
+++ b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c
@@ -39,6 +39,10 @@ volatile struct OpenPIC *OpenPIC = NULL;
static unsigned int NumProcessors;
static unsigned int NumSources;
+#if defined(mpc8240) || defined(mpc8245)
+static unsigned int openpic_eoi_delay = 0;
+#endif
+
/*
* Accesses to the current processor's registers
*/
@@ -312,9 +316,20 @@ unsigned int openpic_irq(unsigned int cpu)
void openpic_eoi(unsigned int 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);
}
+#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
*/
diff --git a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h
index e70a55605b..492742188f 100644
--- a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h
+++ b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h
@@ -43,6 +43,13 @@
#if defined(mpc8240) || defined(mpc8245)
#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
#define OPENPIC_MAX_SOURCES 2048
#endif