setup-sh7750.c 11.3 KB
Newer Older
1 2 3 4
/*
 * SH7750/SH7751 Setup
 *
 *  Copyright (C) 2006  Paul Mundt
5
 *  Copyright (C) 2006  Jamie Lenehan
6 7 8 9 10 11 12 13
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
14
#include <linux/io.h>
M
Magnus Damm 已提交
15
#include <linux/sh_timer.h>
16
#include <linux/serial_sci.h>
17
#include <asm/machtypes.h>
18

19 20 21 22 23 24 25
static struct resource rtc_resources[] = {
	[0] = {
		.start	= 0xffc80000,
		.end	= 0xffc80000 + 0x58 - 1,
		.flags	= IORESOURCE_IO,
	},
	[1] = {
26
		/* Shared Period/Carry/Alarm IRQ */
27 28 29 30 31 32 33 34 35 36 37 38
		.start	= 20,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device rtc_device = {
	.name		= "sh-rtc",
	.id		= -1,
	.num_resources	= ARRAY_SIZE(rtc_resources),
	.resource	= rtc_resources,
};

39 40 41 42 43
static struct plat_sci_port sci_platform_data = {
	.mapbase	= 0xffe00000,
	.flags		= UPF_BOOT_AUTOCONF,
	.type		= PORT_SCI,
	.scscr		= SCSCR_TE | SCSCR_RE,
44
	.scbrr_algo_id	= SCBRR_ALGO_2,
45
	.irqs		= { 23, 23, 23, 0 },
46 47 48 49 50 51 52 53 54
};

static struct platform_device sci_device = {
	.name		= "sh-sci",
	.dev		= {
		.platform_data	= sci_platform_data,
	},
};

55 56 57 58
static struct plat_sci_port scif_platform_data = {
	.mapbase	= 0xffe80000,
	.flags		= UPF_BOOT_AUTOCONF,
	.scscr		= SCSCR_TE | SCSCR_RE | SCSCR_REIE,
59
	.scbrr_algo_id	= SCBRR_ALGO_2,
60 61 62 63 64 65 66 67 68 69 70
	.type		= PORT_SCIF,
	.irqs		= { 40, 40, 40, 40 },
};

static struct platform_device scif_device = {
	.name		= "sh-sci",
	.dev		= {
		.platform_data	= scif_platform_data,
	},
};

M
Magnus Damm 已提交
71 72 73 74
static struct sh_timer_config tmu0_platform_data = {
	.name = "TMU0",
	.channel_offset = 0x04,
	.timer_bit = 0,
75
	.clk = "peripheral_clk",
M
Magnus Damm 已提交
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
	.clockevent_rating = 200,
};

