aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2007-07-20 05:44:49 -0400
committerPaul Mundt <lethal@linux-sh.org>2007-07-20 05:44:49 -0400
commit56386f6424f242cff46e2cfd7be44624cd37dce1 (patch)
treea8dd5193063e892fc424f8b2da247c020ec54496 /arch/sh/kernel
parent339547bf5de1212c9c7b89b0e0d69620709729d2 (diff)
sh: intc - add support for SH7750 and its variants
This patch converts the cpu specific 7750 setup code to use the new intc controller. Many new vectors are added and multiple processor variants including 7091, 7750, 7750s, 7750r, 7751 and 7751r should all have the correct vectors hooked up. IRLM interrupts can be enabled using ipr_irq_enable_irlm() which now is marked as __init. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c253
1 files changed, 189 insertions, 64 deletions
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index b0cd6e0b8539..f2286de22bd5 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -82,88 +82,213 @@ static int __init sh7750_devices_setup(void)
82} 82}
83__initcall(sh7750_devices_setup); 83__initcall(sh7750_devices_setup);
84 84
85static struct ipr_data ipr_irq_table[] = { 85enum {
86 /* IRQ, IPR-idx, shift, priority */ 86 UNUSED = 0,
87 { 16, 0, 12, 2 }, /* TMU0 TUNI*/ 87
88 { 17, 0, 12, 2 }, /* TMU1 TUNI */ 88 /* interrupt sources */
89 { 18, 0, 4, 2 }, /* TMU2 TUNI */ 89 IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
90 { 19, 0, 4, 2 }, /* TMU2 TIPCI */ 90 HUDI, GPIOI,
91 { 27, 1, 12, 2 }, /* WDT ITI */ 91 DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
92 { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ 92 DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
93 { 21, 0, 0, 2 }, /* RTC PRI (period) */ 93 DMAC_DMAE,
94 { 22, 0, 0, 2 }, /* RTC CUI (carry) */ 94 PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
95 { 23, 1, 4, 3 }, /* SCI ERI */ 95 PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3,
96 { 24, 1, 4, 3 }, /* SCI RXI */ 96 TMU3, TMU4, TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
97 { 25, 1, 4, 3 }, /* SCI TXI */ 97 RTC_ATI, RTC_PRI, RTC_CUI,
98 { 40, 2, 4, 3 }, /* SCIF ERI */ 98 SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI,
99 { 41, 2, 4, 3 }, /* SCIF RXI */ 99 SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI,
100 { 42, 2, 4, 3 }, /* SCIF BRI */ 100 WDT,
101 { 43, 2, 4, 3 }, /* SCIF TXI */ 101 REF_RCMI, REF_ROVI,
102 { 34, 2, 8, 7 }, /* DMAC DMTE0 */ 102
103 { 35, 2, 8, 7 }, /* DMAC DMTE1 */ 103 /* interrupt groups */
104 { 36, 2, 8, 7 }, /* DMAC DMTE2 */ 104 DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
105 { 37, 2, 8, 7 }, /* DMAC DMTE3 */
106 { 38, 2, 8, 7 }, /* DMAC DMAE */
107};
108
109static unsigned long ipr_offsets[] = {
110 0xffd00004UL, /* 0: IPRA */
111 0xffd00008UL, /* 1: IPRB */
112 0xffd0000cUL, /* 2: IPRC */
113 0xffd00010UL, /* 3: IPRD */
114};
115
116static struct ipr_desc ipr_irq_desc = {
117 .ipr_offsets = ipr_offsets,
118 .nr_offsets = ARRAY_SIZE(ipr_offsets),
119
120 .ipr_data = ipr_irq_table,
121 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
122
123 .chip = {
124 .name = "IPR-sh7750",
125 },
126}; 105};
127 106
128#ifdef CONFIG_CPU_SUBTYPE_SH7751 107static struct intc_vect vectors[] = {
129static struct ipr_data ipr_irq_table_sh7751[] = { 108 INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
130 { 44, 2, 8, 7 }, /* DMAC DMTE4 */ 109 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
131 { 45, 2, 8, 7 }, /* DMAC DMTE5 */ 110 INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
132 { 46, 2, 8, 7 }, /* DMAC DMTE6 */ 111 INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
133 { 47, 2, 8, 7 }, /* DMAC DMTE7 */ 112 INTC_VECT(RTC_CUI, 0x4c0),
134 /* The following use INTC_INPRI00 for masking, which is a 32-bit 113 INTC_VECT(SCI1_ERI, 0x4e0), INTC_VECT(SCI1_RXI, 0x500),
135 register, not a 16-bit register like the IPRx registers, so it 114 INTC_VECT(SCI1_TXI, 0x520), INTC_VECT(SCI1_TEI, 0x540),
136 would need special support */ 115 INTC_VECT(SCIF_ERI, 0x700), INTC_VECT(SCIF_RXI, 0x720),
137 /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ 116 INTC_VECT(SCIF_BRI, 0x740), INTC_VECT(SCIF_TXI, 0x760),
138 /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ 117 INTC_VECT(WDT, 0x560),
118 INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
139}; 119};
140 120
141static struct ipr_desc ipr_irq_desc_sh7751 = { 121static struct intc_group groups[] = {
142 .ipr_offsets = ipr_offsets, 122 INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
143 .nr_offsets = ARRAY_SIZE(ipr_offsets), 123 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
124 INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI),
125 INTC_GROUP(SCIF, SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI),
126 INTC_GROUP(REF, REF_RCMI, REF_ROVI),
127};
144 128
145 .ipr_data = ipr_irq_table_sh7751, 129static struct intc_prio priorities[] = {
146 .nr_irqs = ARRAY_SIZE(ipr_irq_table_sh7751), 130 INTC_PRIO(SCIF, 3),
131 INTC_PRIO(SCI1, 3),
132 INTC_PRIO(DMAC, 7),
133};
147 134
148 .chip = { 135static struct intc_prio_reg prio_registers[] = {
149 .name = "IPR-sh7751", 136 { 0xffd00004, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
150 }, 137 { 0xffd00008, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
138 { 0xffd0000c, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } },
139 { 0xffd00010, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
140 { 0xfe080000, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0,
141 TMU4, TMU3,
142 PCIC1, PCIC0_PCISERR } },
143};
144
145static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups,
146 priorities, NULL, prio_registers, NULL);
147
148/* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */
149#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \
150 defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
151 defined(CONFIG_CPU_SUBTYPE_SH7751) || \
152 defined(CONFIG_CPU_SUBTYPE_SH7091)
153static struct intc_vect vectors_dma4[] = {
154 INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
155 INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
156 INTC_VECT(DMAC_DMAE, 0x6c0),
157};
158
159static struct intc_group groups_dma4[] = {
160 INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
161 DMAC_DMTE3, DMAC_DMAE),
162};
163
164static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4",
165 vectors_dma4, groups_dma4,
166 priorities, NULL, prio_registers, NULL);
167#endif
168
169/* SH7750R and SH7751R both have 8-channel DMA controllers */
170#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
171static struct intc_vect vectors_dma8[] = {
172 INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
173 INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
174 INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
175 INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0),
176 INTC_VECT(DMAC_DMAE, 0x6c0),
177};
178
179static struct intc_group groups_dma8[] = {
180 INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
181 DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
182 DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
183};
184
185static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8",
186 vectors_dma8, groups_dma8,
187 priorities, NULL, prio_registers, NULL);
188#endif
189
190/* SH7750R, SH7751 and SH7751R all have two extra timer channels */
191#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
192 defined(CONFIG_CPU_SUBTYPE_SH7751) || \
193 defined(CONFIG_CPU_SUBTYPE_SH7751R)
194static struct intc_vect vectors_tmu34[] = {
195 INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80),
196};
197
198static struct intc_mask_reg mask_registers[] = {
199 { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
200 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
201 0, 0, 0, 0, 0, 0, TMU4, TMU3,
202 PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
203 PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2,
204 PCIC1_PCIDMA3, PCIC0_PCISERR } },
205};
206
207static DECLARE_INTC_DESC(intc_desc_tmu34, "sh7750_tmu34",
208 vectors_tmu34, NULL, priorities,
209 mask_registers, prio_registers, NULL);
210#endif
211
212/* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */
213static struct intc_vect vectors_irlm[] = {
214 INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
215 INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
216};
217
218static DECLARE_INTC_DESC(intc_desc_irlm, "sh7750_irlm", vectors_irlm, NULL,
219 priorities, NULL, prio_registers, NULL);
220
221/* SH7751 and SH7751R both have PCI */
222#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
223static struct intc_vect vectors_pci[] = {
224 INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0),
225 INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0),
226 INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60),
227 INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20),
228};
229
230static struct intc_group groups_pci[] = {
231 INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
232 PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
151}; 233};
234
235static DECLARE_INTC_DESC(intc_desc_pci, "sh7750_pci", vectors_pci, groups_pci,
236 priorities, mask_registers, prio_registers, NULL);
152#endif 237#endif
153 238
239#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \
240 defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
241 defined(CONFIG_CPU_SUBTYPE_SH7091)
154void __init plat_irq_setup(void) 242void __init plat_irq_setup(void)
155{ 243{
156 register_ipr_controller(&ipr_irq_desc); 244 /*
157#ifdef CONFIG_CPU_SUBTYPE_SH7751 245 * same vectors for SH7750, SH7750S and SH7091 except for IRLM,
158 register_ipr_controller(&ipr_irq_desc_sh7751); 246 * see below..
247 */
248 register_intc_controller(&intc_desc);
249 register_intc_controller(&intc_desc_dma4);
250}
159#endif 251#endif
252
253#if defined(CONFIG_CPU_SUBTYPE_SH7750R)
254void __init plat_irq_setup(void)
255{
256 register_intc_controller(&intc_desc);
257 register_intc_controller(&intc_desc_dma8);
258 register_intc_controller(&intc_desc_tmu34);
160} 259}
260#endif
261
262#if defined(CONFIG_CPU_SUBTYPE_SH7751)
263void __init plat_irq_setup(void)
264{
265 register_intc_controller(&intc_desc);
266 register_intc_controller(&intc_desc_dma4);
267 register_intc_controller(&intc_desc_tmu34);
268 register_intc_controller(&intc_desc_pci);
269}
270#endif
271
272#if defined(CONFIG_CPU_SUBTYPE_SH7751R)
273void __init plat_irq_setup(void)
274{
275 register_intc_controller(&intc_desc);
276 register_intc_controller(&intc_desc_dma8);
277 register_intc_controller(&intc_desc_tmu34);
278 register_intc_controller(&intc_desc_pci);
279}
280#endif
161 281
162#define INTC_ICR 0xffd00000UL 282#define INTC_ICR 0xffd00000UL
163#define INTC_ICR_IRLM (1<<7) 283#define INTC_ICR_IRLM (1<<7)
164 284
165/* enable individual interrupt mode for external interupts */ 285/* enable individual interrupt mode for external interupts */
166void ipr_irq_enable_irlm(void) 286void __init ipr_irq_enable_irlm(void)
167{ 287{
288#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7091)
289 BUG(); /* impossible to mask interrupts on SH7750 and SH7091 */
290#endif
291 register_intc_controller(&intc_desc_irlm);
292
168 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 293 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
169} 294}