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