Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
26498 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* SH7780 Setup
4
*
5
* Copyright (C) 2006 Paul Mundt
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
18
static 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
24
static struct resource scif0_resources[] = {
25
DEFINE_RES_MEM(0xffe00000, 0x100),
26
DEFINE_RES_IRQ(evt2irq(0x700)),
27
};
28
29
static 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
39
static 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
45
static struct resource scif1_resources[] = {
46
DEFINE_RES_MEM(0xffe10000, 0x100),
47
DEFINE_RES_IRQ(evt2irq(0xb80)),
48
};
49
50
static 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
60
static struct sh_timer_config tmu0_platform_data = {
61
.channels_mask = 7,
62
};
63
64
static 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
71
static 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
81
static struct sh_timer_config tmu1_platform_data = {
82
.channels_mask = 7,
83
};
84
85
static 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
92
static 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
102
static struct resource rtc_resources[] = {
103
[0] = {
104
.start = 0xffe80000,
105
.end = 0xffe80000 + 0x58 - 1,
106
.flags = IORESOURCE_IO,
107
},
108
[1] = {
109
/* Shared Period/Carry/Alarm IRQ */
110
.start = evt2irq(0x480),
111
.flags = IORESOURCE_IRQ,
112
},
113
};
114
115
static 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
/* DMA */
123
static 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
151
static 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
167
static const unsigned int ts_shift[] = TS_SHIFT;
168
169
static 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
181
static 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
193
static struct resource sh7780_dmae0_resources[] = {
194
[0] = {
195
/* Channel registers and DMAOR */
196
.start = 0xfc808020,
197
.end = 0xfc80808f,
198
.flags = IORESOURCE_MEM,
199
},
200
[1] = {
201
/* DMARSx */
202
.start = 0xfc809000,
203
.end = 0xfc80900b,
204
.flags = IORESOURCE_MEM,
205
},
206
{
207
/*
208
* Real DMA error vector is 0x6c0, and channel
209
* vectors are 0x640-0x6a0, 0x780-0x7a0
210
*/
211
.name = "error_irq",
212
.start = evt2irq(0x640),
213
.end = evt2irq(0x640),
214
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
215
},
216
};
217
218
static struct resource sh7780_dmae1_resources[] = {
219
[0] = {
220
/* Channel registers and DMAOR */
221
.start = 0xfc818020,
222
.end = 0xfc81808f,
223
.flags = IORESOURCE_MEM,
224
},
225
/* DMAC1 has no DMARS */
226
{
227
/*
228
* Real DMA error vector is 0x6c0, and channel
229
* vectors are 0x7c0-0x7e0, 0xd80-0xde0
230
*/
231
.name = "error_irq",
232
.start = evt2irq(0x7c0),
233
.end = evt2irq(0x7c0),
234
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
235
},
236
};
237
238
static 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
248
static 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
258
static 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
268
static int __init sh7780_devices_setup(void)
269
{
270
return platform_add_devices(sh7780_devices,
271
ARRAY_SIZE(sh7780_devices));
272
}
273
arch_initcall(sh7780_devices_setup);
274
275
static struct platform_device *sh7780_early_devices[] __initdata = {
276
&scif0_device,
277
&scif1_device,
278
&tmu0_device,
279
&tmu1_device,
280
};
281
282
void __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
293
enum {
294
UNUSED = 0,
295
296
/* interrupt sources */
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
/* interrupt groups */
310
311
TMU012, TMU345,
312
};
313
314
static 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
350
static struct intc_group groups[] __initdata = {
351
INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
352
INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
353
};
354
355
static struct intc_mask_reg mask_registers[] __initdata = {
356
{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
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
363
static struct intc_prio_reg prio_registers[] __initdata = {
364
{ 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
365
TMU2, TMU2_TICPI } },
366
{ 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },
367
{ 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },
368
{ 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } },
369
{ 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC,
370
PCISERR, PCIINTA, } },
371
{ 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,
372
PCIINTD, PCIC5 } },
373
{ 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } },
374
{ 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } },
375
};
376
377
static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups,
378
mask_registers, prio_registers, NULL);
379
380
/* Support for external interrupt pins in IRQ mode */
381
382
static 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
389
static struct intc_mask_reg irq_mask_registers[] __initdata = {
390
{ 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
391
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
392
};
393
394
static struct intc_prio_reg irq_prio_registers[] __initdata = {
395
{ 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
396
IRQ4, IRQ5, IRQ6, IRQ7 } },
397
};
398
399
static struct intc_sense_reg irq_sense_registers[] __initdata = {
400
{ 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
401
IRQ4, IRQ5, IRQ6, IRQ7 } },
402
};
403
404
static struct intc_mask_reg irq_ack_registers[] __initdata = {
405
{ 0xffd00024, 0, 32, /* INTREQ */
406
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
407
};
408
409
static 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
/* External interrupt pins in IRL mode */
414
415
static 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
426
static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
427
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
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
434
static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
435
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
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
443
static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors,
444
NULL, irl7654_mask_registers, NULL, NULL);
445
446
static 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
456
void __init plat_irq_setup(void)
457
{
458
/* disable IRQ7-0 */
459
__raw_writel(0xff000000, INTC_INTMSK0);
460
461
/* disable IRL3-0 + IRL7-4 */
462
__raw_writel(0xc0000000, INTC_INTMSK1);
463
__raw_writel(0xfffefffe, INTC_INTMSK2);
464
465
/* select IRL mode for IRL3-0 + IRL7-4 */
466
__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
467
468
/* disable holding function, ie enable "SH-4 Mode" */
469
__raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
470
471
register_intc_controller(&intc_desc);
472
}
473
474
void __init plat_irq_setup_pins(int mode)
475
{
476
switch (mode) {
477
case IRQ_MODE_IRQ:
478
/* select IRQ mode for IRL3-0 + IRL7-4 */
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
/* enable IRL7-4 but don't provide any masking */
484
__raw_writel(0x40000000, INTC_INTMSKCLR1);
485
__raw_writel(0x0000fffe, INTC_INTMSKCLR2);
486
break;
487
case IRQ_MODE_IRL3210:
488
/* enable IRL0-3 but don't provide any masking */
489
__raw_writel(0x80000000, INTC_INTMSKCLR1);
490
__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
491
break;
492
case IRQ_MODE_IRL7654_MASK:
493
/* enable IRL7-4 and mask using cpu intc controller */
494
__raw_writel(0x40000000, INTC_INTMSKCLR1);
495
register_intc_controller(&intc_irl7654_desc);
496
break;
497
case IRQ_MODE_IRL3210_MASK:
498
/* enable IRL0-3 and mask using cpu intc controller */
499
__raw_writel(0x80000000, INTC_INTMSKCLR1);
500
register_intc_controller(&intc_irl3210_desc);
501
break;
502
default:
503
BUG();
504
}
505
}
506
507