source: mainline/kernel/genarch/include/genarch/drivers/omap/irc.h@ c310f9b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c310f9b was c310f9b, checked in by Maurizio Lombardi <m.lombardi85@…>, 13 years ago

arm32: initial implementation of the unified interrupt controller driver for the OMAP platforms

  • Property mode set to 100644
File size: 7.7 KB
RevLine 
[c310f9b]1/*
2 * Copyright (c) 2012 Maurizio Lombardi
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28/** @addtogroup genarch
29 * @{
30 */
31
32/**
33 * @file
34 * @brief Texas Instruments OMAP on-chip interrupt controller driver.
35 */
36
37#ifndef KERN_OMAP_IRQC_H_
38#define KERN_OMAP_IRQC_H_
39
40#include <genarch/drivers/omap/irc_regs.h>
41#include <typedefs.h>
42
43typedef struct {
44 const ioport32_t revision;
45#define OMAP_IRC_REV_MASK 0xFF
46
47 const uint8_t padd0[12];
48
49 /* This register controls the various parameters
50 * of the OCP interface.
51 */
52 ioport32_t sysconfig;
53#define OMAP_IRC_SYSCONFIG_AUTOIDLE_FLAG (1 << 0)
54#define OMAP_IRC_SYSCONFIG_SOFTRESET_FLAG (1 << 1)
55
56 /* This register provides status information about the module */
57 const ioport32_t sysstatus;
58#define OMAP_IRC_SYSSTATUS_RESET_DONE_FLAG (1 << 0)
59
60 const uint8_t padd1[40];
61
62 /* This register supplies the currently active IRQ interrupt number */
63 ioport32_t sir_irq;
64#define OMAP_IRC_SIR_IRQ_ACTIVEIRQ_MASK 0x7F
65#define OMAP_IRC_SIR_IRQ_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
66
67 /* This register supplies the currently active FIQ interrupt number */
68 const ioport32_t sir_fiq;
69#define OMAP_IRC_FIQ_IRQ_ACTIVEFIQ_MASK 0x7F
70#define OMAP_IRC_FIQ_IRQ_SPURIOUSFIQFLAG_MASK 0xFFFFFFF8
71
72 /* This register contains the new interrupt agreement bits */
73 ioport32_t control;
74#define OMAP_IRC_CONTROL_NEWIRQAGR_FLAG (1 << 0)
75#define OMAP_IRC_CONTROL_NEWFIQAGR_FLAG (1 << 1)
76
77 /* This register controls protection of the other registers.
78 * This register can only be accessed in priviledged mode, regardless
79 * of the current value of the protection bit.
80 */
81 ioport32_t protection;
82#define OMAP_IRC_PROTECTION_FLAG (1 << 0)
83
84 /* This register controls the clock auto-idle for the functional
85 * clock and the input synchronizers.
86 */
87 ioport32_t idle;
88#define OMAP_IRC_IDLE_FUNCIDLE_FLAG (1 << 0)
89#define OMAP_IRC_IDLE_TURBO_FLAG (1 << 1)
90
91 const uint8_t padd2[12];
92
93 /* This register supplies the currently active IRQ priority level */
94 const ioport32_t irq_priority;
95#define OMAP_IRC_IRQ_PRIORITY_IRQPRIORITY_MASK 0x7F
96#define OMAP_IRC_IRQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
97
98 /* This register supplies the currently active FIQ priority level */
99 const ioport32_t fiq_priority;
100#define OMAP_IRC_FIQ_PRIORITY_FIQPRIORITY_MASK 0x7F
101#define OMAP_IRC_FIQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
102
103 /* This register sets the priority threshold */
104 ioport32_t threshold;
105#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_MASK 0xFF
106#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_ENABLED 0x00
107#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_DISABLED 0xFF
108
109 const uint8_t padd[20];
110
111 struct {
112 /* Raw interrupt input status before masking */
113 const ioport32_t itr;
114
115 /* Interrupt mask */
116 ioport32_t mir;
117
118 /* This register is used to clear the interrupt mask bits,
119 * Write 1 clears the mask bit to 0.
120 */
121 ioport32_t mir_clear;
122
123 /* This register is used to set the interrupt mask bits,
124 * Write 1 sets the mask bit to 1.
125 */
126 ioport32_t mir_set;
127
128 /* This register is used to set the software interrupt bits,
129 * it is also used to read the current active software
130 * interrupts.
131 * Write 1 sets the software interrups bits to 1.
132 */
133 ioport32_t isr_set;
134
135 /* This register is used to clear the software interrups bits.
136 * Write 1 clears the software interrupt bits to 0.
137 */
138 ioport32_t isr_clear;
139
140 /* This register contains the IRQ status after masking. */
141 const ioport32_t pending_irq;
142
143 /* This register contains the FIQ status after masking. */
144 const ioport32_t pending_fiq;
145 } interrupts[4];
146
147 /* These registers contain the priority for the interrups and
148 * the FIQ/IRQ steering.
149 */
150 ioport32_t ilr[OMAP_IRC_IRQ_COUNT];
151/* 0 = Interrupt routed to IRQ, 1 = interrupt routed to FIQ */
152#define OMAP_IRC_ILR_FIQNIRQ_FLAG (1 << 0)
153#define OMAP_IRC_ILR_PRIORITY_MASK 0x3F
154#define OMAP_IRC_ILR_PRIORITY_SHIFT 2
155
156} omap_irc_regs_t;
157
158static inline void omap_irc_init(am335x_irc_regs_t *regs)
159{
160 int i;
161
162 /* Initialization sequence */
163
164 /* 1 - Program the SYSCONFIG register: if necessary, enable the
165 * autogating by setting the AUTOIDLE bit.
166 */
167 regs->sysconfig &= ~OMAP_IRC_SYSCONFIG_AUTOIDLE_FLAG;
168
169 /* 2 - Program the IDLE register: if necessary, disable functional
170 * clock autogating or enable synchronizer autogating by setting
171 * the FUNCIDLE bit or the TURBO bit accordingly.
172 */
173 regs->idle &= ~OMAP_IRC_IDLE_FUNCIDLE_FLAG;
174 regs->idle &= ~OMAP_IRC_IDLE_TURBO_FLAG;
175
176 /* 3 - Program ILRm register for each interrupt line: Assign a
177 * priority level and set the FIQNIRQ bit for an FIQ interrupt
178 * (by default, interrupts are mapped to IRQ and
179 * priority is 0 (highest).
180 */
181
182 for (i = 0; i < OMAP_IRC_IRQ_COUNT; ++i)
183 regs->ilr[i] = 0;
184
185 /* 4 - Program the MIRn register: Enable interrupts (by default,
186 * all interrupt lines are masked).
187 */
188 for (i = 0; i < 4; ++i)
189 regs->interrupts[i].mir_set = 0xFFFFFFFF;
190}
191
192/** Get the currently active IRQ interrupt number
193 *
194 * @param regs Pointer to the irc memory mapped registers
195 *
196 * @return The active IRQ interrupt number
197 */
198static inline unsigned omap_irc_inum_get(am335x_irc_regs_t *regs)
199{
200 return regs->sir_irq & OMAP_IRC_SIR_IRQ_ACTIVEIRQ_MASK;
201}
202
203/** Reset IRQ output and enable new IRQ generation
204 *
205 * @param regs Pointer to the irc memory mapped registers
206 */
207static inline void omap_irc_irq_ack(am335x_irc_regs_t *regs)
208{
209 regs->control = OMAP_IRC_CONTROL_NEWIRQAGR_FLAG;
210}
211
212/** Reset FIQ output and enable new FIQ generation
213 *
214 * @param regs Pointer to the irc memory mapped registers
215 */
216static inline void omap_irc_fiq_ack(am335x_irc_regs_t *regs)
217{
218 regs->control = OMAP_IRC_CONTROL_NEWFIQAGR_FLAG;
219}
220
221/** Clear an interrupt mask bit
222 *
223 * @param regs Pointer to the irc memory mapped registers
224 * @param inum The interrupt to be enabled
225 */
226static inline void omap_irc_enable(am335x_irc_regs_t *regs, unsigned inum)
227{
228 ASSERT(inum < OMAP_IRC_IRQ_COUNT);
229 const unsigned set = inum / 32;
230 const unsigned pos = inum % 32;
231 regs->interrupts[set].mir_clear = (1 << pos);
232}
233
234/** Set an interrupt mask bit
235 *
236 * @param regs Pointer to the irc memory mapped registers
237 * @param inum The interrupt to be disabled
238 */
239static inline void omap_irc_disable(am335x_irc_regs_t *regs, unsigned inum)
240{
241 ASSERT(inum < OMAP_IRC_IRQ_COUNT);
242 const unsigned set = inum / 32;
243 const unsigned pos = inum % 32;
244 regs->interrupts[set].mir_set = (1 << pos);
245}
246
247#endif
248
249/**
250 * @}
251 */
Note: See TracBrowser for help on using the repository browser.