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