Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:48

0001 /**
0002  * @file
0003  *
0004  * @ingroup RTEMSImplClassicIntr
0005  * @ingroup arm_beagle
0006  *
0007  * @brief Interrupt support.
0008  */
0009 
0010 /*
0011  * Copyright (c) 2014 Ben Gras <beng@shrike-systems.com>. All rights reserved.
0012  *
0013  * The license and distribution terms for this file may be
0014  * found in the file LICENSE in this distribution or at
0015  * http://www.rtems.org/license/LICENSE.
0016  */
0017 
0018 #include <bsp.h>
0019 #include <bsp/irq-generic.h>
0020 #include <bsp/linker-symbols.h>
0021 #include <bsp/fatal.h>
0022 
0023 #include <rtems/score/armv4.h>
0024 
0025 #include <libcpu/arm-cp15.h>
0026 
0027 struct omap_intr
0028 {
0029   uint32_t base;
0030   int size;
0031 };
0032 
0033 #if IS_DM3730
0034 static struct omap_intr omap_intr = {
0035   .base = OMAP3_DM37XX_INTR_BASE,
0036   .size = 0x1000,
0037 };
0038 #endif
0039 
0040 #if IS_AM335X
0041 static struct omap_intr omap_intr = {
0042   .base = OMAP3_AM335X_INTR_BASE,
0043   .size = 0x1000,
0044 };
0045 #endif
0046 
0047 /* Enables interrupts at the Interrupt Controller side. */
0048 static inline void omap_irq_ack(void)
0049 {
0050   mmio_write(omap_intr.base + OMAP3_INTCPS_CONTROL, OMAP3_INTR_NEWIRQAGR);
0051 
0052   /* Flush data cache to make sure all the previous writes are done
0053      before re-enabling interrupts. */
0054   flush_data_cache();
0055 }
0056 
0057 void bsp_interrupt_dispatch(void)
0058 {
0059   const uint32_t reg = mmio_read(omap_intr.base + OMAP3_INTCPS_SIR_IRQ);
0060 
0061   if ((reg & OMAP3_INTR_SPURIOUSIRQ_MASK) != OMAP3_INTR_SPURIOUSIRQ_MASK) {
0062     const rtems_vector_number irq = reg & OMAP3_INTR_ACTIVEIRQ_MASK;
0063 
0064     bsp_interrupt_handler_dispatch(irq);
0065   } else {
0066     /* Ignore spurious interrupts. We'll still ACK it so new interrupts
0067        can be generated. */
0068   }
0069 
0070   omap_irq_ack();
0071 }
0072 
0073 /* There are 4 32-bit interrupt mask registers for a total of 128 interrupts.
0074    The IRQ number tells us which register to use. */
0075 static uint32_t omap_get_mir_reg(rtems_vector_number vector, uint32_t *const mask)
0076 {
0077   uint32_t mir_reg;
0078 
0079   /* Select which bit to set/clear in the MIR register. */
0080   *mask = 1ul << (vector % 32u);
0081 
0082   if (vector < 32u) {
0083     mir_reg = OMAP3_INTCPS_MIR0;
0084   } else if (vector < 64u) {
0085     mir_reg = OMAP3_INTCPS_MIR1;
0086   } else if (vector < 96u) {
0087     mir_reg = OMAP3_INTCPS_MIR2;
0088   } else if (vector < 128u) {
0089     mir_reg = OMAP3_INTCPS_MIR3;
0090   } else {
0091     /* Invalid IRQ number. This should never happen. */
0092     bsp_fatal(0);
0093   }
0094 
0095   return mir_reg;
0096 }
0097 
0098 rtems_status_code bsp_interrupt_get_attributes(
0099   rtems_vector_number         vector,
0100   rtems_interrupt_attributes *attributes
0101 )
0102 {
0103   return RTEMS_SUCCESSFUL;
0104 }
0105 
0106 rtems_status_code bsp_interrupt_is_pending(
0107   rtems_vector_number vector,
0108   bool               *pending
0109 )
0110 {
0111   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0112   bsp_interrupt_assert(pending != NULL);
0113   *pending = false;
0114   return RTEMS_UNSATISFIED;
0115 }
0116 
0117 rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
0118 {
0119   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0120   return RTEMS_UNSATISFIED;
0121 }
0122 
0123 rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
0124 {
0125   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0126   return RTEMS_UNSATISFIED;
0127 }
0128 
0129 rtems_status_code bsp_interrupt_vector_is_enabled(
0130   rtems_vector_number vector,
0131   bool               *enabled
0132 )
0133 {
0134   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0135   bsp_interrupt_assert(enabled != NULL);
0136   *enabled = false;
0137   return RTEMS_UNSATISFIED;
0138 }
0139 
0140 rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
0141 {
0142   uint32_t mask, cur;
0143   uint32_t mir_reg = omap_get_mir_reg(vector, &mask);
0144 
0145   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0146 
0147   cur = mmio_read(omap_intr.base + mir_reg);
0148   mmio_write(omap_intr.base + mir_reg, cur & ~mask);
0149   flush_data_cache();
0150   return RTEMS_SUCCESSFUL;
0151 }
0152 
0153 rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
0154 {
0155   uint32_t mask, cur;
0156   uint32_t mir_reg = omap_get_mir_reg(vector, &mask);
0157 
0158   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0159 
0160   cur = mmio_read(omap_intr.base + mir_reg);
0161   mmio_write(omap_intr.base + mir_reg, cur | mask);
0162   flush_data_cache();
0163   return RTEMS_SUCCESSFUL;
0164 }
0165 
0166 rtems_status_code bsp_interrupt_set_priority(
0167   rtems_vector_number vector,
0168   uint32_t priority
0169 )
0170 {
0171   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0172   return RTEMS_UNSATISFIED;
0173 }
0174 
0175 rtems_status_code bsp_interrupt_get_priority(
0176   rtems_vector_number vector,
0177   uint32_t *priority
0178 )
0179 {
0180   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0181   bsp_interrupt_assert(priority != NULL);
0182   return RTEMS_UNSATISFIED;
0183 }
0184 
0185 void bsp_interrupt_facility_initialize(void)
0186 {
0187   int i;
0188   uint32_t intc_ilrx;
0189 
0190   /* AM335X TRM 6.2.1 Initialization Sequence */
0191   mmio_write(omap_intr.base + OMAP3_INTCPS_SYSCONFIG, OMAP3_SYSCONFIG_AUTOIDLE);
0192   mmio_write(omap_intr.base + OMAP3_INTCPS_IDLE, 0);
0193   /* priority 0 to all IRQs */
0194   for(intc_ilrx = 0x100; intc_ilrx <= 0x2fc; intc_ilrx += 4) {
0195     mmio_write(omap_intr.base + intc_ilrx, 0);
0196   }
0197 
0198   /* Mask all interrupts */
0199   for(i = 0; i < BSP_INTERRUPT_VECTOR_COUNT; i++)
0200     bsp_interrupt_vector_disable(i);
0201 
0202   /* Install generic interrupt handler */
0203   arm_cp15_set_exception_handler(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt);
0204   arm_cp15_set_vector_base_address(bsp_vector_table_begin);
0205 }