realview_eb.c 12.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 *  linux/arch/arm/mach-realview/realview_eb.c
 *
 *  Copyright (C) 2004 ARM Limited
 *  Copyright (C) 2000 Deep Blue Solutions Ltd
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/init.h>
23
#include <linux/platform_device.h>
K
Kay Sievers 已提交
24
#include <linux/device.h>
25
#include <linux/amba/bus.h>
26
#include <linux/amba/pl061.h>
27
#include <linux/amba/mmci.h>
28
#include <linux/amba/pl022.h>
29
#include <linux/io.h>
30

31
#include <mach/hardware.h>
32 33
#include <asm/irq.h>
#include <asm/mach-types.h>
34
#include <asm/pmu.h>
35
#include <asm/pgtable.h>
36
#include <asm/hardware/gic.h>
37
#include <asm/hardware/cache-l2x0.h>
38
#include <asm/smp_twd.h>
39 40 41

#include <asm/mach/arch.h>
#include <asm/mach/map.h>
42
#include <asm/mach/time.h>
43

44 45
#include <mach/board-eb.h>
#include <mach/irqs.h>
46 47 48 49

#include "core.h"

static struct map_desc realview_eb_io_desc[] __initdata = {
50 51 52 53 54 55
	{
		.virtual	= IO_ADDRESS(REALVIEW_SYS_BASE),
		.pfn		= __phys_to_pfn(REALVIEW_SYS_BASE),
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	}, {
56 57
		.virtual	= IO_ADDRESS(REALVIEW_EB_GIC_CPU_BASE),
		.pfn		= __phys_to_pfn(REALVIEW_EB_GIC_CPU_BASE),
58 59 60
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	}, {
61 62
		.virtual	= IO_ADDRESS(REALVIEW_EB_GIC_DIST_BASE),
		.pfn		= __phys_to_pfn(REALVIEW_EB_GIC_DIST_BASE),
63 64 65 66 67 68 69 70
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	}, {
		.virtual	= IO_ADDRESS(REALVIEW_SCTL_BASE),
		.pfn		= __phys_to_pfn(REALVIEW_SCTL_BASE),
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	}, {
71 72
		.virtual	= IO_ADDRESS(REALVIEW_EB_TIMER0_1_BASE),
		.pfn		= __phys_to_pfn(REALVIEW_EB_TIMER0_1_BASE),
73 74 75
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	}, {
76 77
		.virtual	= IO_ADDRESS(REALVIEW_EB_TIMER2_3_BASE),
		.pfn		= __phys_to_pfn(REALVIEW_EB_TIMER2_3_BASE),
78 79 80
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	},
81
#ifdef CONFIG_DEBUG_LL
82
	{
83 84
		.virtual	= IO_ADDRESS(REALVIEW_EB_UART0_BASE),
		.pfn		= __phys_to_pfn(REALVIEW_EB_UART0_BASE),
85 86 87
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	}
88 89 90
#endif
};

91 92
static struct map_desc realview_eb11mp_io_desc[] __initdata = {
	{
93 94 95
		.virtual	= IO_ADDRESS(REALVIEW_EB11MP_PRIV_MEM_BASE),
		.pfn		= __phys_to_pfn(REALVIEW_EB11MP_PRIV_MEM_BASE),
		.length		= REALVIEW_EB11MP_PRIV_MEM_SIZE,
96 97 98 99 100 101 102 103 104
		.type		= MT_DEVICE,
	}, {
		.virtual	= IO_ADDRESS(REALVIEW_EB11MP_L220_BASE),
		.pfn		= __phys_to_pfn(REALVIEW_EB11MP_L220_BASE),
		.length		= SZ_8K,
		.type		= MT_DEVICE,
	}
};

105 106 107
static void __init realview_eb_map_io(void)
{
	iotable_init(realview_eb_io_desc, ARRAY_SIZE(realview_eb_io_desc));
108
	if (core_tile_eb11mp() || core_tile_a9mp())
109
		iotable_init(realview_eb11mp_io_desc, ARRAY_SIZE(realview_eb11mp_io_desc));
110 111
}

112 113 114 115 116 117 118 119 120 121 122 123
static struct pl061_platform_data gpio0_plat_data = {
	.gpio_base	= 0,
};

static struct pl061_platform_data gpio1_plat_data = {
	.gpio_base	= 8,
};

static struct pl061_platform_data gpio2_plat_data = {
	.gpio_base	= 16,
};

124 125 126 127 128 129
static struct pl022_ssp_controller ssp0_plat_data = {
	.bus_id = 0,
	.enable_dma = 0,
	.num_chipselect = 1,
};

130 131 132 133 134 135 136
/*
 * RealView EB AMBA devices
 */

/*
 * These devices are connected via the core APB bridge
 */
