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