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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4f8772d4 was 63e27ef, checked in by Jiri Svoboda <jiri@…>, 8 years ago

ASSERT → assert

  • 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 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 /* This register controls the various parameters
53 * of the OCP interface.
54 */
55 ioport32_t sysconfig;
56#define OMAP_IRC_SYSCONFIG_AUTOIDLE_FLAG (1 << 0)
57#define OMAP_IRC_SYSCONFIG_SOFTRESET_FLAG (1 << 1)
58
59 /* This register provides status information about the module */
60 const ioport32_t sysstatus;
61#define OMAP_IRC_SYSSTATUS_RESET_DONE_FLAG (1 << 0)
62
63 const uint8_t padd1[40];
64
65 /* This register supplies the currently active IRQ interrupt number */
66 ioport32_t sir_irq;
67#define OMAP_IRC_SIR_IRQ_ACTIVEIRQ_MASK 0x7F
68#define OMAP_IRC_SIR_IRQ_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
69
70 /* This register supplies the currently active FIQ interrupt number */
71 const ioport32_t sir_fiq;
72#define OMAP_IRC_FIQ_IRQ_ACTIVEFIQ_MASK 0x7F
73#define OMAP_IRC_FIQ_IRQ_SPURIOUSFIQFLAG_MASK 0xFFFFFFF8
74
75 /* This register contains the new interrupt agreement bits */
76 ioport32_t control;
77#define OMAP_IRC_CONTROL_NEWIRQAGR_FLAG (1 << 0)
78#define OMAP_IRC_CONTROL_NEWFIQAGR_FLAG (1 << 1)
79
80 /* This register controls protection of the other registers.
81 * This register can only be accessed in priviledged mode, regardless
82 * of the current value of the protection bit.
83 */
84 ioport32_t protection;
85#define OMAP_IRC_PROTECTION_FLAG (1 << 0)
86
87 /* This register controls the clock auto-idle for the functional
88 * clock and the input synchronizers.
89 */
90 ioport32_t idle;
91#define OMAP_IRC_IDLE_FUNCIDLE_FLAG (1 << 0)
92#define OMAP_IRC_IDLE_TURBO_FLAG (1 << 1)
93
94 const uint8_t padd2[12];
95
96 /* This register supplies the currently active IRQ priority level */
97 const ioport32_t irq_priority;
98#define OMAP_IRC_IRQ_PRIORITY_IRQPRIORITY_MASK 0x7F
99#define OMAP_IRC_IRQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
100
101 /* This register supplies the currently active FIQ priority level */
102 const ioport32_t fiq_priority;
103#define OMAP_IRC_FIQ_PRIORITY_FIQPRIORITY_MASK 0x7F
104#define OMAP_IRC_FIQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
105
106 /* This register sets the priority threshold */
107 ioport32_t threshold;
108#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_MASK 0xFF
109#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_ENABLED 0x00
110#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_DISABLED 0xFF
111
112 const uint8_t padd3[20];
113
114 struct {
115 /* Raw interrupt input status before masking */
116 const ioport32_t itr;
117
118 /* Interrupt mask */
119 ioport32_t mir;
120
121 /* This register is used to clear the interrupt mask bits,
122 * Write 1 clears the mask bit to 0.
123 */
124 ioport32_t mir_clear;
125
126 /* This register is used to set the interrupt mask bits,
127 * Write 1 sets the mask bit to 1.
128 */
129 ioport32_t mir_set;
130
131 /* This register is used to set the software interrupt bits,
132 * it is also used to read the current active software
133 * interrupts.
134 * Write 1 sets the software interrups bits to 1.
135 */
136 ioport32_t isr_set;
137
138 /* This register is used to clear the software interrups bits.
139 * Write 1 clears the software interrupt bits to 0.
140 */
141 ioport32_t isr_clear;
142
143 /* This register contains the IRQ status after masking. */
144 const ioport32_t pending_irq;
145
146 /* This register contains the FIQ status after masking. */
147 const ioport32_t pending_fiq;
148 } interrupts[OMAP_IRC_IRQ_GROUPS_COUNT];
149
150 const uint32_t padd4[8 * OMAP_IRC_IRQ_GROUPS_PAD];
151
152 /* These registers contain the priority for the interrups and
153 * the FIQ/IRQ steering.
154 */
155 ioport32_t ilr[OMAP_IRC_IRQ_COUNT];
156/* 0 = Interrupt routed to IRQ, 1 = interrupt routed to FIQ */
157#define OMAP_IRC_ILR_FIQNIRQ_FLAG (1 << 0)
158#define OMAP_IRC_ILR_PRIORITY_MASK 0x3F
159#define OMAP_IRC_ILR_PRIORITY_SHIFT 2
160
161} omap_irc_regs_t;
162
163static inline void omap_irc_init(omap_irc_regs_t *regs)
164{
165 int i;
166
167 /* Initialization sequence */
168
169 /* 1 - Program the SYSCONFIG register: if necessary, enable the
170 * autogating by setting the AUTOIDLE bit.
171 */
172 regs->sysconfig &= ~OMAP_IRC_SYSCONFIG_AUTOIDLE_FLAG;
173
174 /* 2 - Program the IDLE register: if necessary, disable functional
175 * clock autogating or enable synchronizer autogating by setting
176 * the FUNCIDLE bit or the TURBO bit accordingly.
177 */
178 regs->idle &= ~OMAP_IRC_IDLE_FUNCIDLE_FLAG;
179 regs->idle &= ~OMAP_IRC_IDLE_TURBO_FLAG;
180
181 /* 3 - Program ILRm register for each interrupt line: Assign a
182 * priority level and set the FIQNIRQ bit for an FIQ interrupt
183 * (by default, interrupts are mapped to IRQ and
184 * priority is 0 (highest).
185 */
186
187 for (i = 0; i < OMAP_IRC_IRQ_COUNT; ++i)
188 regs->ilr[i] = 0;
189
190 /* 4 - Program the MIRn register: Enable interrupts (by default,
191 * all interrupt lines are masked).
192 */
193 for (i = 0; i < OMAP_IRC_IRQ_GROUPS_COUNT; ++i)
194 regs->interrupts[i].mir_set = 0xFFFFFFFF;
195}
196
197/** Get the currently active IRQ interrupt number
198 *
199 * @param regs Pointer to the irc memory mapped registers
200 *
201 * @return The active IRQ interrupt number
202 */
203static inline unsigned omap_irc_inum_get(omap_irc_regs_t *regs)
204{
205 return regs->sir_irq & OMAP_IRC_SIR_IRQ_ACTIVEIRQ_MASK;
206}
207
208/** Reset IRQ output and enable new IRQ generation
209 *
210 * @param regs Pointer to the irc memory mapped registers
211 */
212static inline void omap_irc_irq_ack(omap_irc_regs_t *regs)
213{
214 regs->control = OMAP_IRC_CONTROL_NEWIRQAGR_FLAG;
215}
216
217/** Reset FIQ output and enable new FIQ generation
218 *
219 * @param regs Pointer to the irc memory mapped registers
220 */
221static inline void omap_irc_fiq_ack(omap_irc_regs_t *regs)
222{
223 regs->control = OMAP_IRC_CONTROL_NEWFIQAGR_FLAG;
224}
225
226/** Clear an interrupt mask bit
227 *
228 * @param regs Pointer to the irc memory mapped registers
229 * @param inum The interrupt to be enabled
230 */
231static inline void omap_irc_enable(omap_irc_regs_t *regs, unsigned inum)
232{
233 assert(inum < OMAP_IRC_IRQ_COUNT);
234 const unsigned set = inum / 32;
235 const unsigned pos = inum % 32;
236 regs->interrupts[set].mir_clear = (1 << pos);
237}
238
239/** Set an interrupt mask bit
240 *
241 * @param regs Pointer to the irc memory mapped registers
242 * @param inum The interrupt to be disabled
243 */
244static inline void omap_irc_disable(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_set = (1 << pos);
250}
251
252static inline void omap_irc_dump(omap_irc_regs_t *regs)
253{
254#define DUMP_REG(name) \
255 printf("%s %p(%x).\n", #name, &regs->name, regs->name);
256
257 DUMP_REG(revision);
258 DUMP_REG(sysconfig);
259 DUMP_REG(sysstatus);
260 DUMP_REG(sir_irq);
261 DUMP_REG(sir_fiq);
262 DUMP_REG(control);
263 DUMP_REG(protection);
264 DUMP_REG(idle);
265 DUMP_REG(irq_priority);
266 DUMP_REG(fiq_priority);
267 DUMP_REG(threshold);
268
269 for (int i = 0; i < OMAP_IRC_IRQ_GROUPS_COUNT; ++i) {
270 DUMP_REG(interrupts[i].itr);
271 DUMP_REG(interrupts[i].mir);
272 DUMP_REG(interrupts[i].isr_set);
273 DUMP_REG(interrupts[i].pending_irq);
274 DUMP_REG(interrupts[i].pending_fiq);
275 }
276 for (int i = 0; i < OMAP_IRC_IRQ_COUNT; ++i) {
277 DUMP_REG(ilr[i]);
278 }
279
280#undef DUMP_REG
281}
282
283#endif
284
285/**
286 * @}
287 */
Note: See TracBrowser for help on using the repository browser.