137 138
#define GPIO2_IRQ	{ IRQ_EB_GPIO2 }
#define GPIO3_IRQ	{ IRQ_EB_GPIO3 }
139

140
#define AACI_IRQ	{ IRQ_EB_AACI }
141
#define MMCI0_IRQ	{ IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
142 143
#define KMI0_IRQ	{ IRQ_EB_KMI0 }
#define KMI1_IRQ	{ IRQ_EB_KMI1 }
144 145 146 147

/*
 * These devices are connected directly to the multi-layer AHB switch
 */
148 149 150 151
#define EB_SMC_IRQ	{ }
#define MPMC_IRQ	{ }
#define EB_CLCD_IRQ	{ IRQ_EB_CLCD }
#define DMAC_IRQ	{ IRQ_EB_DMA }
152 153 154 155

/*
 * These devices are connected via the core APB bridge
 */
156 157 158 159 160
#define SCTL_IRQ	{ }
#define EB_WATCHDOG_IRQ	{ IRQ_EB_WDOG }
#define EB_GPIO0_IRQ	{ IRQ_EB_GPIO0 }
#define GPIO1_IRQ	{ IRQ_EB_GPIO1 }
#define EB_RTC_IRQ	{ IRQ_EB_RTC }
161 162 163 164

/*
 * These devices are connected via the DMA APB bridge
 */
165 166 167 168 169 170
#define SCI_IRQ		{ IRQ_EB_SCI }
#define EB_UART0_IRQ	{ IRQ_EB_UART0 }
#define EB_UART1_IRQ	{ IRQ_EB_UART1 }
#define EB_UART2_IRQ	{ IRQ_EB_UART2 }
#define EB_UART3_IRQ	{ IRQ_EB_UART3 }
#define EB_SSP_IRQ	{ IRQ_EB_SSP }
171

172
/* FPGA Primecells */
173 174 175 176 177
APB_DEVICE(aaci,  "fpga:aaci",  AACI,     NULL);
APB_DEVICE(mmc0,  "fpga:mmc0",  MMCI0,    &realview_mmc0_plat_data);
APB_DEVICE(kmi0,  "fpga:kmi0",  KMI0,     NULL);
APB_DEVICE(kmi1,  "fpga:kmi1",  KMI1,     NULL);
APB_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL);
178 179

/* DevChip Primecells */
180 181 182 183 184 185 186 187 188 189 190 191 192 193
AHB_DEVICE(smc,   "dev:smc",   EB_SMC,   NULL);
AHB_DEVICE(clcd,  "dev:clcd",  EB_CLCD,  &clcd_plat_data);
AHB_DEVICE(dmac,  "dev:dmac",  DMAC,     NULL);
AHB_DEVICE(sctl,  "dev:sctl",  SCTL,     NULL);
APB_DEVICE(wdog,  "dev:wdog",  EB_WATCHDOG, NULL);
APB_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data);
APB_DEVICE(gpio1, "dev:gpio1", GPIO1,    &gpio1_plat_data);
APB_DEVICE(gpio2, "dev:gpio2", GPIO2,    &gpio2_plat_data);
APB_DEVICE(rtc,   "dev:rtc",   EB_RTC,   NULL);
APB_DEVICE(sci0,  "dev:sci0",  SCI,      NULL);
APB_DEVICE(uart0, "dev:uart0", EB_UART0, NULL);
APB_DEVICE(uart1, "dev:uart1", EB_UART1, NULL);
APB_DEVICE(uart2, "dev:uart2", EB_UART2, NULL);
APB_DEVICE(ssp0,  "dev:ssp0",  EB_SSP,   &ssp0_plat_data);
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216

static struct amba_device *amba_devs[] __initdata = {
	&dmac_device,
	&uart0_device,
	&uart1_device,
	&uart2_device,
	&uart3_device,
	&smc_device,
	&clcd_device,
	&sctl_device,
	&wdog_device,
	&gpio0_device,
	&gpio1_device,
	&gpio2_device,
	&rtc_device,
	&sci0_device,
	&ssp0_device,
	&aaci_device,
	&mmc0_device,
	&kmi0_device,
	&kmi1_device,
};

217 218 219
/*
 * RealView EB platform devices
 */
220 221 222 223 224
static struct resource realview_eb_flash_resource = {
	.start			= REALVIEW_EB_FLASH_BASE,
	.end			= REALVIEW_EB_FLASH_BASE + REALVIEW_EB_FLASH_SIZE - 1,
	.flags			= IORESOURCE_MEM,
};
225

226
static struct resource realview_eb_eth_resources[] = {
227
	[0] = {
228 229
		.start		= REALVIEW_EB_ETH_BASE,
		.end		= REALVIEW_EB_ETH_BASE + SZ_64K - 1,
230 231 232 233 234 235 236 237 238
		.flags		= IORESOURCE_MEM,
	},
	[1] = {
		.start		= IRQ_EB_ETH,
		.end		= IRQ_EB_ETH,
		.flags		= IORESOURCE_IRQ,
	},
};

