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

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

arm32: make the irc registers structure generic enough to be used by both am335x and amdm37x

  • Property mode set to 100644
File size: 8.5 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 <typedefs.h>
42
43#define OMAP_IRC_IRQ_GROUPS_PAD (4 - OMAP_IRC_IRQ_GROUPS_COUNT)
44
45typedef struct {
46 const ioport32_t revision;
47#define OMAP_IRC_REV_MASK 0xFF
48
49 const uint8_t padd0[12];
50
51 /* This register controls the various parameters
52 * of the OCP interface.
53 */
54 ioport32_t sysconfig;
55#define OMAP_IRC_SYSCONFIG_AUTOIDLE_FLAG (1 << 0)
56#define OMAP_IRC_SYSCONFIG_SOFTRESET_FLAG (1 << 1)
57
58 /* This register provides status information about the module */
59 const ioport32_t sysstatus;
60#define OMAP_IRC_SYSSTATUS_RESET_DONE_FLAG (1 << 0)
61
62 const uint8_t padd1[40];
63
64 /* This register supplies the currently active IRQ interrupt number */
65 ioport32_t sir_irq;
66#define OMAP_IRC_SIR_IRQ_ACTIVEIRQ_MASK 0x7F
67#define OMAP_IRC_SIR_IRQ_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
68
69 /* This register supplies the currently active FIQ interrupt number */
70 const ioport32_t sir_fiq;
71#define OMAP_IRC_FIQ_IRQ_ACTIVEFIQ_MASK 0x7F
72#define OMAP_IRC_FIQ_IRQ_SPURIOUSFIQFLAG_MASK 0xFFFFFFF8
73
74 /* This register contains the new interrupt agreement bits */
75 ioport32_t control;
76#define OMAP_IRC_CONTROL_NEWIRQAGR_FLAG (1 << 0)
77#define OMAP_IRC_CONTROL_NEWFIQAGR_FLAG (1 << 1)
78
79 /* This register controls protection of the other registers.
80 * This register can only be accessed in priviledged mode, regardless
81 * of the current value of the protection bit.
82 */
83 ioport32_t protection;
84#define OMAP_IRC_PROTECTION_FLAG (1 << 0)
85
86 /* This register controls the clock auto-idle for the functional
87 * clock and the input synchronizers.
88 */
89 ioport32_t idle;
90#define OMAP_IRC_IDLE_FUNCIDLE_FLAG (1 << 0)
91#define OMAP_IRC_IDLE_TURBO_FLAG (1 << 1)
92
93 const uint8_t padd2[12];
94
95 /* This register supplies the currently active IRQ priority level */
96 const ioport32_t irq_priority;
97#define OMAP_IRC_IRQ_PRIORITY_IRQPRIORITY_MASK 0x7F
98#define OMAP_IRC_IRQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
99
100 /* This register supplies the currently active FIQ priority level */
101 const ioport32_t fiq_priority;
102#define OMAP_IRC_FIQ_PRIORITY_FIQPRIORITY_MASK 0x7F
103#define OMAP_IRC_FIQ_PRIORITY_SPURIOUSIRQFLAG_MASK 0xFFFFFFF8
104
105 /* This register sets the priority threshold */
106 ioport32_t threshold;
107#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_MASK 0xFF
108#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_ENABLED 0x00
109#define OMAP_IRC_THRESHOLD_PRIORITYTHRESHOLD_DISABLED 0xFF
110
111 const uint8_t padd3[20];
112
113 struct {
114 /* Raw interrupt input status before masking */
115 const ioport32_t itr;
116
117 /* Interrupt mask */
118 ioport32_t mir;
119
120 /* This register is used to clear the interrupt mask bits,
121 * Write 1 clears the mask bit to 0.
122 */
123 ioport32_t mir_clear;
124
125 /* This register is used to set the interrupt mask bits,
126 * Write 1 sets the mask bit to 1.
127 */
128 ioport32_t mir_set;
129
130 /* This register is used to set the software interrupt bits,
131 * it is also used to read the current active software
132 * interrupts.
133 * Write 1 sets the software interrups bits to 1.
134 */
135 ioport32_t isr_set;
136
137 /* This register is used to clear the software interrups bits.
138 * Write 1 clears the software interrupt bits to 0.
139 */
140 ioport32_t isr_clear;
141
142 /* This register contains the IRQ status after masking. */
143 const ioport32_t pending_irq;
144
145 /* This register contains the FIQ status after masking. */
146 const ioport32_t pending_fiq;
147 } interrupts[OMAP_IRC_IRQ_GROUPS_COUNT];
148
149 const uint32_t padd4[32 * OMAP_IRC_IRQ_GROUPS_PAD];
150
151 /* These registers contain the priority for the interrups and
152 * the FIQ/IRQ steering.
153 */
154 ioport32_t ilr[OMAP_IRC_IRQ_COUNT];
155/* 0 = Interrupt routed to IRQ, 1 = interrupt routed to FIQ */
156#define OMAP_IRC_ILR_FIQNIRQ_FLAG (1 << 0)
157#define OMAP_IRC_ILR_PRIORITY_MASK 0x3F
158#define OMAP_IRC_ILR_PRIORITY_SHIFT 2
159
160} omap_irc_regs_t;
161
162static inline void omap_irc_init(omap_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 &= ~OMAP_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 &= ~OMAP_IRC_IDLE_FUNCIDLE_FLAG;
178 regs->idle &= ~OMAP_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 < OMAP_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 < OMAP_IRC_IRQ_GROUPS_COUNT; ++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 */
202static inline unsigned omap_irc_inum_get(omap_irc_regs_t *regs)
203{
204 return regs->sir_irq & OMAP_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 */
211static inline void omap_irc_irq_ack(omap_irc_regs_t *regs)
212{
213 regs->control = OMAP_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 */
220static inline void omap_irc_fiq_ack(omap_irc_regs_t *regs)
221{
222 regs->control = OMAP_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 */
230static inline void omap_irc_enable(omap_irc_regs_t *regs, unsigned inum)
231{
232 ASSERT(inum < OMAP_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 */
243static inline void omap_irc_disable(omap_irc_regs_t *regs, unsigned inum)
244{
245 ASSERT(inum < OMAP_IRC_IRQ_COUNT);
246 const unsigned set = inum / 32;
247 const unsigned pos = inum % 32;
248 regs->interrupts[set].mir_set = (1 << pos);
249}
250
251static inline void omap_irc_dump(omap_irc_regs_t *regs)
252{
253#define DUMP_REG(name) \
254 printf("%s %p(%x).\n", #name, &regs->name, regs->name);
255
256 DUMP_REG(revision);
257 DUMP_REG(sysconfig);
258 DUMP_REG(sysstatus);
259 DUMP_REG(sir_irq);
260 DUMP_REG(sir_fiq);
261 DUMP_REG(control);
262 DUMP_REG(protection);
263 DUMP_REG(idle);
264 DUMP_REG(irq_priority);
265 DUMP_REG(fiq_priority);
266 DUMP_REG(threshold);
267
268 for (int i = 0; i < OMAP_IRC_IRQ_GROUPS_COUNT; ++i) {
269 DUMP_REG(interrupts[i].itr);
270 DUMP_REG(interrupts[i].mir);
271 DUMP_REG(interrupts[i].isr_set);
272 DUMP_REG(interrupts[i].pending_irq);
273 DUMP_REG(interrupts[i].pending_fiq);
274 }
275 for (int i = 0; i < OMAP_IRC_IRQ_COUNT; ++i) {
276 DUMP_REG(ilr[i]);
277 }
278
279#undef DUMP_REG
280}
281
282#endif
283
284/**
285 * @}
286 */
Note: See TracBrowser for help on using the repository browser.