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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6404aca was 6404aca, checked in by Jakub Jermar <jakub@…>, 7 years ago

Disambiguate doxygroup genarch*

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