1
2
3
4
5
6
7#include <linux/platform_device.h>
8#include <linux/init.h>
9#include <linux/serial.h>
10#include <linux/io.h>
11#include <linux/serial_sci.h>
12#include <linux/sh_dma.h>
13#include <linux/sh_timer.h>
14#include <linux/sh_intc.h>
15#include <cpu/dma-register.h>
16#include <asm/platform_early.h>
17
18static struct plat_sci_port scif0_platform_data = {
19 .scscr = SCSCR_REIE | SCSCR_CKE1,
20 .type = PORT_SCIF,
21 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
22};
23
24static struct resource scif0_resources[] = {
25 DEFINE_RES_MEM(0xffe00000, 0x100),
26 DEFINE_RES_IRQ(evt2irq(0x700)),
27};
28
29static struct platform_device scif0_device = {
30 .name = "sh-sci",
31 .id = 0,
32 .resource = scif0_resources,
33 .num_resources = ARRAY_SIZE(scif0_resources),
34 .dev = {
35 .platform_data = &scif0_platform_data,
36 },
37};
38
39static struct plat_sci_port scif1_platform_data = {
40 .scscr = SCSCR_REIE | SCSCR_CKE1,
41 .type = PORT_SCIF,
42 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
43};
44
45static struct resource scif1_resources[] = {
46 DEFINE_RES_MEM(0xffe10000, 0x100),
47 DEFINE_RES_IRQ(evt2irq(0xb80)),
48};
49
50static struct platform_device scif1_device = {
51 .name = "sh-sci",
52 .id = 1,
53 .resource = scif1_resources,
54 .num_resources = ARRAY_SIZE(scif1_resources),
55 .dev = {
56 .platform_data = &scif1_platform_data,
57 },
58};
59
60static struct sh_timer_config tmu0_platform_data = {
61 .channels_mask = 7,
62};
63
64static struct resource tmu0_resources[] = {
65 DEFINE_RES_MEM(0xffd80000, 0x30),
66 DEFINE_RES_IRQ(evt2irq(0x580)),
67 DEFINE_RES_IRQ(evt2irq(0x5a0)),
68 DEFINE_RES_IRQ(evt2irq(0x5c0)),
69};
70
71static struct platform_device tmu0_device = {
72 .name = "sh-tmu",
73 .id = 0,
74 .dev = {
75 .platform_data = &tmu0_platform_data,
76 },
77 .resource = tmu0_resources,
78 .num_resources = ARRAY_SIZE(tmu0_resources),
79};
80
81static struct sh_timer_config tmu1_platform_data = {
82 .channels_mask = 7,
83};
84
85static struct resource tmu1_resources[] = {
86 DEFINE_RES_MEM(0xffdc0000, 0x2c),
87 DEFINE_RES_IRQ(evt2irq(0xe00)),
88 DEFINE_RES_IRQ(evt2irq(0xe20)),
89 DEFINE_RES_IRQ(evt2irq(0xe40)),
90};
91
92static struct platform_device tmu1_device = {
93 .name = "sh-tmu",
94 .id = 1,
95 .dev = {
96 .platform_data = &tmu1_platform_data,
97 },
98 .resource = tmu1_resources,
99 .num_resources = ARRAY_SIZE(tmu1_resources),
100};
101
102static struct resource rtc_resources[] = {
103 [0] = {
104 .start = 0xffe80000,
105 .end = 0xffe80000 + 0x58 - 1,
106 .flags = IORESOURCE_IO,
107 },
108 [1] = {
109
110 .start = evt2irq(0x480),
111 .flags = IORESOURCE_IRQ,
112 },
113};
114
115static struct platform_device rtc_device = {
116 .name = "sh-rtc",
117 .id = -1,
118 .num_resources = ARRAY_SIZE(rtc_resources),
119 .resource = rtc_resources,
120};
121
122
123static const struct sh_dmae_channel sh7780_dmae0_channels[] = {
124 {
125 .offset = 0,
126 .dmars = 0,
127 .dmars_bit = 0,
128 }, {
129 .offset = 0x10,
130 .dmars = 0,
131 .dmars_bit = 8,
132 }, {
133 .offset = 0x20,
134 .dmars = 4,
135 .dmars_bit = 0,
136 }, {
137 .offset = 0x30,
138 .dmars = 4,
139 .dmars_bit = 8,
140 }, {
141 .offset = 0x50,
142 .dmars = 8,
143 .dmars_bit = 0,
144 }, {
145 .offset = 0x60,
146 .dmars = 8,
147 .dmars_bit = 8,
148 }
149};
150
151static const struct sh_dmae_channel sh7780_dmae1_channels[] = {
152 {
153 .offset = 0,
154 }, {
155 .offset = 0x10,
156 }, {
157 .offset = 0x20,
158 }, {
159 .offset = 0x30,
160 }, {
161 .offset = 0x50,
162 }, {
163 .offset = 0x60,
164 }
165};
166
167static const unsigned int ts_shift[] = TS_SHIFT;
168
169static struct sh_dmae_pdata dma0_platform_data = {
170 .channel = sh7780_dmae0_channels,
171 .channel_num = ARRAY_SIZE(sh7780_dmae0_channels),
172 .ts_low_shift = CHCR_TS_LOW_SHIFT,
173 .ts_low_mask = CHCR_TS_LOW_MASK,
174 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
175 .ts_high_mask = CHCR_TS_HIGH_MASK,
176 .ts_shift = ts_shift,
177 .ts_shift_num = ARRAY_SIZE(ts_shift),
178 .dmaor_init = DMAOR_INIT,
179};
180
181static struct sh_dmae_pdata dma1_platform_data = {
182 .channel = sh7780_dmae1_channels,
183 .channel_num = ARRAY_SIZE(sh7780_dmae1_channels),
184 .ts_low_shift = CHCR_TS_LOW_SHIFT,
185 .ts_low_mask = CHCR_TS_LOW_MASK,
186 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
187 .ts_high_mask = CHCR_TS_HIGH_MASK,
188 .ts_shift = ts_shift,
189 .ts_shift_num = ARRAY_SIZE(ts_shift),
190 .dmaor_init = DMAOR_INIT,
191};
192
193static struct resource sh7780_dmae0_resources[] = {
194 [0] = {
195
196 .start = 0xfc808020,
197 .end = 0xfc80808f,
198 .flags = IORESOURCE_MEM,
199 },
200 [1] = {
201
202 .start = 0xfc809000,
203 .end = 0xfc80900b,
204 .flags = IORESOURCE_MEM,
205 },
206 {
207
208
209
210
211 .name = "error_irq",
212 .start = evt2irq(0x640),
213 .end = evt2irq(0x640),
214 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
215 },
216};
217
218static struct resource sh7780_dmae1_resources[] = {
219 [0] = {
220
221 .start = 0xfc818020,
222 .end = 0xfc81808f,
223 .flags = IORESOURCE_MEM,
224 },
225
226 {
227
228
229
230
231 .name = "error_irq",
232 .start = evt2irq(0x7c0),
233 .end = evt2irq(0x7c0),
234 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
235 },
236};
237
238static struct platform_device dma0_device = {
239 .name = "sh-dma-engine",
240 .id = 0,
241 .resource = sh7780_dmae0_resources,
242 .num_resources = ARRAY_SIZE(sh7780_dmae0_resources),
243 .dev = {
244 .platform_data = &dma0_platform_data,
245 },
246};
247
248static struct platform_device dma1_device = {
249 .name = "sh-dma-engine",
250 .id = 1,
251 .resource = sh7780_dmae1_resources,
252 .num_resources = ARRAY_SIZE(sh7780_dmae1_resources),
253 .dev = {
254 .platform_data = &dma1_platform_data,
255 },
256};
257
258static struct platform_device *sh7780_devices[] __initdata = {
259 &scif0_device,
260 &scif1_device,
261 &tmu0_device,
262 &tmu1_device,
263 &rtc_device,
264 &dma0_device,
265 &dma1_device,
266};
267
268static int __init sh7780_devices_setup(void)
269{
270 return platform_add_devices(sh7780_devices,
271 ARRAY_SIZE(sh7780_devices));
272}
273arch_initcall(sh7780_devices_setup);
274
275static struct platform_device *sh7780_early_devices[] __initdata = {
276 &scif0_device,
277 &scif1_device,
278 &tmu0_device,
279 &tmu1_device,
280};
281
282void __init plat_early_device_setup(void)
283{
284 if (mach_is_sh2007()) {
285 scif0_platform_data.scscr &= ~SCSCR_CKE1;
286 scif1_platform_data.scscr &= ~SCSCR_CKE1;
287 }
288
289 sh_early_platform_add_devices(sh7780_early_devices,
290 ARRAY_SIZE(sh7780_early_devices));
291}
292
293enum {
294 UNUSED = 0,
295
296
297
298 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
299 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
300 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
301 IRL_HHLL, IRL_HHLH, IRL_HHHL,
302
303 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
304 RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
305 HUDI, DMAC0, SCIF0, DMAC1, CMT, HAC,
306 PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
307 SCIF1, SIOF, HSPI, MMCIF, TMU3, TMU4, TMU5, SSI, FLCTL, GPIO,
308
309
310
311 TMU012, TMU345,
312};
313
314static struct intc_vect vectors[] __initdata = {
315 INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
316 INTC_VECT(RTC, 0x4c0),
317 INTC_VECT(WDT, 0x560),
318 INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
319 INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
320 INTC_VECT(HUDI, 0x600),
321 INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660),
322 INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0),
323 INTC_VECT(DMAC0, 0x6c0),
324 INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
325 INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
326 INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0),
327 INTC_VECT(DMAC1, 0x7c0), INTC_VECT(DMAC1, 0x7e0),
328 INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980),
329 INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
330 INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
331 INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
332 INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
333 INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
334 INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),
335 INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),
336 INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80),
337 INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
338 INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
339 INTC_VECT(DMAC1, 0xd80), INTC_VECT(DMAC1, 0xda0),
340 INTC_VECT(DMAC1, 0xdc0), INTC_VECT(DMAC1, 0xde0),
341 INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
342 INTC_VECT(TMU5, 0xe40),
343 INTC_VECT(SSI, 0xe80),
344 INTC_VECT(FLCTL, 0xf00), INTC_VECT(FLCTL, 0xf20),
345 INTC_VECT(FLCTL, 0xf40), INTC_VECT(FLCTL, 0xf60),
346 INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
347 INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
348};
349
350static struct intc_group groups[] __initdata = {
351 INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
352 INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
353};
354
355static struct intc_mask_reg mask_registers[] __initdata = {
356 { 0xffd40038, 0xffd4003c, 32,
357 { 0, 0, 0, 0, 0, 0, GPIO, FLCTL,
358 SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB,
359 PCIINTA, PCISERR, HAC, CMT, 0, 0, DMAC1, DMAC0,
360 HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },
361};
362
363static struct intc_prio_reg prio_registers[] __initdata = {
364 { 0xffd40000, 0, 32, 8, { TMU0, TMU1,
365 TMU2, TMU2_TICPI } },
366 { 0xffd40004, 0, 32, 8, { TMU3, TMU4, TMU5, RTC } },
367 { 0xffd40008, 0, 32, 8, { SCIF0, SCIF1, WDT } },
368 { 0xffd4000c, 0, 32, 8, { HUDI, DMAC0, DMAC1 } },
369 { 0xffd40010, 0, 32, 8, { CMT, HAC,
370 PCISERR, PCIINTA, } },
371 { 0xffd40014, 0, 32, 8, { PCIINTB, PCIINTC,
372 PCIINTD, PCIC5 } },
373 { 0xffd40018, 0, 32, 8, { SIOF, HSPI, MMCIF, SSI } },
374 { 0xffd4001c, 0, 32, 8, { FLCTL, GPIO } },
375};
376
377static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups,
378 mask_registers, prio_registers, NULL);
379
380
381
382static struct intc_vect irq_vectors[] __initdata = {
383 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
384 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
385 INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
386 INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
387};
388
389static struct intc_mask_reg irq_mask_registers[] __initdata = {
390 { 0xffd00044, 0xffd00064, 32,
391 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
392};
393
394static struct intc_prio_reg irq_prio_registers[] __initdata = {
395 { 0xffd00010, 0, 32, 4, { IRQ0, IRQ1, IRQ2, IRQ3,
396 IRQ4, IRQ5, IRQ6, IRQ7 } },
397};
398
399static struct intc_sense_reg irq_sense_registers[] __initdata = {
400 { 0xffd0001c, 32, 2, { IRQ0, IRQ1, IRQ2, IRQ3,
401 IRQ4, IRQ5, IRQ6, IRQ7 } },
402};
403
404static struct intc_mask_reg irq_ack_registers[] __initdata = {
405 { 0xffd00024, 0, 32,
406 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
407};
408
409static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7780-irq", irq_vectors,
410 NULL, irq_mask_registers, irq_prio_registers,
411 irq_sense_registers, irq_ack_registers);
412
413
414
415static struct intc_vect irl_vectors[] __initdata = {
416 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
417 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
418 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
419 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
420 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
421 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
422 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
423 INTC_VECT(IRL_HHHL, 0x3c0),
424};
425
426static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
427 { 0xffd40080, 0xffd40084, 32,
428 { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
429 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
430 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
431 IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
432};
433
434static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
435 { 0xffd40080, 0xffd40084, 32,
436 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
437 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
438 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
439 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
440 IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
441};
442
443static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors,
444 NULL, irl7654_mask_registers, NULL, NULL);
445
446static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
447 NULL, irl3210_mask_registers, NULL, NULL);
448
449#define INTC_ICR0 0xffd00000
450#define INTC_INTMSK0 0xffd00044
451#define INTC_INTMSK1 0xffd00048
452#define INTC_INTMSK2 0xffd40080
453#define INTC_INTMSKCLR1 0xffd00068
454#define INTC_INTMSKCLR2 0xffd40084
455
456void __init plat_irq_setup(void)
457{
458
459 __raw_writel(0xff000000, INTC_INTMSK0);
460
461
462 __raw_writel(0xc0000000, INTC_INTMSK1);
463 __raw_writel(0xfffefffe, INTC_INTMSK2);
464
465
466 __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
467
468
469 __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
470
471 register_intc_controller(&intc_desc);
472}
473
474void __init plat_irq_setup_pins(int mode)
475{
476 switch (mode) {
477 case IRQ_MODE_IRQ:
478
479 __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
480 register_intc_controller(&intc_irq_desc);
481 break;
482 case IRQ_MODE_IRL7654:
483
484 __raw_writel(0x40000000, INTC_INTMSKCLR1);
485 __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
486 break;
487 case IRQ_MODE_IRL3210:
488
489 __raw_writel(0x80000000, INTC_INTMSKCLR1);
490 __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
491 break;
492 case IRQ_MODE_IRL7654_MASK:
493
494 __raw_writel(0x40000000, INTC_INTMSKCLR1);
495 register_intc_controller(&intc_irl7654_desc);
496 break;
497 case IRQ_MODE_IRL3210_MASK:
498
499 __raw_writel(0x80000000, INTC_INTMSKCLR1);
500 register_intc_controller(&intc_irl3210_desc);
501 break;
502 default:
503 BUG();
504 }
505}
506