realview_pba8.c revision c5a0adb51002e51a4254cb7f0ab7190d41d8b930
1/*
2 *  linux/arch/arm/mach-realview/realview_pba8.c
3 *
4 *  Copyright (C) 2008 ARM Limited
5 *  Copyright (C) 2000 Deep Blue Solutions Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 */
21
22#include <linux/init.h>
23#include <linux/platform_device.h>
24#include <linux/sysdev.h>
25#include <linux/amba/bus.h>
26#include <linux/amba/pl061.h>
27#include <linux/amba/mmci.h>
28#include <linux/io.h>
29
30#include <asm/irq.h>
31#include <asm/leds.h>
32#include <asm/mach-types.h>
33#include <asm/hardware/gic.h>
34
35#include <asm/mach/arch.h>
36#include <asm/mach/map.h>
37#include <asm/mach/time.h>
38
39#include <mach/hardware.h>
40#include <mach/board-pba8.h>
41#include <mach/irqs.h>
42
43#include "core.h"
44#include "clock.h"
45
46static struct map_desc realview_pba8_io_desc[] __initdata = {
47	{
48		.virtual	= IO_ADDRESS(REALVIEW_SYS_BASE),
49		.pfn		= __phys_to_pfn(REALVIEW_SYS_BASE),
50		.length		= SZ_4K,
51		.type		= MT_DEVICE,
52	}, {
53		.virtual	= IO_ADDRESS(REALVIEW_PBA8_GIC_CPU_BASE),
54		.pfn		= __phys_to_pfn(REALVIEW_PBA8_GIC_CPU_BASE),
55		.length		= SZ_4K,
56		.type		= MT_DEVICE,
57	}, {
58		.virtual	= IO_ADDRESS(REALVIEW_PBA8_GIC_DIST_BASE),
59		.pfn		= __phys_to_pfn(REALVIEW_PBA8_GIC_DIST_BASE),
60		.length		= SZ_4K,
61		.type		= MT_DEVICE,
62	}, {
63		.virtual	= IO_ADDRESS(REALVIEW_SCTL_BASE),
64		.pfn		= __phys_to_pfn(REALVIEW_SCTL_BASE),
65		.length		= SZ_4K,
66		.type		= MT_DEVICE,
67	}, {
68		.virtual	= IO_ADDRESS(REALVIEW_PBA8_TIMER0_1_BASE),
69		.pfn		= __phys_to_pfn(REALVIEW_PBA8_TIMER0_1_BASE),
70		.length		= SZ_4K,
71		.type		= MT_DEVICE,
72	}, {
73		.virtual	= IO_ADDRESS(REALVIEW_PBA8_TIMER2_3_BASE),
74		.pfn		= __phys_to_pfn(REALVIEW_PBA8_TIMER2_3_BASE),
75		.length		= SZ_4K,
76		.type		= MT_DEVICE,
77	},
78#ifdef CONFIG_PCI
79	{
80		.virtual	= PCIX_UNIT_BASE,
81		.pfn		= __phys_to_pfn(REALVIEW_PBA8_PCI_BASE),
82		.length		= REALVIEW_PBA8_PCI_BASE_SIZE,
83		.type		= MT_DEVICE
84	},
85#endif
86#ifdef CONFIG_DEBUG_LL
87	{
88		.virtual	= IO_ADDRESS(REALVIEW_PBA8_UART0_BASE),
89		.pfn		= __phys_to_pfn(REALVIEW_PBA8_UART0_BASE),
90		.length		= SZ_4K,
91		.type		= MT_DEVICE,
92	},
93#endif
94};
95
96static void __init realview_pba8_map_io(void)
97{
98	iotable_init(realview_pba8_io_desc, ARRAY_SIZE(realview_pba8_io_desc));
99}
100
101static struct pl061_platform_data gpio0_plat_data = {
102	.gpio_base	= 0,
103	.irq_base	= -1,
104};
105
106static struct pl061_platform_data gpio1_plat_data = {
107	.gpio_base	= 8,
108	.irq_base	= -1,
109};
110
111static struct pl061_platform_data gpio2_plat_data = {
112	.gpio_base	= 16,
113	.irq_base	= -1,
114};
115
116/*
117 * RealView PBA8Core AMBA devices
118 */
119
120#define GPIO2_IRQ		{ IRQ_PBA8_GPIO2, NO_IRQ }
121#define GPIO2_DMA		{ 0, 0 }
122#define GPIO3_IRQ		{ IRQ_PBA8_GPIO3, NO_IRQ }
123#define GPIO3_DMA		{ 0, 0 }
124#define AACI_IRQ		{ IRQ_PBA8_AACI, NO_IRQ }
125#define AACI_DMA		{ 0x80, 0x81 }
126#define MMCI0_IRQ		{ IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
127#define MMCI0_DMA		{ 0x84, 0 }
128#define KMI0_IRQ		{ IRQ_PBA8_KMI0, NO_IRQ }
129#define KMI0_DMA		{ 0, 0 }
130#define KMI1_IRQ		{ IRQ_PBA8_KMI1, NO_IRQ }
131#define KMI1_DMA		{ 0, 0 }
132#define PBA8_SMC_IRQ		{ NO_IRQ, NO_IRQ }
133#define PBA8_SMC_DMA		{ 0, 0 }
134#define MPMC_IRQ		{ NO_IRQ, NO_IRQ }
135#define MPMC_DMA		{ 0, 0 }
136#define PBA8_CLCD_IRQ		{ IRQ_PBA8_CLCD, NO_IRQ }
137#define PBA8_CLCD_DMA		{ 0, 0 }
138#define DMAC_IRQ		{ IRQ_PBA8_DMAC, NO_IRQ }
139#define DMAC_DMA		{ 0, 0 }
140#define SCTL_IRQ		{ NO_IRQ, NO_IRQ }
141#define SCTL_DMA		{ 0, 0 }
142#define PBA8_WATCHDOG_IRQ	{ IRQ_PBA8_WATCHDOG, NO_IRQ }
143#define PBA8_WATCHDOG_DMA	{ 0, 0 }
144#define PBA8_GPIO0_IRQ		{ IRQ_PBA8_GPIO0, NO_IRQ }
145#define PBA8_GPIO0_DMA		{ 0, 0 }
146#define GPIO1_IRQ		{ IRQ_PBA8_GPIO1, NO_IRQ }
147#define GPIO1_DMA		{ 0, 0 }
148#define PBA8_RTC_IRQ		{ IRQ_PBA8_RTC, NO_IRQ }
149#define PBA8_RTC_DMA		{ 0, 0 }
150#define SCI_IRQ			{ IRQ_PBA8_SCI, NO_IRQ }
151#define SCI_DMA			{ 7, 6 }
152#define PBA8_UART0_IRQ		{ IRQ_PBA8_UART0, NO_IRQ }
153#define PBA8_UART0_DMA		{ 15, 14 }
154#define PBA8_UART1_IRQ		{ IRQ_PBA8_UART1, NO_IRQ }
155#define PBA8_UART1_DMA		{ 13, 12 }
156#define PBA8_UART2_IRQ		{ IRQ_PBA8_UART2, NO_IRQ }
157#define PBA8_UART2_DMA		{ 11, 10 }
158#define PBA8_UART3_IRQ		{ IRQ_PBA8_UART3, NO_IRQ }
159#define PBA8_UART3_DMA		{ 0x86, 0x87 }
160#define PBA8_SSP_IRQ		{ IRQ_PBA8_SSP, NO_IRQ }
161#define PBA8_SSP_DMA		{ 9, 8 }
162
163/* FPGA Primecells */
164AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
165AMBA_DEVICE(mmc0,	"fpga:mmc0",	MMCI0,		&realview_mmc0_plat_data);
166AMBA_DEVICE(kmi0,	"fpga:kmi0",	KMI0,		NULL);
167AMBA_DEVICE(kmi1,	"fpga:kmi1",	KMI1,		NULL);
168AMBA_DEVICE(uart3,	"fpga:uart3",	PBA8_UART3,	NULL);
169
170/* DevChip Primecells */
171AMBA_DEVICE(smc,	"dev:smc",	PBA8_SMC,	NULL);
172AMBA_DEVICE(sctl,	"dev:sctl",	SCTL,		NULL);
173AMBA_DEVICE(wdog,	"dev:wdog",	PBA8_WATCHDOG, NULL);
174AMBA_DEVICE(gpio0,	"dev:gpio0",	PBA8_GPIO0,	&gpio0_plat_data);
175AMBA_DEVICE(gpio1,	"dev:gpio1",	GPIO1,		&gpio1_plat_data);
176AMBA_DEVICE(gpio2,	"dev:gpio2",	GPIO2,		&gpio2_plat_data);
177AMBA_DEVICE(rtc,	"dev:rtc",	PBA8_RTC,	NULL);
178AMBA_DEVICE(sci0,	"dev:sci0",	SCI,		NULL);
179AMBA_DEVICE(uart0,	"dev:uart0",	PBA8_UART0,	NULL);
180AMBA_DEVICE(uart1,	"dev:uart1",	PBA8_UART1,	NULL);
181AMBA_DEVICE(uart2,	"dev:uart2",	PBA8_UART2,	NULL);
182AMBA_DEVICE(ssp0,	"dev:ssp0",	PBA8_SSP,	NULL);
183
184/* Primecells on the NEC ISSP chip */
185AMBA_DEVICE(clcd,	"issp:clcd",	PBA8_CLCD,	&clcd_plat_data);
186AMBA_DEVICE(dmac,	"issp:dmac",	DMAC,		NULL);
187
188static struct amba_device *amba_devs[] __initdata = {
189	&dmac_device,
190	&uart0_device,
191	&uart1_device,
192	&uart2_device,
193	&uart3_device,
194	&smc_device,
195	&clcd_device,
196	&sctl_device,
197	&wdog_device,
198	&gpio0_device,
199	&gpio1_device,
200	&gpio2_device,
201	&rtc_device,
202	&sci0_device,
203	&ssp0_device,
204	&aaci_device,
205	&mmc0_device,
206	&kmi0_device,
207	&kmi1_device,
208};
209
210/*
211 * RealView PB-A8 platform devices
212 */
213static struct resource realview_pba8_flash_resource[] = {
214	[0] = {
215		.start		= REALVIEW_PBA8_FLASH0_BASE,
216		.end		= REALVIEW_PBA8_FLASH0_BASE + REALVIEW_PBA8_FLASH0_SIZE - 1,
217		.flags		= IORESOURCE_MEM,
218	},
219	[1] = {
220		.start		= REALVIEW_PBA8_FLASH1_BASE,
221		.end		= REALVIEW_PBA8_FLASH1_BASE + REALVIEW_PBA8_FLASH1_SIZE - 1,
222		.flags		= IORESOURCE_MEM,
223	},
224};
225
226static struct resource realview_pba8_smsc911x_resources[] = {
227	[0] = {
228		.start		= REALVIEW_PBA8_ETH_BASE,
229		.end		= REALVIEW_PBA8_ETH_BASE + SZ_64K - 1,
230		.flags		= IORESOURCE_MEM,
231	},
232	[1] = {
233		.start		= IRQ_PBA8_ETH,
234		.end		= IRQ_PBA8_ETH,
235		.flags		= IORESOURCE_IRQ,
236	},
237};
238
239static struct resource realview_pba8_isp1761_resources[] = {
240	[0] = {
241		.start		= REALVIEW_PBA8_USB_BASE,
242		.end		= REALVIEW_PBA8_USB_BASE + SZ_128K - 1,
243		.flags		= IORESOURCE_MEM,
244	},
245	[1] = {
246		.start		= IRQ_PBA8_USB,
247		.end		= IRQ_PBA8_USB,
248		.flags		= IORESOURCE_IRQ,
249	},
250};
251
252static void __init gic_init_irq(void)
253{
254	/* ARM PB-A8 on-board GIC */
255	gic_cpu_base_addr = __io_address(REALVIEW_PBA8_GIC_CPU_BASE);
256	gic_dist_init(0, __io_address(REALVIEW_PBA8_GIC_DIST_BASE), IRQ_PBA8_GIC_START);
257	gic_cpu_init(0, __io_address(REALVIEW_PBA8_GIC_CPU_BASE));
258}
259
260static void __init realview_pba8_timer_init(void)
261{
262	timer0_va_base = __io_address(REALVIEW_PBA8_TIMER0_1_BASE);
263	timer1_va_base = __io_address(REALVIEW_PBA8_TIMER0_1_BASE) + 0x20;
264	timer2_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE);
265	timer3_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE) + 0x20;
266
267	realview_timer_init(IRQ_PBA8_TIMER0_1);
268}
269
270static struct sys_timer realview_pba8_timer = {
271	.init		= realview_pba8_timer_init,
272};
273
274static void realview_pba8_reset(char mode)
275{
276	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
277	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
278
279	/*
280	 * To reset, we hit the on-board reset register
281	 * in the system FPGA
282	 */
283	__raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
284	__raw_writel(0x0000, reset_ctrl);
285	__raw_writel(0x0004, reset_ctrl);
286}
287
288static void __init realview_pba8_init(void)
289{
290	int i;
291
292	realview_flash_register(realview_pba8_flash_resource,
293				ARRAY_SIZE(realview_pba8_flash_resource));
294	realview_eth_register(NULL, realview_pba8_smsc911x_resources);
295	platform_device_register(&realview_i2c_device);
296	platform_device_register(&realview_cf_device);
297	realview_usb_register(realview_pba8_isp1761_resources);
298
299	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
300		struct amba_device *d = amba_devs[i];
301		amba_device_register(d, &iomem_resource);
302	}
303
304#ifdef CONFIG_LEDS
305	leds_event = realview_leds_event;
306#endif
307	realview_reset = realview_pba8_reset;
308}
309
310MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
311	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
312	.phys_io	= REALVIEW_PBA8_UART0_BASE,
313	.io_pg_offst	= (IO_ADDRESS(REALVIEW_PBA8_UART0_BASE) >> 18) & 0xfffc,
314	.boot_params	= PHYS_OFFSET + 0x00000100,
315	.fixup		= realview_fixup,
316	.map_io		= realview_pba8_map_io,
317	.init_irq	= gic_init_irq,
318	.timer		= &realview_pba8_timer,
319	.init_machine	= realview_pba8_init,
320MACHINE_END
321