diff options
author | Till Straumann <strauman@slac.stanford.edu> | 2007-12-02 21:35:49 +0000 |
---|---|---|
committer | Till Straumann <strauman@slac.stanford.edu> | 2007-12-02 21:35:49 +0000 |
commit | d7a2009a6392a5c6ddeefc8d2f0e8d1f5e7d879b (patch) | |
tree | 0bb565b182a0ea7739592ac3230cba2be0cdc4d5 /c | |
parent | 2007-12-02 Till Straumann <strauman@slac.stanford.edu> (diff) | |
download | rtems-d7a2009a6392a5c6ddeefc8d2f0e8d1f5e7d879b.tar.bz2 |
2007-12-02 Till Straumann <strauman@slac.stanford.edu>
* shared/openpic/openpic.c shared/openpic/openpic.h,
shared/irq/irq_init.c: added more parameters to
openpic_init() so that more details of the configuration
can be overridden/set from the BSP. Moved setup of
the EPIC-specific EOI delay from BSP code into openpic_init()
using the new 'epic_freq' parameter.
Diffstat (limited to 'c')
-rw-r--r-- | c/src/lib/libbsp/powerpc/ChangeLog | 9 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/irq/irq_init.c | 38 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/openpic/openpic.c | 54 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/openpic/openpic.h | 31 |
4 files changed, 84 insertions, 48 deletions
diff --git a/c/src/lib/libbsp/powerpc/ChangeLog b/c/src/lib/libbsp/powerpc/ChangeLog index ac723d234f..0398ef54a2 100644 --- a/c/src/lib/libbsp/powerpc/ChangeLog +++ b/c/src/lib/libbsp/powerpc/ChangeLog @@ -1,4 +1,13 @@ 2007-12-02 Till Straumann <strauman@slac.stanford.edu> + + * shared/openpic/openpic.c shared/openpic/openpic.h, + shared/irq/irq_init.c: added more parameters to + openpic_init() so that more details of the configuration + can be overridden/set from the BSP. Moved setup of + the EPIC-specific EOI delay from BSP code into openpic_init() + using the new 'epic_freq' parameter. + +2007-12-02 Till Straumann <strauman@slac.stanford.edu> * shared/openpic/openpic.c, shared/openpic/openpic.h: - eliminated conditional compilation (#ifdef mpc8240) The difference in register-layout between the EPIC 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 4ba7d6bf2f..47ac343740 100644 --- a/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c +++ b/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c @@ -270,45 +270,15 @@ void BSP_rtems_irq_mng_init(unsigned cpuId) #ifdef TRACE_IRQ_INIT 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' + /* EPIC sources don't start at the regular place; define appropriate offset + * prior to initializing the PIC. */ - { - 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 ); - } - } + openpic_init(1, mvme2100_openpic_initpolarities, mvme2100_openpic_initsenses, 16, 16, BSP_bus_frequency); #else #ifdef TRACE_IRQ_INIT printk("Going to initialize raven interrupt controller (openpic compliant)\n"); #endif - openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses); + openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses, 0, 0, 0); #ifdef TRACE_IRQ_INIT printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n"); #endif diff --git a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c index f752055cd7..46fc86d967 100644 --- a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c +++ b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c @@ -167,7 +167,7 @@ static void openpic_safe_writefield(volatile unsigned int *addr, unsigned int ma * IRQ0 is no longer treated specially. */ -void openpic_init(int main_pic, unsigned char *polarities, unsigned char *senses) +void openpic_init(int main_pic, unsigned char *polarities, unsigned char *senses, int num_sources, int source_offset, unsigned long epic_freq) { unsigned int t, i; unsigned int vendorid, devid, stepping, timerfreq; @@ -237,6 +237,16 @@ void openpic_init(int main_pic, unsigned char *polarities, unsigned char *senses printk("OpenPIC Vendor %d (%s), Device %d (%s), Stepping %d\n", vendorid, vendor, devid, device, stepping); + /* Override if they desire */ + if ( num_sources ) { + if ( NumSources != num_sources ) + printk("Overriding NumSources (%i) from configuration with %i\n", + NumSources, num_sources); + NumSources = num_sources; + } + + openpic_src_offst = source_offset; + timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); printk("OpenPIC timer frequency is "); if (timerfreq) @@ -280,6 +290,41 @@ void openpic_init(int main_pic, unsigned char *polarities, unsigned char *senses openpic_set_priority(0, 0); openpic_disable_8259_pass_through(); } + if ( epic_freq ) { + /* 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 EPIC-specific piece in 'openpic.c' + * Unfortunately, there is no easy way of figuring out if the + * device is an EPIC or not. + */ + 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 = epic_freq / 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 ); + } + } } /* @@ -341,13 +386,6 @@ unsigned rval = openpic_eoi_delay; return rval; } -int openpic_set_src_offst(int offset) -{ -int rval = openpic_src_offst; - openpic_src_offst = offset; - return rval; -} - /* * 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 b69a37687b..477d7b3699 100644 --- a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h +++ b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h @@ -315,18 +315,37 @@ extern volatile struct OpenPIC *OpenPIC; * openpic_set_sense() * openpic_get_source_priority() * openpic_set_source_priority() + * the desired source offset parameter is passed to openpic_init(). * - * The routines 'openpic_set_eoi_delay()' and 'openpic_set_src_offst()' - * return the respective previous values of the affected parameters. - * - * NOTE: openpic_set_src_offst() MUST be called PRIOR to openpic_init() + * The routine 'openpic_set_eoi_delay()' returns the previous/old + * value of the delay parameter. */ extern unsigned openpic_set_eoi_delay(unsigned tb_cycles); -extern int openpic_set_src_offst(int offset); /* Global Operations */ -extern void openpic_init(int,unsigned char *, unsigned char *); + +/* num_sources: number of sources to use; if zero this value + * is read from the device, if nonzero the value read from + * the device is overridden. + * 'polarities' and 'senses' are arrays defining the desired + * polarities (active hi [nonzero]/lo [zero]) and + * senses (level [nonzero]/edge [zero]). + * Either of the two array pointers may be NULL resulting + * in the driver choosing default values of: 'active low' + * and 'level sensitive', respectively. + * NOTE: if you do pass arrays then their size must either + * match the number of sources read from the device or + * that value must be overridden by specifying + * a non-zero 'num_sources' parameter. + * + * Nonzero 'epic_freq' activates the EOI delay if the EPIC is + * configured in serial mode (driver assumes firmware performs initial + * EPIC setup). The BSP must pass the clock frequency of the EPIC + * serial interface here. + */ +extern void openpic_init(int main_pic, unsigned char *polarities, unsigned char *senses, int num_sources, int source_offset, unsigned long epic_freq); + extern void openpic_reset(void); extern void openpic_enable_8259_pass_through(void); extern void openpic_disable_8259_pass_through(void); |