Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/sh/kernel/cpu/sh4a/setup-shx3.c
26498 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* SH-X3 Prototype Setup
4
*
5
* Copyright (C) 2007 - 2010 Paul Mundt
6
*/
7
#include <linux/platform_device.h>
8
#include <linux/init.h>
9
#include <linux/serial.h>
10
#include <linux/serial_sci.h>
11
#include <linux/io.h>
12
#include <linux/gpio.h>
13
#include <linux/sh_timer.h>
14
#include <linux/sh_intc.h>
15
#include <cpu/shx3.h>
16
#include <asm/mmzone.h>
17
#include <asm/platform_early.h>
18
19
/*
20
* This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2
21
* INTEVT values overlap with the FPU EXPEVT ones, requiring special
22
* demuxing in the exception dispatch path.
23
*
24
* As this overlap is something that never should have made it in to
25
* silicon in the first place, we just refuse to deal with the port at
26
* all rather than adding infrastructure to hack around it.
27
*/
28
static struct plat_sci_port scif0_platform_data = {
29
.scscr = SCSCR_REIE,
30
.type = PORT_SCIF,
31
};
32
33
static struct resource scif0_resources[] = {
34
DEFINE_RES_MEM(0xffc30000, 0x100),
35
DEFINE_RES_IRQ(evt2irq(0x700)),
36
DEFINE_RES_IRQ(evt2irq(0x720)),
37
DEFINE_RES_IRQ(evt2irq(0x760)),
38
DEFINE_RES_IRQ(evt2irq(0x740)),
39
};
40
41
static struct platform_device scif0_device = {
42
.name = "sh-sci",
43
.id = 0,
44
.resource = scif0_resources,
45
.num_resources = ARRAY_SIZE(scif0_resources),
46
.dev = {
47
.platform_data = &scif0_platform_data,
48
},
49
};
50
51
static struct plat_sci_port scif1_platform_data = {
52
.scscr = SCSCR_REIE,
53
.type = PORT_SCIF,
54
};
55
56
static struct resource scif1_resources[] = {
57
DEFINE_RES_MEM(0xffc40000, 0x100),
58
DEFINE_RES_IRQ(evt2irq(0x780)),
59
DEFINE_RES_IRQ(evt2irq(0x7a0)),
60
DEFINE_RES_IRQ(evt2irq(0x7e0)),
61
DEFINE_RES_IRQ(evt2irq(0x7c0)),
62
};
63
64
static struct platform_device scif1_device = {
65
.name = "sh-sci",
66
.id = 1,
67
.resource = scif1_resources,
68
.num_resources = ARRAY_SIZE(scif1_resources),
69
.dev = {
70
.platform_data = &scif1_platform_data,
71
},
72
};
73
74
static struct plat_sci_port scif2_platform_data = {
75
.scscr = SCSCR_REIE,
76
.type = PORT_SCIF,
77
};
78
79
static struct resource scif2_resources[] = {
80
DEFINE_RES_MEM(0xffc60000, 0x100),
81
DEFINE_RES_IRQ(evt2irq(0x880)),
82
DEFINE_RES_IRQ(evt2irq(0x8a0)),
83
DEFINE_RES_IRQ(evt2irq(0x8e0)),
84
DEFINE_RES_IRQ(evt2irq(0x8c0)),
85
};
86
87
static struct platform_device scif2_device = {
88
.name = "sh-sci",
89
.id = 2,
90
.resource = scif2_resources,
91
.num_resources = ARRAY_SIZE(scif2_resources),
92
.dev = {
93
.platform_data = &scif2_platform_data,
94
},
95
};
96
97
static struct sh_timer_config tmu0_platform_data = {
98
.channels_mask = 7,
99
};
100
101
static struct resource tmu0_resources[] = {
102
DEFINE_RES_MEM(0xffc10000, 0x30),
103
DEFINE_RES_IRQ(evt2irq(0x400)),
104
DEFINE_RES_IRQ(evt2irq(0x420)),
105
DEFINE_RES_IRQ(evt2irq(0x440)),
106
};
107
108
static struct platform_device tmu0_device = {
109
.name = "sh-tmu",
110
.id = 0,
111
.dev = {
112
.platform_data = &tmu0_platform_data,
113
},
114
.resource = tmu0_resources,
115
.num_resources = ARRAY_SIZE(tmu0_resources),
116
};
117
118
static struct sh_timer_config tmu1_platform_data = {
119
.channels_mask = 7,
120
};
121
122
static struct resource tmu1_resources[] = {
123
DEFINE_RES_MEM(0xffc20000, 0x2c),
124
DEFINE_RES_IRQ(evt2irq(0x460)),
125
DEFINE_RES_IRQ(evt2irq(0x480)),
126
DEFINE_RES_IRQ(evt2irq(0x4a0)),
127
};
128
129
static struct platform_device tmu1_device = {
130
.name = "sh-tmu",
131
.id = 1,
132
.dev = {
133
.platform_data = &tmu1_platform_data,
134
},
135
.resource = tmu1_resources,
136
.num_resources = ARRAY_SIZE(tmu1_resources),
137
};
138
139
static struct platform_device *shx3_early_devices[] __initdata = {
140
&scif0_device,
141
&scif1_device,
142
&scif2_device,
143
&tmu0_device,
144
&tmu1_device,
145
};
146
147
static int __init shx3_devices_setup(void)
148
{
149
return platform_add_devices(shx3_early_devices,
150
ARRAY_SIZE(shx3_early_devices));
151
}
152
arch_initcall(shx3_devices_setup);
153
154
void __init plat_early_device_setup(void)
155
{
156
sh_early_platform_add_devices(shx3_early_devices,
157
ARRAY_SIZE(shx3_early_devices));
158
}
159
160
enum {
161
UNUSED = 0,
162
163
/* interrupt sources */
164
IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
165
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
166
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
167
IRL_HHLL, IRL_HHLH, IRL_HHHL,
168
IRQ0, IRQ1, IRQ2, IRQ3,
169
HUDII,
170
TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
171
PCII0, PCII1, PCII2, PCII3, PCII4,
172
PCII5, PCII6, PCII7, PCII8, PCII9,
173
SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
174
SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
175
SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
176
SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI,
177
DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
178
DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
179
DU,
180
DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
181
DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
182
IIC, VIN0, VIN1, VCORE0, ATAPI,
183
DTU0, DTU1, DTU2, DTU3,
184
FE0, FE1,
185
GPIO0, GPIO1, GPIO2, GPIO3,
186
PAM, IRM,
187
INTICI0, INTICI1, INTICI2, INTICI3,
188
INTICI4, INTICI5, INTICI6, INTICI7,
189
190
/* interrupt groups */
191
IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
192
DMAC0, DMAC1,
193
};
194
195
static struct intc_vect vectors[] __initdata = {
196
INTC_VECT(HUDII, 0x3e0),
197
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
198
INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460),
199
INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0),
200
INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520),
201
INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560),
202
INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0),
203
INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0),
204
INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620),
205
INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
206
INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
207
INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
208
INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
209
INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
210
INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
211
INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
212
INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960),
213
INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0),
214
INTC_VECT(DMAC0_DMAE, 0x9c0),
215
INTC_VECT(DU, 0x9e0),
216
INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20),
217
INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60),
218
INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0),
219
INTC_VECT(DMAC1_DMAE, 0xac0),
220
INTC_VECT(IIC, 0xae0),
221
INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
222
INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
223
INTC_VECT(DTU0, 0xc00), INTC_VECT(DTU0, 0xc20),
224
INTC_VECT(DTU0, 0xc40),
225
INTC_VECT(DTU1, 0xc60), INTC_VECT(DTU1, 0xc80),
226
INTC_VECT(DTU1, 0xca0),
227
INTC_VECT(DTU2, 0xcc0), INTC_VECT(DTU2, 0xce0),
228
INTC_VECT(DTU2, 0xd00),
229
INTC_VECT(DTU3, 0xd20), INTC_VECT(DTU3, 0xd40),
230
INTC_VECT(DTU3, 0xd60),
231
INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
232
INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
233
INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
234
INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0),
235
INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
236
INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
237
INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
238
INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
239
};
240
241
static struct intc_group groups[] __initdata = {
242
INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
243
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
244
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
245
IRL_HHLL, IRL_HHLH, IRL_HHHL),
246
INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
247
INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
248
INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
249
INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
250
INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
251
DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
252
INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
253
DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
254
};
255
256
#define INT2DISTCR0 0xfe4108a0
257
#define INT2DISTCR1 0xfe4108a4
258
#define INT2DISTCR2 0xfe4108a8
259
260
static struct intc_mask_reg mask_registers[] __initdata = {
261
{ 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
262
{ IRQ0, IRQ1, IRQ2, IRQ3 } },
263
{ 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */
264
{ IRL } },
265
{ 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */
266
{ FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
267
DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
268
0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
269
0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, },
270
INTC_SMP_BALANCING(INT2DISTCR0) },
271
{ 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
272
{ 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
273
PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
274
PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
275
DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
276
DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
277
DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 },
278
INTC_SMP_BALANCING(INT2DISTCR1) },
279
{ 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
280
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
281
SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
282
SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
283
SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
284
SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI },
285
INTC_SMP_BALANCING(INT2DISTCR2) },
286
};
287
288
static struct intc_prio_reg prio_registers[] __initdata = {
289
{ 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
290
291
{ 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4,
292
TMU3, TMU2, TMU1, TMU0 } },
293
{ 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0,
294
SCIF3, SCIF2,
295
SCIF1, SCIF0 } },
296
{ 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0,
297
PCII56789, PCII4,
298
PCII3, PCII2,
299
PCII1, PCII0 } },
300
{ 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0,
301
VIN1, VIN0, IIC, DU} },
302
{ 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3,
303
GPIO2, GPIO1, GPIO0, IRM } },
304
{ 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
305
{ INTICI7, INTICI6, INTICI5, INTICI4,
306
INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) },
307
};
308
309
static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups,
310
mask_registers, prio_registers, NULL);
311
312
/* Support for external interrupt pins in IRQ mode */
313
static struct intc_vect vectors_irq[] __initdata = {
314
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
315
INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
316
};
317
318
static struct intc_sense_reg sense_registers[] __initdata = {
319
{ 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
320
};
321
322
static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
323
mask_registers, prio_registers, sense_registers);
324
325
/* External interrupt pins in IRL mode */
326
static struct intc_vect vectors_irl[] __initdata = {
327
INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
328
INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
329
INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
330
INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
331
INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
332
INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
333
INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
334
INTC_VECT(IRL_HHHL, 0x3c0),
335
};
336
337
static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
338
mask_registers, prio_registers, NULL);
339
340
void __init plat_irq_setup_pins(int mode)
341
{
342
int ret = 0;
343
344
switch (mode) {
345
case IRQ_MODE_IRQ:
346
ret |= gpio_request(GPIO_FN_IRQ3, intc_desc_irq.name);
347
ret |= gpio_request(GPIO_FN_IRQ2, intc_desc_irq.name);
348
ret |= gpio_request(GPIO_FN_IRQ1, intc_desc_irq.name);
349
ret |= gpio_request(GPIO_FN_IRQ0, intc_desc_irq.name);
350
351
if (unlikely(ret)) {
352
pr_err("Failed to set IRQ mode\n");
353
return;
354
}
355
356
register_intc_controller(&intc_desc_irq);
357
break;
358
case IRQ_MODE_IRL3210:
359
ret |= gpio_request(GPIO_FN_IRL3, intc_desc_irl.name);
360
ret |= gpio_request(GPIO_FN_IRL2, intc_desc_irl.name);
361
ret |= gpio_request(GPIO_FN_IRL1, intc_desc_irl.name);
362
ret |= gpio_request(GPIO_FN_IRL0, intc_desc_irl.name);
363
364
if (unlikely(ret)) {
365
pr_err("Failed to set IRL mode\n");
366
return;
367
}
368
369
register_intc_controller(&intc_desc_irl);
370
break;
371
default:
372
BUG();
373
}
374
}
375
376
void __init plat_irq_setup(void)
377
{
378
register_intc_controller(&intc_desc);
379
}
380
381
void __init plat_mem_setup(void)
382
{
383
unsigned int nid = 1;
384
385
/* Register CPU#0 URAM space as Node 1 */
386
setup_bootmem_node(nid++, 0x145f0000, 0x14610000); /* CPU0 */
387
388
#if 0
389
/* XXX: Not yet.. */
390
setup_bootmem_node(nid++, 0x14df0000, 0x14e10000); /* CPU1 */
391
setup_bootmem_node(nid++, 0x155f0000, 0x15610000); /* CPU2 */
392
setup_bootmem_node(nid++, 0x15df0000, 0x15e10000); /* CPU3 */
393
#endif
394
395
setup_bootmem_node(nid++, 0x16000000, 0x16020000); /* CSM */
396
}
397
398