239 240 241 242 243 244
/*
 * Detect and register the correct Ethernet device. RealView/EB rev D
 * platforms use the newer SMSC LAN9118 Ethernet chip
 */
static int eth_device_register(void)
{
245
	void __iomem *eth_addr = ioremap(REALVIEW_EB_ETH_BASE, SZ_4K);
246
	const char *name = NULL;
247 248 249 250 251 252
	u32 idrev;

	if (!eth_addr)
		return -ENOMEM;

	idrev = readl(eth_addr + 0x50);
253 254 255
	if ((idrev & 0xFFFF0000) != 0x01180000)
		/* SMSC LAN9118 not present, use LAN91C111 instead */
		name = "smc91x";
256 257

	iounmap(eth_addr);
258
	return realview_eth_register(name, realview_eb_eth_resources);
259 260
}

261 262 263 264 265 266 267 268 269 270 271 272 273
static struct resource realview_eb_isp1761_resources[] = {
	[0] = {
		.start		= REALVIEW_EB_USB_BASE,
		.end		= REALVIEW_EB_USB_BASE + SZ_128K - 1,
		.flags		= IORESOURCE_MEM,
	},
	[1] = {
		.start		= IRQ_EB_USB,
		.end		= IRQ_EB_USB,
		.flags		= IORESOURCE_IRQ,
	},
};

274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
static struct resource pmu_resources[] = {
	[0] = {
		.start		= IRQ_EB11MP_PMU_CPU0,
		.end		= IRQ_EB11MP_PMU_CPU0,
		.flags		= IORESOURCE_IRQ,
	},
	[1] = {
		.start		= IRQ_EB11MP_PMU_CPU1,
		.end		= IRQ_EB11MP_PMU_CPU1,
		.flags		= IORESOURCE_IRQ,
	},
	[2] = {
		.start		= IRQ_EB11MP_PMU_CPU2,
		.end		= IRQ_EB11MP_PMU_CPU2,
		.flags		= IORESOURCE_IRQ,
	},
	[3] = {
		.start		= IRQ_EB11MP_PMU_CPU3,
		.end		= IRQ_EB11MP_PMU_CPU3,
		.flags		= IORESOURCE_IRQ,
	},
};

static struct platform_device pmu_device = {
	.name			= "arm-pmu",
	.id			= ARM_PMU_DEVICE_CPU,
	.num_resources		= ARRAY_SIZE(pmu_resources),
	.resource		= pmu_resources,
};

304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
static struct resource char_lcd_resources[] = {
	{
		.start = REALVIEW_CHAR_LCD_BASE,
		.end   = (REALVIEW_CHAR_LCD_BASE + SZ_4K - 1),
		.flags = IORESOURCE_MEM,
	},
	{
		.start	= IRQ_EB_CHARLCD,
		.end	= IRQ_EB_CHARLCD,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device char_lcd_device = {
	.name		=	"arm-charlcd",
	.id		=	-1,
	.num_resources	=	ARRAY_SIZE(char_lcd_resources),
	.resource	=	char_lcd_resources,
};

324 325
static void __init gic_init_irq(void)
{
326
	if (core_tile_eb11mp() || core_tile_a9mp()) {
327 328 329 330 331 332 333 334 335 336
		unsigned int pldctrl;

		/* new irq mode */
		writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
		pldctrl = readl(__io_address(REALVIEW_SYS_BASE)	+ REALVIEW_EB11MP_SYS_PLD_CTRL1);
		pldctrl |= 0x00800000;
		writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + REALVIEW_EB11MP_SYS_PLD_CTRL1);
		writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));

		/* core tile GIC, primary */
337
		gic_init(0, 29, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE),
338
			 __io_address(REALVIEW_EB11MP_GIC_CPU_BASE));
339

340
#ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB
341
		/* board GIC, secondary */
342
		gic_init(1, 96, __io_address(REALVIEW_EB_GIC_DIST_BASE),
343
			 __io_address(REALVIEW_EB_GIC_CPU_BASE));
344
		gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1);
345
#endif
346 347
	} else {
		/* board GIC, primary */
348
		gic_init(0, 29, __io_address(REALVIEW_EB_GIC_DIST_BASE),
349
			 __io_address(REALVIEW_EB_GIC_CPU_BASE));
350
	}
351 352
}

353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
/*
 * Fix up the IRQ numbers for the RealView EB/ARM11MPCore tile
 */
