]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - arch/arm/plat-omap/include/mach/entry-macro.S
ARM: OMAP4: SMP: Add mpu timer support for OMAP4430
[linux-2.6.git] / arch / arm / plat-omap / include / mach / entry-macro.S
1 /*
2  * arch/arm/plat-omap/include/mach/entry-macro.S
3  *
4  * Low-level IRQ helper macros for OMAP-based platforms
5  *
6  * Copyright (C) 2009 Texas Instruments
7  * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
8  *
9  * This file is licensed under  the terms of the GNU General Public
10  * License version 2. This program is licensed "as is" without any
11  * warranty of any kind, whether express or implied.
12  */
13 #include <mach/hardware.h>
14 #include <mach/io.h>
15 #include <mach/irqs.h>
16 #include <asm/hardware/gic.h>
17
18 #if defined(CONFIG_ARCH_OMAP1)
19
20 #if defined(CONFIG_ARCH_OMAP730) && \
21         (defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX))
22 #error "FIXME: OMAP730 doesn't support multiple-OMAP"
23 #elif defined(CONFIG_ARCH_OMAP730)
24 #define INT_IH2_IRQ             INT_730_IH2_IRQ
25 #elif defined(CONFIG_ARCH_OMAP15XX)
26 #define INT_IH2_IRQ             INT_1510_IH2_IRQ
27 #elif defined(CONFIG_ARCH_OMAP16XX)
28 #define INT_IH2_IRQ             INT_1610_IH2_IRQ
29 #else
30 #warning "IH2 IRQ defaulted"
31 #define INT_IH2_IRQ             INT_1510_IH2_IRQ
32 #endif
33
34                 .macro  disable_fiq
35                 .endm
36
37                 .macro  get_irqnr_preamble, base, tmp
38                 .endm
39
40                 .macro  arch_ret_to_user, tmp1, tmp2
41                 .endm
42
43                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
44                 ldr     \base, =IO_ADDRESS(OMAP_IH1_BASE)
45                 ldr     \irqnr, [\base, #IRQ_ITR_REG_OFFSET]
46                 ldr     \tmp, [\base, #IRQ_MIR_REG_OFFSET]
47                 mov     \irqstat, #0xffffffff
48                 bic     \tmp, \irqstat, \tmp
49                 tst     \irqnr, \tmp
50                 beq     1510f
51
52                 ldr     \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
53                 cmp     \irqnr, #0
54                 ldreq   \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
55                 cmpeq   \irqnr, #INT_IH2_IRQ
56                 ldreq   \base, =IO_ADDRESS(OMAP_IH2_BASE)
57                 ldreq   \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
58                 addeqs  \irqnr, \irqnr, #32
59 1510:
60                 .endm
61
62 #endif
63 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
64                         defined(CONFIG_ARCH_OMAP4)
65
66 #include <mach/omap24xx.h>
67 #include <mach/omap34xx.h>
68
69 /* REVISIT: This should be set dynamically if CONFIG_MULTI_OMAP2 is selected */
70 #if defined(CONFIG_ARCH_OMAP2420) || defined(CONFIG_ARCH_OMAP2430)
71 #define OMAP2_VA_IC_BASE                IO_ADDRESS(OMAP24XX_IC_BASE)
72 #elif defined(CONFIG_ARCH_OMAP34XX)
73 #define OMAP2_VA_IC_BASE                IO_ADDRESS(OMAP34XX_IC_BASE)
74 #endif
75 #if defined(CONFIG_ARCH_OMAP4)
76 #include <mach/omap44xx.h>
77 #endif
78 #define INTCPS_SIR_IRQ_OFFSET   0x0040          /* Active interrupt offset */
79 #define ACTIVEIRQ_MASK          0x7f            /* Active interrupt bits */
80
81                 .macro  disable_fiq
82                 .endm
83
84                 .macro  get_irqnr_preamble, base, tmp
85                 .endm
86
87                 .macro  arch_ret_to_user, tmp1, tmp2
88                 .endm
89
90 #ifndef CONFIG_ARCH_OMAP4
91                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
92                 ldr     \base, =OMAP2_VA_IC_BASE
93                 ldr     \irqnr, [\base, #0x98] /* IRQ pending reg 1 */
94                 cmp     \irqnr, #0x0
95                 bne     2222f
96                 ldr     \irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
97                 cmp     \irqnr, #0x0
98                 bne     2222f
99                 ldr     \irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
100                 cmp     \irqnr, #0x0
101 2222:
102                 ldrne   \irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
103                 and     \irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
104
105                 .endm
106 #else
107                 /*
108                  * The interrupt numbering scheme is defined in the
109                  * interrupt controller spec.  To wit:
110                  *
111                  * Interrupts 0-15 are IPI
112                  * 16-28 are reserved
113                  * 29-31 are local.  We allow 30 to be used for the watchdog.
114                  * 32-1020 are global
115                  * 1021-1022 are reserved
116                  * 1023 is "spurious" (no interrupt)
117                  *
118                  * For now, we ignore all local interrupts so only return an
119                  * interrupt if it's between 30 and 1020.  The test_for_ipi
120                  * routine below will pick up on IPIs.
121                  * A simple read from the controller will tell us the number
122                  * of the highest priority enabled interrupt.
123                  * We then just need to check whether it is in the
124                  * valid range for an IRQ (30-1020 inclusive).
125                  */
126                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
127                 ldr     \base, =OMAP44XX_VA_GIC_CPU_BASE
128                 ldr     \irqstat, [\base, #GIC_CPU_INTACK]
129
130                 ldr     \tmp, =1021
131
132                 bic     \irqnr, \irqstat, #0x1c00
133
134                 cmp     \irqnr, #29
135                 cmpcc   \irqnr, \irqnr
136                 cmpne   \irqnr, \tmp
137                 cmpcs   \irqnr, \irqnr
138                 .endm
139
140                 /* We assume that irqstat (the raw value of the IRQ acknowledge
141                  * register) is preserved from the macro above.
142                  * If there is an IPI, we immediately signal end of interrupt
143                  * on the controller, since this requires the original irqstat
144                  * value which we won't easily be able to recreate later.
145                  */
146
147                 .macro test_for_ipi, irqnr, irqstat, base, tmp
148                 bic     \irqnr, \irqstat, #0x1c00
149                 cmp     \irqnr, #16
150                 it      cc
151                 strcc   \irqstat, [\base, #GIC_CPU_EOI]
152                 it      cs
153                 cmpcs   \irqnr, \irqnr
154                 .endm
155
156                 /* As above, this assumes that irqstat and base are preserved */
157
158                 .macro test_for_ltirq, irqnr, irqstat, base, tmp
159                 bic     \irqnr, \irqstat, #0x1c00
160                 mov     \tmp, #0
161                 cmp     \irqnr, #29
162                 itt     eq
163                 moveq   \tmp, #1
164                 streq   \irqstat, [\base, #GIC_CPU_EOI]
165                 cmp     \tmp, #0
166                 .endm
167 #endif
168
169                 .macro  irq_prio_table
170                 .endm
171
172 #endif