1/* 2 * arch/arm/mach-realview/realview_pbx.c 3 * 4 * Copyright (C) 2009 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 version 2 as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21#include <linux/init.h> 22#include <linux/platform_device.h> 23#include <linux/device.h> 24#include <linux/amba/bus.h> 25#include <linux/amba/pl061.h> 26#include <linux/amba/mmci.h> 27#include <linux/amba/pl022.h> 28#include <linux/io.h> 29#include <linux/irqchip/arm-gic.h> 30#include <linux/platform_data/clk-realview.h> 31#include <linux/reboot.h> 32#include <linux/memblock.h> 33 34#include <asm/irq.h> 35#include <asm/mach-types.h> 36#include <asm/smp_twd.h> 37#include <asm/pgtable.h> 38#include <asm/hardware/cache-l2x0.h> 39 40#include <asm/mach/arch.h> 41#include <asm/mach/map.h> 42#include <asm/mach/time.h> 43 44#include <mach/hardware.h> 45#include <mach/board-pbx.h> 46#include <mach/irqs.h> 47 48#include "core.h" 49 50static struct map_desc realview_pbx_io_desc[] __initdata = { 51 { 52 .virtual = IO_ADDRESS(REALVIEW_SYS_BASE), 53 .pfn = __phys_to_pfn(REALVIEW_SYS_BASE), 54 .length = SZ_4K, 55 .type = MT_DEVICE, 56 }, { 57 .virtual = IO_ADDRESS(REALVIEW_PBX_GIC_CPU_BASE), 58 .pfn = __phys_to_pfn(REALVIEW_PBX_GIC_CPU_BASE), 59 .length = SZ_4K, 60 .type = MT_DEVICE, 61 }, { 62 .virtual = IO_ADDRESS(REALVIEW_PBX_GIC_DIST_BASE), 63 .pfn = __phys_to_pfn(REALVIEW_PBX_GIC_DIST_BASE), 64 .length = SZ_4K, 65 .type = MT_DEVICE, 66 }, { 67 .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE), 68 .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE), 69 .length = SZ_4K, 70 .type = MT_DEVICE, 71 }, { 72 .virtual = IO_ADDRESS(REALVIEW_PBX_TIMER0_1_BASE), 73 .pfn = __phys_to_pfn(REALVIEW_PBX_TIMER0_1_BASE), 74 .length = SZ_4K, 75 .type = MT_DEVICE, 76 }, { 77 .virtual = IO_ADDRESS(REALVIEW_PBX_TIMER2_3_BASE), 78 .pfn = __phys_to_pfn(REALVIEW_PBX_TIMER2_3_BASE), 79 .length = SZ_4K, 80 .type = MT_DEVICE, 81 }, 82#ifdef CONFIG_PCI 83 { 84 .virtual = PCIX_UNIT_BASE, 85 .pfn = __phys_to_pfn(REALVIEW_PBX_PCI_BASE), 86 .length = REALVIEW_PBX_PCI_BASE_SIZE, 87 .type = MT_DEVICE, 88 }, 89#endif 90#ifdef CONFIG_DEBUG_LL 91 { 92 .virtual = IO_ADDRESS(REALVIEW_PBX_UART0_BASE), 93 .pfn = __phys_to_pfn(REALVIEW_PBX_UART0_BASE), 94 .length = SZ_4K, 95 .type = MT_DEVICE, 96 }, 97#endif 98}; 99 100static struct map_desc realview_local_io_desc[] __initdata = { 101 { 102 .virtual = IO_ADDRESS(REALVIEW_PBX_TILE_SCU_BASE), 103 .pfn = __phys_to_pfn(REALVIEW_PBX_TILE_SCU_BASE), 104 .length = SZ_4K, 105 .type = MT_DEVICE, 106 }, { 107 .virtual = IO_ADDRESS(REALVIEW_PBX_TILE_GIC_DIST_BASE), 108 .pfn = __phys_to_pfn(REALVIEW_PBX_TILE_GIC_DIST_BASE), 109 .length = SZ_4K, 110 .type = MT_DEVICE, 111 }, { 112 .virtual = IO_ADDRESS(REALVIEW_PBX_TILE_L220_BASE), 113 .pfn = __phys_to_pfn(REALVIEW_PBX_TILE_L220_BASE), 114 .length = SZ_8K, 115 .type = MT_DEVICE, 116 } 117}; 118 119static void __init realview_pbx_map_io(void) 120{ 121 iotable_init(realview_pbx_io_desc, ARRAY_SIZE(realview_pbx_io_desc)); 122 if (core_tile_pbx11mp() || core_tile_pbxa9mp()) 123 iotable_init(realview_local_io_desc, ARRAY_SIZE(realview_local_io_desc)); 124} 125 126static struct pl061_platform_data gpio0_plat_data = { 127 .gpio_base = 0, 128}; 129 130static struct pl061_platform_data gpio1_plat_data = { 131 .gpio_base = 8, 132}; 133 134static struct pl061_platform_data gpio2_plat_data = { 135 .gpio_base = 16, 136}; 137 138static struct pl022_ssp_controller ssp0_plat_data = { 139 .bus_id = 0, 140 .enable_dma = 0, 141 .num_chipselect = 1, 142}; 143 144/* 145 * RealView PBXCore AMBA devices 146 */ 147 148#define GPIO2_IRQ { IRQ_PBX_GPIO2 } 149#define GPIO3_IRQ { IRQ_PBX_GPIO3 } 150#define AACI_IRQ { IRQ_PBX_AACI } 151#define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B } 152#define KMI0_IRQ { IRQ_PBX_KMI0 } 153#define KMI1_IRQ { IRQ_PBX_KMI1 } 154#define PBX_SMC_IRQ { } 155#define MPMC_IRQ { } 156#define PBX_CLCD_IRQ { IRQ_PBX_CLCD } 157#define DMAC_IRQ { IRQ_PBX_DMAC } 158#define SCTL_IRQ { } 159#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG } 160#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0 } 161#define GPIO1_IRQ { IRQ_PBX_GPIO1 } 162#define PBX_RTC_IRQ { IRQ_PBX_RTC } 163#define SCI_IRQ { IRQ_PBX_SCI } 164#define PBX_UART0_IRQ { IRQ_PBX_UART0 } 165#define PBX_UART1_IRQ { IRQ_PBX_UART1 } 166#define PBX_UART2_IRQ { IRQ_PBX_UART2 } 167#define PBX_UART3_IRQ { IRQ_PBX_UART3 } 168#define PBX_SSP_IRQ { IRQ_PBX_SSP } 169 170/* FPGA Primecells */ 171APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); 172APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); 173APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); 174APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); 175APB_DEVICE(uart3, "fpga:uart3", PBX_UART3, NULL); 176 177/* DevChip Primecells */ 178AHB_DEVICE(smc, "dev:smc", PBX_SMC, NULL); 179AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); 180APB_DEVICE(wdog, "dev:wdog", PBX_WATCHDOG, NULL); 181APB_DEVICE(gpio0, "dev:gpio0", PBX_GPIO0, &gpio0_plat_data); 182APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); 183APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); 184APB_DEVICE(rtc, "dev:rtc", PBX_RTC, NULL); 185APB_DEVICE(sci0, "dev:sci0", SCI, NULL); 186APB_DEVICE(uart0, "dev:uart0", PBX_UART0, NULL); 187APB_DEVICE(uart1, "dev:uart1", PBX_UART1, NULL); 188APB_DEVICE(uart2, "dev:uart2", PBX_UART2, NULL); 189APB_DEVICE(ssp0, "dev:ssp0", PBX_SSP, &ssp0_plat_data); 190 191/* Primecells on the NEC ISSP chip */ 192AHB_DEVICE(clcd, "issp:clcd", PBX_CLCD, &clcd_plat_data); 193AHB_DEVICE(dmac, "issp:dmac", DMAC, NULL); 194 195static struct amba_device *amba_devs[] __initdata = { 196 &dmac_device, 197 &uart0_device, 198 &uart1_device, 199 &uart2_device, 200 &uart3_device, 201 &smc_device, 202 &clcd_device, 203 &sctl_device, 204 &wdog_device, 205 &gpio0_device, 206 &gpio1_device, 207 &gpio2_device, 208 &rtc_device, 209 &sci0_device, 210 &ssp0_device, 211 &aaci_device, 212 &mmc0_device, 213 &kmi0_device, 214 &kmi1_device, 215}; 216 217/* 218 * RealView PB-X platform devices 219 */ 220static struct resource realview_pbx_flash_resources[] = { 221 [0] = { 222 .start = REALVIEW_PBX_FLASH0_BASE, 223 .end = REALVIEW_PBX_FLASH0_BASE + REALVIEW_PBX_FLASH0_SIZE - 1, 224 .flags = IORESOURCE_MEM, 225 }, 226 [1] = { 227 .start = REALVIEW_PBX_FLASH1_BASE, 228 .end = REALVIEW_PBX_FLASH1_BASE + REALVIEW_PBX_FLASH1_SIZE - 1, 229 .flags = IORESOURCE_MEM, 230 }, 231}; 232 233static struct resource realview_pbx_smsc911x_resources[] = { 234 [0] = { 235 .start = REALVIEW_PBX_ETH_BASE, 236 .end = REALVIEW_PBX_ETH_BASE + SZ_64K - 1, 237 .flags = IORESOURCE_MEM, 238 }, 239 [1] = { 240 .start = IRQ_PBX_ETH, 241 .end = IRQ_PBX_ETH, 242 .flags = IORESOURCE_IRQ, 243 }, 244}; 245 246static struct resource realview_pbx_isp1761_resources[] = { 247 [0] = { 248 .start = REALVIEW_PBX_USB_BASE, 249 .end = REALVIEW_PBX_USB_BASE + SZ_128K - 1, 250 .flags = IORESOURCE_MEM, 251 }, 252 [1] = { 253 .start = IRQ_PBX_USB, 254 .end = IRQ_PBX_USB, 255 .flags = IORESOURCE_IRQ, 256 }, 257}; 258 259static struct resource pmu_resources[] = { 260 [0] = { 261 .start = IRQ_PBX_PMU_CPU0, 262 .end = IRQ_PBX_PMU_CPU0, 263 .flags = IORESOURCE_IRQ, 264 }, 265 [1] = { 266 .start = IRQ_PBX_PMU_CPU1, 267 .end = IRQ_PBX_PMU_CPU1, 268 .flags = IORESOURCE_IRQ, 269 }, 270 [2] = { 271 .start = IRQ_PBX_PMU_CPU2, 272 .end = IRQ_PBX_PMU_CPU2, 273 .flags = IORESOURCE_IRQ, 274 }, 275 [3] = { 276 .start = IRQ_PBX_PMU_CPU3, 277 .end = IRQ_PBX_PMU_CPU3, 278 .flags = IORESOURCE_IRQ, 279 }, 280}; 281 282static struct platform_device pmu_device = { 283 .name = "arm-pmu", 284 .id = -1, 285 .num_resources = ARRAY_SIZE(pmu_resources), 286 .resource = pmu_resources, 287}; 288 289static void __init gic_init_irq(void) 290{ 291 /* ARM PBX on-board GIC */ 292 if (core_tile_pbx11mp() || core_tile_pbxa9mp()) { 293 gic_init(0, 29, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE), 294 __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE)); 295 } else { 296 gic_init(0, IRQ_PBX_GIC_START, 297 __io_address(REALVIEW_PBX_GIC_DIST_BASE), 298 __io_address(REALVIEW_PBX_GIC_CPU_BASE)); 299 } 300} 301 302#ifdef CONFIG_HAVE_ARM_TWD 303static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 304 REALVIEW_PBX_TILE_TWD_BASE, 305 IRQ_LOCALTIMER); 306 307static void __init realview_pbx_twd_init(void) 308{ 309 int err = twd_local_timer_register(&twd_local_timer); 310 if (err) 311 pr_err("twd_local_timer_register failed %d\n", err); 312} 313#else 314#define realview_pbx_twd_init() do { } while(0) 315#endif 316 317static void __init realview_pbx_timer_init(void) 318{ 319 timer0_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE); 320 timer1_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE) + 0x20; 321 timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE); 322 timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20; 323 324 realview_clk_init(__io_address(REALVIEW_SYS_BASE), false); 325 realview_timer_init(IRQ_PBX_TIMER0_1); 326 realview_pbx_twd_init(); 327} 328 329static void realview_pbx_fixup(struct tag *tags, char **from) 330{ 331#ifdef CONFIG_SPARSEMEM 332 /* 333 * Memory configuration with SPARSEMEM enabled on RealView PBX (see 334 * asm/mach/memory.h for more information). 335 */ 336 337 memblock_add(0, SZ_256M); 338 memblock_add(0x20000000, SZ_512M); 339 memblock_add(0x80000000, SZ_256M); 340#else 341 realview_fixup(tags, from); 342#endif 343} 344 345static void realview_pbx_restart(enum reboot_mode mode, const char *cmd) 346{ 347 void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); 348 void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); 349 350 /* 351 * To reset, we hit the on-board reset register 352 * in the system FPGA 353 */ 354 __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); 355 __raw_writel(0x00F0, reset_ctrl); 356 __raw_writel(0x00F4, reset_ctrl); 357 dsb(); 358} 359 360static void __init realview_pbx_init(void) 361{ 362 int i; 363 364#ifdef CONFIG_CACHE_L2X0 365 if (core_tile_pbxa9mp()) { 366 void __iomem *l2x0_base = 367 __io_address(REALVIEW_PBX_TILE_L220_BASE); 368 369 /* set RAM latencies to 1 cycle for eASIC */ 370 writel(0, l2x0_base + L310_TAG_LATENCY_CTRL); 371 writel(0, l2x0_base + L310_DATA_LATENCY_CTRL); 372 373 /* 16KB way size, 8-way associativity, parity disabled 374 * Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */ 375 l2x0_init(l2x0_base, 0x02520000, 0xc0000fff); 376 platform_device_register(&pmu_device); 377 } 378#endif 379 380 realview_flash_register(realview_pbx_flash_resources, 381 ARRAY_SIZE(realview_pbx_flash_resources)); 382 realview_eth_register(NULL, realview_pbx_smsc911x_resources); 383 platform_device_register(&realview_i2c_device); 384 platform_device_register(&realview_cf_device); 385 platform_device_register(&realview_leds_device); 386 realview_usb_register(realview_pbx_isp1761_resources); 387 388 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { 389 struct amba_device *d = amba_devs[i]; 390 amba_device_register(d, &iomem_resource); 391 } 392} 393 394MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX") 395 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ 396 .atag_offset = 0x100, 397 .smp = smp_ops(realview_smp_ops), 398 .fixup = realview_pbx_fixup, 399 .map_io = realview_pbx_map_io, 400 .init_early = realview_init_early, 401 .init_irq = gic_init_irq, 402 .init_time = realview_pbx_timer_init, 403 .init_machine = realview_pbx_init, 404#ifdef CONFIG_ZONE_DMA 405 .dma_zone_size = SZ_256M, 406#endif 407 .restart = realview_pbx_restart, 408MACHINE_END 409