static void realview_eb11mp_fixup(void)
{
	/* AMBA devices */
	dmac_device.irq[0]	= IRQ_EB11MP_DMA;
	uart0_device.irq[0]	= IRQ_EB11MP_UART0;
	uart1_device.irq[0]	= IRQ_EB11MP_UART1;
	uart2_device.irq[0]	= IRQ_EB11MP_UART2;
	uart3_device.irq[0]	= IRQ_EB11MP_UART3;
	clcd_device.irq[0]	= IRQ_EB11MP_CLCD;
	wdog_device.irq[0]	= IRQ_EB11MP_WDOG;
	gpio0_device.irq[0]	= IRQ_EB11MP_GPIO0;
	gpio1_device.irq[0]	= IRQ_EB11MP_GPIO1;
	gpio2_device.irq[0]	= IRQ_EB11MP_GPIO2;
	rtc_device.irq[0]	= IRQ_EB11MP_RTC;
	sci0_device.irq[0]	= IRQ_EB11MP_SCI;
	ssp0_device.irq[0]	= IRQ_EB11MP_SSP;
	aaci_device.irq[0]	= IRQ_EB11MP_AACI;
	mmc0_device.irq[0]	= IRQ_EB11MP_MMCI0A;
	mmc0_device.irq[1]	= IRQ_EB11MP_MMCI0B;
	kmi0_device.irq[0]	= IRQ_EB11MP_KMI0;
	kmi1_device.irq[0]	= IRQ_EB11MP_KMI1;

	/* platform devices */
379 380
	realview_eb_eth_resources[1].start	= IRQ_EB11MP_ETH;
	realview_eb_eth_resources[1].end	= IRQ_EB11MP_ETH;
381 382
	realview_eb_isp1761_resources[1].start	= IRQ_EB11MP_USB;
	realview_eb_isp1761_resources[1].end	= IRQ_EB11MP_USB;
383 384
}

385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
#ifdef CONFIG_HAVE_ARM_TWD
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
			      REALVIEW_EB11MP_TWD_BASE,
			      IRQ_LOCALTIMER);

static void __init realview_eb_twd_init(void)
{
	if (core_tile_eb11mp() || core_tile_a9mp()) {
		int err = twd_local_timer_register(&twd_local_timer);
		if (err)
			pr_err("twd_local_timer_register failed %d\n", err);
	}
}
#else
#define realview_eb_twd_init()	do { } while(0)
#endif

402 403 404 405
static void __init realview_eb_timer_init(void)
{
	unsigned int timer_irq;

406 407 408 409 410
	timer0_va_base = __io_address(REALVIEW_EB_TIMER0_1_BASE);
	timer1_va_base = __io_address(REALVIEW_EB_TIMER0_1_BASE) + 0x20;
	timer2_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE);
	timer3_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE) + 0x20;

411
	if (core_tile_eb11mp() || core_tile_a9mp())
412
		timer_irq = IRQ_EB11MP_TIMER0_1;
413
	else
414 415 416
		timer_irq = IRQ_EB_TIMER0_1;

	realview_timer_init(timer_irq);
417
	realview_eb_twd_init();
418 419 420 421 422 423
}

static struct sys_timer realview_eb_timer = {
	.init		= realview_eb_timer_init,
};

424
static void realview_eb_restart(char mode, const char *cmd)
425 426 427 428 429 430 431 432 433 434 435
{
	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);

	/*
	 * To reset, we hit the on-board reset register
	 * in the system FPGA
	 */
	__raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
	if (core_tile_eb11mp())
		__raw_writel(0x0008, reset_ctrl);
436
	dsb();
437 438
}

439 440 441 442
static void __init realview_eb_init(void)
{
	int i;

443
	if (core_tile_eb11mp() || core_tile_a9mp()) {
444 445
		realview_eb11mp_fixup();

446
#ifdef CONFIG_CACHE_L2X0
447 448 449
		/* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
		 * Bits:  .... ...0 0111 1001 0000 .... .... .... */
		l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
450
#endif
451
		platform_device_register(&pmu_device);
452
	}
453

454
	realview_flash_register(&realview_eb_flash_resource, 1);
455
	platform_device_register(&realview_i2c_device);
456
	platform_device_register(&char_lcd_device);
457
	eth_device_register();
458
	realview_usb_register(realview_eb_isp1761_resources);
459 460 461 462 463 464 465 466 467

	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
		struct amba_device *d = amba_devs[i];
		amba_device_register(d, &iomem_resource);
	}
}

MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
468
	.atag_offset	= 0x100,
469
	.fixup		= realview_fixup,
470
	.map_io		= realview_eb_map_io,
471
	.init_early	= realview_init_early,
472
	.init_irq	= gic_init_irq,
473
	.timer		= &realview_eb_timer,
474
	.handle_irq	= gic_handle_irq,
475
	.init_machine	= realview_eb_init,
476 477 478
#ifdef CONFIG_ZONE_DMA
	.dma_zone_size	= SZ_256M,
#endif
479
	.restart	= realview_eb_restart,
480
MACHINE_END