static struct resource tmu0_resources[] = {
	[0] = {
		.name	= "TMU0",
		.start	= 0xffd80008,
		.end	= 0xffd80013,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= 16,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device tmu0_device = {
	.name		= "sh_tmu",
	.id		= 0,
	.dev = {
		.platform_data	= &tmu0_platform_data,
	},
	.resource	= tmu0_resources,
	.num_resources	= ARRAY_SIZE(tmu0_resources),
};

static struct sh_timer_config tmu1_platform_data = {
	.name = "TMU1",
	.channel_offset = 0x10,
	.timer_bit = 1,
106
	.clk = "peripheral_clk",
M
Magnus Damm 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
	.clocksource_rating = 200,
};

static struct resource tmu1_resources[] = {
	[0] = {
		.name	= "TMU1",
		.start	= 0xffd80014,
		.end	= 0xffd8001f,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= 17,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device tmu1_device = {
	.name		= "sh_tmu",
	.id		= 1,
	.dev = {
		.platform_data	= &tmu1_platform_data,
	},
	.resource	= tmu1_resources,
	.num_resources	= ARRAY_SIZE(tmu1_resources),
};

static struct sh_timer_config tmu2_platform_data = {
	.name = "TMU2",
	.channel_offset = 0x1c,
	.timer_bit = 2,
137
	.clk = "peripheral_clk",
M
Magnus Damm 已提交
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
};

static struct resource tmu2_resources[] = {
	[0] = {
		.name	= "TMU2",
		.start	= 0xffd80020,
		.end	= 0xffd8002f,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= 18,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device tmu2_device = {
	.name		= "sh_tmu",
	.id		= 2,
	.dev = {
		.platform_data	= &tmu2_platform_data,
	},
	.resource	= tmu2_resources,
	.num_resources	= ARRAY_SIZE(tmu2_resources),
};

/* SH7750R, SH7751 and SH7751R all have two extra timer channels */
#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
	defined(CONFIG_CPU_SUBTYPE_SH7751) || \
	defined(CONFIG_CPU_SUBTYPE_SH7751R)

static struct sh_timer_config tmu3_platform_data = {
	.name = "TMU3",
	.channel_offset = 0x04,
	.timer_bit = 0,
172
	.clk = "peripheral_clk",
M
Magnus Damm 已提交
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
};

static struct resource tmu3_resources[] = {
	[0] = {
		.name	= "TMU3",
		.start	= 0xfe100008,
		.end	= 0xfe100013,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= 72,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device tmu3_device = {
	.name		= "sh_tmu",
	.id		= 3,
	.dev = {
		.platform_data	= &tmu3_platform_data,
	},
	.resource	= tmu3_resources,
	.num_resources	= ARRAY_SIZE(tmu3_resources),
};

static struct sh_timer_config tmu4_platform_data = {
	.name = "TMU4",
	.channel_offset = 0x10,
	.timer_bit = 1,
202
	.clk = "peripheral_clk",
M
Magnus Damm 已提交
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
};

static struct resource tmu4_resources[] = {
	[0] = {
		.name	= "TMU4",
		.start	= 0xfe100014,
		.end	= 0xfe10001f,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= 76,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device tmu4_device = {
	.name		= "sh_tmu",
	.id		= 4,
	.dev = {
		.platform_data	= &tmu4_platform_data,
	},
	.resource	= tmu4_resources,
	.num_resources	= ARRAY_SIZE(tmu4_resources),
};

#endif

230
static struct platform_device *sh7750_devices[] __initdata = {
231
	&rtc_device,
M
Magnus Damm 已提交
232 233 234 235 236 237 238 239 240
	&tmu0_device,
	&tmu1_device,
	&tmu2_device,
#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
	defined(CONFIG_CPU_SUBTYPE_SH7751) || \
	defined(CONFIG_CPU_SUBTYPE_SH7751R)
	&tmu3_device,
	&tmu4_device,
#endif
241 242 243 244
};

static int __init sh7750_devices_setup(void)
{
245 246 247 248 249 250 251 252
	if (mach_is_rts7751r2d()) {
		scif_platform_data.scscr |= SCSCR_CKE1;
		platform_register_device(&scif_device);
	} else {
		platform_register_device(&sci_device);
		platform_register_device(&scif_device);
	}

253 254 255 256
	return platform_add_devices(sh7750_devices,
				    ARRAY_SIZE(sh7750_devices));
}
__initcall(sh7750_devices_setup);
257

M
Magnus Damm 已提交
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
static struct platform_device *sh7750_early_devices[] __initdata = {
	&tmu0_device,
	&tmu1_device,
	&tmu2_device,
#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
	defined(CONFIG_CPU_SUBTYPE_SH7751) || \
	defined(CONFIG_CPU_SUBTYPE_SH7751R)
	&tmu3_device,
	&tmu4_device,
#endif
};

void __init plat_early_device_setup(void)
{
	early_platform_add_devices(sh7750_early_devices,
				   ARRAY_SIZE(sh7750_early_devices));
}

276 277 278 279 280
enum {
	UNUSED = 0,

	/* interrupt sources */
	IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
281
	HUDI, GPIOI, DMAC,
282 283
	PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
	PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3,
284
	TMU3, TMU4, TMU0, TMU1, TMU2, RTC, SCI1, SCIF, WDT, REF,
285 286

	/* interrupt groups */
287
	PCIC1,
M
Magnus Damm 已提交
288 289
};

290
static struct intc_vect vectors[] __initdata = {
291 292
	INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
	INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
293 294 295 296 297 298 299
	INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460),
	INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
	INTC_VECT(RTC, 0x4c0),
	INTC_VECT(SCI1, 0x4e0), INTC_VECT(SCI1, 0x500),
	INTC_VECT(SCI1, 0x520), INTC_VECT(SCI1, 0x540),
	INTC_VECT(SCIF, 0x700), INTC_VECT(SCIF, 0x720),
	INTC_VECT(SCIF, 0x740), INTC_VECT(SCIF, 0x760),
300
	INTC_VECT(WDT, 0x560),
301
	INTC_VECT(REF, 0x580), INTC_VECT(REF, 0x5a0),
302
};
M
Magnus Damm 已提交
303

304
static struct intc_prio_reg prio_registers[] __initdata = {
305 306 307 308 309 310 311
	{ 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
	{ 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
	{ 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } },
	{ 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
	{ 0xfe080000, 0, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0,
						 TMU4, TMU3,
						 PCIC1, PCIC0_PCISERR } },
312 313
};

314
static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, NULL,
315
			 NULL, prio_registers, NULL);
316 317 318 319 320 321

/* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */
#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \
	defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
	defined(CONFIG_CPU_SUBTYPE_SH7751) || \
	defined(CONFIG_CPU_SUBTYPE_SH7091)
322
static struct intc_vect vectors_dma4[] __initdata = {
323 324 325
	INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
	INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
	INTC_VECT(DMAC, 0x6c0),
326 327 328
};

static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4",
329
			 vectors_dma4, NULL,
330
			 NULL, prio_registers, NULL);
331 332 333 334
#endif

/* SH7750R and SH7751R both have 8-channel DMA controllers */
#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
335
static struct intc_vect vectors_dma8[] __initdata = {
336 337 338 339 340
	INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
	INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
	INTC_VECT(DMAC, 0x780), INTC_VECT(DMAC, 0x7a0),
	INTC_VECT(DMAC, 0x7c0), INTC_VECT(DMAC, 0x7e0),
	INTC_VECT(DMAC, 0x6c0),
341 342 343
};

static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8",
344
			 vectors_dma8, NULL,
345
			 NULL, prio_registers, NULL);
346 347 348 349 350 351
#endif

/* SH7750R, SH7751 and SH7751R all have two extra timer channels */
#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
	defined(CONFIG_CPU_SUBTYPE_SH7751) || \
	defined(CONFIG_CPU_SUBTYPE_SH7751R)
352
static struct intc_vect vectors_tmu34[] __initdata = {
353 354 355
	INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80),
};

356
static struct intc_mask_reg mask_registers[] __initdata = {
357 358 359 360 361 362 363 364 365
	{ 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
	  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	    0, 0, 0, 0, 0, 0, TMU4, TMU3,
	    PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
	    PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2,
	    PCIC1_PCIDMA3, PCIC0_PCISERR } },
};

static DECLARE_INTC_DESC(intc_desc_tmu34, "sh7750_tmu34",
366
			 vectors_tmu34, NULL,
367 368 369 370
			 mask_registers, prio_registers, NULL);
#endif

/* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */
371
static struct intc_vect vectors_irlm[] __initdata = {
372 373 374 375 376
	INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
	INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
};

static DECLARE_INTC_DESC(intc_desc_irlm, "sh7750_irlm", vectors_irlm, NULL,
377
			 NULL, prio_registers, NULL);
378 379 380

/* SH7751 and SH7751R both have PCI */
#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
381
static struct intc_vect vectors_pci[] __initdata = {
382 383 384 385 386 387
	INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0),
	INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0),
	INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60),
	INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20),
};

388
static struct intc_group groups_pci[] __initdata = {
389 390
	INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
		   PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
391
};
392 393

static DECLARE_INTC_DESC(intc_desc_pci, "sh7750_pci", vectors_pci, groups_pci,
394
			 mask_registers, prio_registers, NULL);
M
Magnus Damm 已提交
395
#endif
396

397 398 399
#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \
	defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
	defined(CONFIG_CPU_SUBTYPE_SH7091)
400
void __init plat_irq_setup(void)
401
{
402 403 404 405 406 407 408
	/*
	 * same vectors for SH7750, SH7750S and SH7091 except for IRLM,
	 * see below..
	 */
	register_intc_controller(&intc_desc);
	register_intc_controller(&intc_desc_dma4);
}
M
Magnus Damm 已提交
409
#endif
410 411 412 413 414 415 416

#if defined(CONFIG_CPU_SUBTYPE_SH7750R)
void __init plat_irq_setup(void)
{
	register_intc_controller(&intc_desc);
	register_intc_controller(&intc_desc_dma8);
	register_intc_controller(&intc_desc_tmu34);
417
}
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
#endif

#if defined(CONFIG_CPU_SUBTYPE_SH7751)
void __init plat_irq_setup(void)
{
	register_intc_controller(&intc_desc);
	register_intc_controller(&intc_desc_dma4);
	register_intc_controller(&intc_desc_tmu34);
	register_intc_controller(&intc_desc_pci);
}
#endif

#if defined(CONFIG_CPU_SUBTYPE_SH7751R)
void __init plat_irq_setup(void)
{
	register_intc_controller(&intc_desc);
	register_intc_controller(&intc_desc_dma8);
	register_intc_controller(&intc_desc_tmu34);
	register_intc_controller(&intc_desc_pci);
}
#endif
439 440 441 442

#define INTC_ICR	0xffd00000UL
#define INTC_ICR_IRLM   (1<<7)

443
void __init plat_irq_setup_pins(int mode)
444
{
445 446
#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7091)
	BUG(); /* impossible to mask interrupts on SH7750 and SH7091 */
447
	return;
448 449
#endif

450 451 452 453 454 455 456 457
	switch (mode) {
	case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
		ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
		register_intc_controller(&intc_desc_irlm);
		break;
	default:
		BUG();
	}
458
}