Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 4cdcd2b in mainline


Ignore:
Timestamp:
2013-09-10T13:01:57Z (8 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master
Children:
e8d6ce2
Parents:
5b08d750 (diff), 3c9646b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

arm32: merge the unified interrupt controller implementation

Location:
kernel
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c

    r5b08d750 r4cdcd2b  
    6060
    6161static struct beagleboard {
    62         amdm37x_irc_regs_t *irc_addr;
     62        omap_irc_regs_t *irc_addr;
    6363        omap_uart_t uart;
    6464        amdm37x_gpt_t timer;
     
    103103            PAGE_NOT_CACHEABLE);
    104104        ASSERT(beagleboard.irc_addr);
    105         amdm37x_irc_init(beagleboard.irc_addr);
     105        omap_irc_init(beagleboard.irc_addr);
    106106
    107107        /* Initialize timer. Use timer1, because it is in WKUP power domain
     
    123123
    124124        /* Enable timer interrupt */
    125         amdm37x_irc_enable(beagleboard.irc_addr, AMDM37x_GPT1_IRQ);
     125        omap_irc_enable(beagleboard.irc_addr, AMDM37x_GPT1_IRQ);
    126126
    127127        /* Start timer here */
     
    147147static void bbxm_irq_exception(unsigned int exc_no, istate_t *istate)
    148148{
    149         const unsigned inum = amdm37x_irc_inum_get(beagleboard.irc_addr);
     149        const unsigned inum = omap_irc_inum_get(beagleboard.irc_addr);
    150150
    151151        irq_t *irq = irq_dispatch_and_lock(inum);
     
    161161        /** amdm37x manual ch. 12.5.2 (p. 2428) places irc ack at the end
    162162         * of ISR. DO this to avoid strange behavior. */
    163         amdm37x_irc_irq_ack(beagleboard.irc_addr);
     163        omap_irc_irq_ack(beagleboard.irc_addr);
    164164}
    165165
     
    188188                indev_t *srln = srln_wire(srln_instance, sink);
    189189                omap_uart_input_wire(&beagleboard.uart, srln);
    190                 amdm37x_irc_enable(beagleboard.irc_addr, AMDM37x_UART3_IRQ);
     190                omap_irc_enable(beagleboard.irc_addr, AMDM37x_UART3_IRQ);
    191191        }
    192192#endif
  • kernel/arch/arm32/src/mach/beaglebone/beaglebone.c

    r5b08d750 r4cdcd2b  
    6363
    6464static struct beaglebone {
    65         am335x_irc_regs_t *irc_addr;
     65        omap_irc_regs_t *irc_addr;
    6666        am335x_cm_per_regs_t *cm_per_addr;
    6767        am335x_cm_dpll_regs_t *cm_dpll_addr;
     
    104104
    105105        /* Initialize the interrupt controller */
    106         am335x_irc_init(bbone.irc_addr);
     106        omap_irc_init(bbone.irc_addr);
    107107}
    108108
     
    153153        }
    154154        /* Enable the interrupt */
    155         am335x_irc_enable(bbone.irc_addr, AM335x_DMTIMER2_IRQ);
     155        omap_irc_enable(bbone.irc_addr, AM335x_DMTIMER2_IRQ);
    156156        /* Start the timer */
    157157        am335x_timer_start(&bbone.timer);
     
    176176static void bbone_irq_exception(unsigned int exc_no, istate_t *istate)
    177177{
    178         const unsigned inum = am335x_irc_inum_get(bbone.irc_addr);
     178        const unsigned inum = omap_irc_inum_get(bbone.irc_addr);
    179179
    180180        irq_t *irq = irq_dispatch_and_lock(inum);
     
    187187        }
    188188
    189         am335x_irc_irq_ack(bbone.irc_addr);
     189        omap_irc_irq_ack(bbone.irc_addr);
    190190}
    191191
     
    214214                indev_t *srln = srln_wire(srln_instance, sink);
    215215                omap_uart_input_wire(&bbone.uart, srln);
    216                 am335x_irc_enable(bbone.irc_addr, AM335x_UART0_IRQ);
     216                omap_irc_enable(bbone.irc_addr, AM335x_UART0_IRQ);
    217217        }
    218218#endif
  • kernel/genarch/include/genarch/drivers/am335x/irc.h

    r5b08d750 r4cdcd2b  
    3838#define KERN_AM335x_IRQC_H_
    3939
    40 #define AM335x_IRC_BASE_ADDRESS 0x48200000
    41 #define AM335x_IRC_SIZE         4096
     40#define AM335x_IRC_BASE_ADDRESS     0x48200000
     41#define AM335x_IRC_SIZE             4096
    4242
    43 #define AM335x_IRC_IRQ_COUNT    128
     43#define AM335x_IRC_IRQ_COUNT        128
     44#define AM335x_IRC_IRQ_GROUPS_COUNT 4
    4445
    45 #include <typedefs.h>
     46#define OMAP_IRC_IRQ_COUNT        AM335x_IRC_IRQ_COUNT
     47#define OMAP_IRC_IRQ_GROUPS_COUNT AM335x_IRC_IRQ_GROUPS_COUNT
    4648
    47 typedef struct {
    48         const ioport32_t revision;
    49 #define AM335x_IRC_REV_MASK 0xFF
    50 
    51         const uint8_t padd0[12];
    52 
    53         /* This register controls the various parameters
    54          * of the OCP interface.
    55          */
    56         ioport32_t sysconfig;
    57 #define AM335x_IRC_SYSCONFIG_AUTOIDLE_FLAG   (1 << 0)
    58 #define AM335x_IRC_SYSCONFIG_SOFTRESET_FLAG  (1 << 1)
    59 
    60         /* This register provides status information about the module */
    61         const ioport32_t sysstatus;
    62 #define AM335x_IRC_SYSSTATUS_RESET_DONE_FLAG (1 << 0)
    63 
    64         const uint8_t padd1[40];
    65 
    66         /* This register supplies the currently active IRQ interrupt number */
    67         ioport32_t sir_irq;
    68 #define AM335x_IRC_SIR_IRQ_ACTIVEIRQ_MASK       0x7F
    69 #define AM335x_IRC_SIR_IRQ_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
    70 
    71         /* This register supplies the currently active FIQ interrupt number */
    72         const ioport32_t sir_fiq;
    73 #define AM335x_IRC_FIQ_IRQ_ACTIVEFIQ_MASK       0x7F
    74 #define AM335x_IRC_FIQ_IRQ_SPURIOUSFIQFLAG_MASK 0xFFFFFFF8
    75 
    76         /* This register contains the new interrupt agreement bits */
    77         ioport32_t control;
    78 #define AM335x_IRC_CONTROL_NEWIRQAGR_FLAG       (1 << 0)
    79 #define AM335x_IRC_CONTROL_NEWFIQAGR_FLAG       (1 << 1)
    80 
    81         /* This register controls protection of the other registers.
    82          * This register can only be accessed in priviledged mode, regardless
    83          * of the current value of the protection bit.
    84          */
    85         ioport32_t protection;
    86 #define AM335x_IRC_PROTECTION_FLAG              (1 << 0)
    87 
    88         /* This register controls the clock auto-idle for the functional
    89          * clock and the input synchronizers.
    90          */
    91         ioport32_t idle;
    92 #define AM335x_IRC_IDLE_FUNCIDLE_FLAG           (1 << 0)
    93 #define AM335x_IRC_IDLE_TURBO_FLAG              (1 << 1)
    94 
    95         const uint8_t padd2[12];
    96 
    97         /* This register supplies the currently active IRQ priority level */
    98         const ioport32_t irq_priority;
    99 #define AM335x_IRC_IRQ_PRIORITY_IRQPRIORITY_MASK     0x7F
    100 #define AM335x_IRC_IRQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
    101 
    102         /* This register supplies the currently active FIQ priority level */
    103         const ioport32_t fiq_priority;
    104 #define AM335x_IRC_FIQ_PRIORITY_FIQPRIORITY_MASK     0x7F
    105 #define AM335x_IRC_FIQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
    106 
    107         /* This register sets the priority threshold */
    108         ioport32_t threshold;
    109 #define AM335x_IRC_THRESHOLD_PRIORITYTHRESHOLD_MASK     0xFF
    110 #define AM335x_IRC_THRESHOLD_PRIORITYTHRESHOLD_ENABLED  0x00
    111 #define AM335x_IRC_THRESHOLD_PRIORITYTHRESHOLD_DISABLED 0xFF
    112 
    113         const uint8_t padd[20];
    114 
    115         struct {
    116                 /* Raw interrupt input status before masking */
    117                 const ioport32_t itr;
    118 
    119                 /* Interrupt mask */
    120                 ioport32_t mir;
    121 
    122                 /* This register is used to clear the interrupt mask bits,
    123                  * Write 1 clears the mask bit to 0.
    124                  */
    125                 ioport32_t mir_clear;
    126 
    127                 /* This register is used to set the interrupt mask bits,
    128                  * Write 1 sets the mask bit to 1.
    129                  */
    130                 ioport32_t mir_set;
    131 
    132                 /* This register is used to set the software interrupt bits,
    133                  * it is also used to read the current active software
    134                  * interrupts.
    135                  * Write 1 sets the software interrups bits to 1.
    136                  */
    137                 ioport32_t isr_set;
    138 
    139                 /* This register is used to clear the software interrups bits.
    140                  * Write 1 clears the software interrupt bits to 0.
    141                  */
    142                 ioport32_t isr_clear;
    143 
    144                 /* This register contains the IRQ status after masking. */
    145                 const ioport32_t pending_irq;
    146 
    147                 /* This register contains the FIQ status after masking. */
    148                 const ioport32_t pending_fiq;
    149         } interrupts[4];
    150 
    151         /* These registers contain the priority for the interrups and
    152          * the FIQ/IRQ steering.
    153          */
    154         ioport32_t ilr[AM335x_IRC_IRQ_COUNT];
    155 /* 0 = Interrupt routed to IRQ, 1 = interrupt routed to FIQ */
    156 #define AM335x_IRC_ILR_FIQNIRQ_FLAG    (1 << 0)
    157 #define AM335x_IRC_ILR_PRIORITY_MASK   0x3F
    158 #define AM335x_IRC_ILR_PRIORITY_SHIFT  2
    159 
    160 } am335x_irc_regs_t;
    161 
    162 static inline void am335x_irc_init(am335x_irc_regs_t *regs)
    163 {
    164         int i;
    165 
    166         /* Initialization sequence */
    167 
    168         /* 1 - Program the SYSCONFIG register: if necessary, enable the
    169          *     autogating by setting the AUTOIDLE bit.
    170          */
    171         regs->sysconfig &= ~AM335x_IRC_SYSCONFIG_AUTOIDLE_FLAG;
    172 
    173         /* 2 - Program the IDLE register: if necessary, disable functional
    174          *     clock autogating or enable synchronizer autogating by setting
    175          *     the FUNCIDLE bit or the TURBO bit accordingly.
    176          */
    177         regs->idle &= ~AM335x_IRC_IDLE_FUNCIDLE_FLAG;
    178         regs->idle &= ~AM335x_IRC_IDLE_TURBO_FLAG;
    179 
    180         /* 3 - Program ILRm register for each interrupt line: Assign a
    181          *     priority level and set the FIQNIRQ bit for an FIQ interrupt
    182          *     (by default, interrupts are mapped to IRQ and
    183          *     priority is 0 (highest).
    184          */
    185 
    186         for (i = 0; i < AM335x_IRC_IRQ_COUNT; ++i)
    187                 regs->ilr[i] = 0;
    188 
    189         /* 4 - Program the MIRn register: Enable interrupts (by default,
    190          *     all interrupt lines are masked).
    191          */
    192         for (i = 0; i < 4; ++i)
    193                 regs->interrupts[i].mir_set = 0xFFFFFFFF;
    194 }
    195 
    196 /** Get the currently active IRQ interrupt number
    197  *
    198  * @param regs     Pointer to the irc memory mapped registers
    199  *
    200  * @return         The active IRQ interrupt number
    201  */
    202 static inline unsigned am335x_irc_inum_get(am335x_irc_regs_t *regs)
    203 {
    204         return regs->sir_irq & AM335x_IRC_SIR_IRQ_ACTIVEIRQ_MASK;
    205 }
    206 
    207 /** Reset IRQ output and enable new IRQ generation
    208  *
    209  * @param regs    Pointer to the irc memory mapped registers
    210  */
    211 static inline void am335x_irc_irq_ack(am335x_irc_regs_t *regs)
    212 {
    213         regs->control = AM335x_IRC_CONTROL_NEWIRQAGR_FLAG;
    214 }
    215 
    216 /** Reset FIQ output and enable new FIQ generation
    217  *
    218  * @param regs    Pointer to the irc memory mapped registers
    219  */
    220 static inline void am335x_irc_fiq_ack(am335x_irc_regs_t *regs)
    221 {
    222         regs->control = AM335x_IRC_CONTROL_NEWFIQAGR_FLAG;
    223 }
    224 
    225 /** Clear an interrupt mask bit
    226  *
    227  * @param regs    Pointer to the irc memory mapped registers
    228  * @param inum    The interrupt to be enabled
    229  */
    230 static inline void am335x_irc_enable(am335x_irc_regs_t *regs, unsigned inum)
    231 {
    232         ASSERT(inum < AM335x_IRC_IRQ_COUNT);
    233         const unsigned set = inum / 32;
    234         const unsigned pos = inum % 32;
    235         regs->interrupts[set].mir_clear = (1 << pos);
    236 }
    237 
    238 /** Set an interrupt mask bit
    239  *
    240  * @param regs    Pointer to the irc memory mapped registers
    241  * @param inum    The interrupt to be disabled
    242  */
    243 static inline void am335x_irc_disable(am335x_irc_regs_t *regs, unsigned inum)
    244 {
    245         ASSERT(inum < AM335x_IRC_IRQ_COUNT);
    246         const unsigned set = inum / 32;
    247         const unsigned pos = inum % 32;
    248         regs->interrupts[set].mir_set = (1 << pos);
    249 }
     49#include <genarch/drivers/omap/irc.h>
    25050
    25151#endif
  • kernel/genarch/include/genarch/drivers/amdm37x/irc.h

    r5b08d750 r4cdcd2b  
    3838
    3939/* AMDM37x TRM p. 1079 */
    40 #define AMDM37x_IRC_BASE_ADDRESS 0x48200000
    41 #define AMDM37x_IRC_SIZE 4096
     40#define AMDM37x_IRC_BASE_ADDRESS     0x48200000
     41#define AMDM37x_IRC_SIZE             4096
    4242
    43 #define AMDM37x_IRC_IRQ_COUNT 96
     43#define AMDM37x_IRC_IRQ_COUNT        96
     44#define AMDM37x_IRC_IRQ_GROUPS_COUNT 3
    4445
    45 #include <typedefs.h>
     46#define OMAP_IRC_IRQ_COUNT        AMDM37x_IRC_IRQ_COUNT
     47#define OMAP_IRC_IRQ_GROUPS_COUNT AMDM37x_IRC_IRQ_GROUPS_COUNT
    4648
    47 typedef struct {
    48         const ioport32_t revision; /**< Revision */
    49 #define AMDM37x_IRC_REV_MASK (0xff)
    50 
    51         uint8_t padd0_[12];
    52 
    53         ioport32_t sysconfig; /**< SYS config */
    54 #define AMDM37x_IRC_SYSCONFIG_AUTOIDLE_FLAG (1 << 0)
    55 #define AMDM37x_IRC_SYSCONFIG_SOFTRESET_FLAG (1 << 1)
    56 
    57         const ioport32_t sysstatus; /**< SYS status */
    58 #define AMDM37x_IRC_SYSSTATUS_RESET_DONE_FLAG (1 << 0)
    59 
    60         uint8_t padd1_[40];
    61 
    62         const ioport32_t sir_irq;   /**< Currently active irq number */
    63 #define AMDM37x_IRC_SIR_IRQ_ACTIVEIRQ_MASK (0x7f)
    64 #define AMDM37x_IRC_SIR_IRQ_SPURIOUSIRQFLAG_MASK (0xfffffff8)
    65 
    66         const ioport32_t sir_fiq;
    67 #define AMDM37x_IRC_SIR_FIQ_ACTIVEIRQ_MASK (0x7f)
    68 #define AMDM37x_IRC_SIR_FIQ_SPURIOUSIRQFLAG_MASK (0xfffffff8)
    69 
    70         ioport32_t control;   /**< New interrupt agreement. */
    71 #define AMDM37x_IRC_CONTROL_NEWIRQAGR_FLAG (1 << 0)
    72 #define AMDM37x_IRC_CONTROL_NEWFIQAGR_FLAG (1 << 1)
    73 
    74         ioport32_t protection;  /**< Protect other registers. */
    75 #define AMDM37x_IRC_PROTECTION_PROETCTION_FLAG (1 << 0)
    76 
    77         ioport32_t idle;   /**< Idle and autogating */
    78 #define AMDM37x_IRC_IDLE_FUNCIDLE_FLAG (1 << 0)
    79 #define AMDM37x_IRC_IDLE_TURBO_FLAG (1 << 1)
    80 
    81         uint8_t padd2_[12];
    82 
    83         ioport32_t irq_priority; /**< Active IRQ priority */
    84 #define AMDM37x_IRC_IRQ_PRIORITY_IRQPRIORITY_MASK (0x7f)
    85 #define AMDM37x_IRC_IRQ_PRIORITY_SPURIOUSIRQFLAG_MASK (0xfffffff8)
    86 
    87         ioport32_t fiq_priority; /**< Active FIQ priority */
    88 #define AMDM37x_IRC_FIQ_PRIORITY_FIQPRIORITY_MASK (0x7f)
    89 #define AMDM37x_IRC_FIQ_PRIORITY_SPURIOUSFIQFLAG_MASK (0xfffffff8)
    90 
    91         ioport32_t threshold; /**< Priority threshold */
    92 #define AMDM37x_IRC_THRESHOLD_PRIORITYTHRESHOLD_MASK (0xff)
    93 #define AMDM37x_IRC_THRESHOLD_PRIORITYTHRESHOLD_ENABLED (0x00)
    94 #define AMDM37x_IRC_THRESHOLD_PRIORITYTHRESHOLD_DISABLED (0xff)
    95 
    96         uint8_t padd3__[20];
    97 
    98         struct {
    99                 const ioport32_t itr;   /**< Interrupt input status before masking */
    100                 ioport32_t mir;   /**< Interrupt mask */
    101                 ioport32_t mir_clear; /**< Clear mir mask bits */
    102                 ioport32_t mir_set;   /**< Set mir mask bits */
    103                 ioport32_t isr_set;   /**< Set software interrupt bits */
    104                 ioport32_t isr_clear; /**< Clear software interrupt bits */
    105                 const ioport32_t pending_irq; /**< IRQ status after masking */
    106                 const ioport32_t pending_fiq; /**< FIQ status after masking */
    107         } interrupts[3];
    108 
    109         uint8_t padd4_[32];
    110 
    111         ioport32_t ilr[96];   /**< FIQ/IRQ steering */
    112 #define AMDM37x_IRC_ILR_FIQNIRQ (1 << 0)
    113 #define AMDM37x_IRC_ILR_PRIORITY_MASK (0x3f)
    114 #define AMDM37x_IRC_ILR_PRIORITY_SHIFT (2)
    115 
    116 } amdm37x_irc_regs_t;
    117 
    118 static inline void amdm37x_irc_dump(amdm37x_irc_regs_t *regs)
    119 {
    120 #define DUMP_REG(name) \
    121         printf("%s %p(%x).\n", #name, &regs->name, regs->name);
    122 
    123         DUMP_REG(revision);
    124         DUMP_REG(sysconfig);
    125         DUMP_REG(sysstatus);
    126         DUMP_REG(sir_irq);
    127         DUMP_REG(sir_fiq);
    128         DUMP_REG(control);
    129         DUMP_REG(protection);
    130         DUMP_REG(idle);
    131         DUMP_REG(irq_priority);
    132         DUMP_REG(fiq_priority);
    133         DUMP_REG(threshold);
    134 
    135         for (int i = 0; i < 3; ++i) {
    136                 DUMP_REG(interrupts[i].itr);
    137                 DUMP_REG(interrupts[i].mir);
    138                 DUMP_REG(interrupts[i].isr_set);
    139                 DUMP_REG(interrupts[i].pending_irq);
    140                 DUMP_REG(interrupts[i].pending_fiq);
    141         }
    142         for (int i = 0; i < AMDM37x_IRC_IRQ_COUNT; ++i) {
    143                 DUMP_REG(ilr[i]);
    144         }
    145 
    146 #undef DUMP_REG
    147 }
    148 
    149 static inline void amdm37x_irc_init(amdm37x_irc_regs_t *regs)
    150 {
    151         /* AMDM37x TRM sec 12.5.1 p. 2425 */
    152         /* Program system config register */
    153         //TODO enable this when you know the meaning
    154         //regs->sysconfig |= AMDM37x_IRC_SYSCONFIG_AUTOIDLE_FLAG;
    155 
    156         /* Program idle register */
    157         //TODO enable this when you know the meaning
    158         //regs->sysconfig |= AMDM37x_IRC_IDLE_TURBO_FLAG;
    159 
    160         /* Program ilr[m] assign priority, decide fiq */
    161         for (unsigned i = 0; i < AMDM37x_IRC_IRQ_COUNT; ++i) {
    162                 regs->ilr[i] = 0; /* highest prio(default) route to irq */
    163         }
    164 
    165         /* Disable all interrupts */
    166         regs->interrupts[0].mir_set = 0xffffffff;
    167         regs->interrupts[1].mir_set = 0xffffffff;
    168         regs->interrupts[2].mir_set = 0xffffffff;
    169 }
    170 
    171 static inline unsigned amdm37x_irc_inum_get(amdm37x_irc_regs_t *regs)
    172 {
    173         return regs->sir_irq & AMDM37x_IRC_SIR_IRQ_ACTIVEIRQ_MASK;
    174 }
    175 
    176 static inline void amdm37x_irc_irq_ack(amdm37x_irc_regs_t *regs)
    177 {
    178         regs->control = AMDM37x_IRC_CONTROL_NEWIRQAGR_FLAG;
    179 }
    180 
    181 static inline void amdm37x_irc_fiq_ack(amdm37x_irc_regs_t *regs)
    182 {
    183         regs->control = AMDM37x_IRC_CONTROL_NEWFIQAGR_FLAG;
    184 }
    185 
    186 static inline void amdm37x_irc_enable(amdm37x_irc_regs_t *regs, unsigned inum)
    187 {
    188         ASSERT(inum < AMDM37x_IRC_IRQ_COUNT);
    189         const unsigned set = inum / 32;
    190         const unsigned pos = inum % 32;
    191         regs->interrupts[set].mir_clear = (1 << pos);
    192 }
    193 
    194 static inline void amdm37x_irc_disable(amdm37x_irc_regs_t *regs, unsigned inum)
    195 {
    196         ASSERT(inum < AMDM37x_IRC_IRQ_COUNT);
    197         const unsigned set = inum / 32;
    198         const unsigned pos = inum % 32;
    199         regs->interrupts[set].mir_set = (1 << pos);
    200 }
     49#include <genarch/drivers/omap/irc.h>
    20150
    20251#endif
Note: See TracChangeset for help on using the changeset viewer.