diff options
| -rw-r--r-- | arch/arm/mach-ux500/Kconfig | 15 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/Makefile | 8 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/board-mop500.c | 158 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/cpu-u8500.c | 64 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/headsmp.S | 38 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/include/mach/debug-macro.S | 19 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/include/mach/entry-macro.S | 89 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/include/mach/memory.h | 18 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/include/mach/setup.h | 23 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/include/mach/smp.h | 32 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/include/mach/system.h | 25 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/include/mach/timex.h | 6 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/include/mach/uncompress.h | 58 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/include/mach/vmalloc.h | 18 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/localtimer.c | 28 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/platsmp.c | 177 |
16 files changed, 776 insertions, 0 deletions
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig new file mode 100644 index 000000000000..03625d744857 --- /dev/null +++ b/arch/arm/mach-ux500/Kconfig | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | menu "ST-Ericsson platform type" | ||
| 2 | depends on ARCH_U8500 | ||
| 3 | |||
| 4 | comment "ST-Ericsson Multicore Mobile Platforms" | ||
| 5 | |||
| 6 | config MACH_U8500_MOP | ||
| 7 | bool "U8500 Early Development platform" | ||
| 8 | default y | ||
| 9 | select ARM_GIC | ||
| 10 | select HAS_MTU | ||
| 11 | help | ||
| 12 | Include support for mop500 development platform | ||
| 13 | based on U8500 architecture. The platform is based | ||
| 14 | on early drop silicon version of 8500. | ||
| 15 | endmenu | ||
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile new file mode 100644 index 000000000000..95e6e24c0042 --- /dev/null +++ b/arch/arm/mach-ux500/Makefile | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the linux kernel, U8500 machine. | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-y := clock.o | ||
| 6 | obj-$(CONFIG_ARCH_U8500) += cpu-u8500.o | ||
| 7 | obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o | ||
| 8 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o | ||
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c new file mode 100644 index 000000000000..aa5afbcc90f9 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500.c | |||
| @@ -0,0 +1,158 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008-2009 ST-Ericsson | ||
| 3 | * | ||
| 4 | * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2, as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/io.h> | ||
| 16 | #include <linux/amba/bus.h> | ||
| 17 | #include <linux/amba/pl022.h> | ||
| 18 | #include <linux/spi/spi.h> | ||
| 19 | |||
| 20 | #include <asm/localtimer.h> | ||
| 21 | #include <asm/mach-types.h> | ||
| 22 | #include <asm/mach/arch.h> | ||
| 23 | |||
| 24 | #include <plat/mtu.h> | ||
| 25 | |||
| 26 | #include <mach/hardware.h> | ||
| 27 | #include <mach/setup.h> | ||
| 28 | |||
| 29 | #define __MEM_4K_RESOURCE(x) \ | ||
| 30 | .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} | ||
| 31 | |||
| 32 | /* These are active devices on this board */ | ||
| 33 | static struct amba_device uart0_device = { | ||
| 34 | .dev = { .init_name = "uart0" }, | ||
| 35 | __MEM_4K_RESOURCE(U8500_UART0_BASE), | ||
| 36 | .irq = {IRQ_UART0, NO_IRQ}, | ||
| 37 | }; | ||
| 38 | |||
| 39 | static struct amba_device uart1_device = { | ||
| 40 | .dev = { .init_name = "uart1" }, | ||
| 41 | __MEM_4K_RESOURCE(U8500_UART1_BASE), | ||
| 42 | .irq = {IRQ_UART1, NO_IRQ}, | ||
| 43 | }; | ||
| 44 | |||
| 45 | static struct amba_device uart2_device = { | ||
| 46 | .dev = { .init_name = "uart2" }, | ||
| 47 | __MEM_4K_RESOURCE(U8500_UART2_BASE), | ||
| 48 | .irq = {IRQ_UART2, NO_IRQ}, | ||
| 49 | }; | ||
| 50 | |||
| 51 | static void ab4500_spi_cs_control(u32 command) | ||
| 52 | { | ||
| 53 | /* set the FRM signal, which is CS - TODO */ | ||
| 54 | } | ||
| 55 | |||
| 56 | struct pl022_config_chip ab4500_chip_info = { | ||
| 57 | .lbm = LOOPBACK_DISABLED, | ||
| 58 | .com_mode = INTERRUPT_TRANSFER, | ||
| 59 | .iface = SSP_INTERFACE_MOTOROLA_SPI, | ||
| 60 | /* we can act as master only */ | ||
| 61 | .hierarchy = SSP_MASTER, | ||
| 62 | .slave_tx_disable = 0, | ||
| 63 | .endian_rx = SSP_RX_MSB, | ||
| 64 | .endian_tx = SSP_TX_MSB, | ||
| 65 | .data_size = SSP_DATA_BITS_24, | ||
| 66 | .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, | ||
| 67 | .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, | ||
| 68 | .clk_phase = SSP_CLK_SECOND_EDGE, | ||
| 69 | .clk_pol = SSP_CLK_POL_IDLE_HIGH, | ||
| 70 | .cs_control = ab4500_spi_cs_control, | ||
| 71 | }; | ||
| 72 | |||
| 73 | static struct spi_board_info u8500_spi_devices[] = { | ||
| 74 | { | ||
| 75 | .modalias = "ab4500", | ||
| 76 | .controller_data = &ab4500_chip_info, | ||
| 77 | .max_speed_hz = 12000000, | ||
| 78 | .bus_num = 0, | ||
| 79 | .chip_select = 0, | ||
| 80 | .mode = SPI_MODE_0, | ||
| 81 | .irq = IRQ_AB4500, | ||
| 82 | }, | ||
| 83 | }; | ||
| 84 | |||
| 85 | static struct pl022_ssp_controller ssp0_platform_data = { | ||
| 86 | .bus_id = 0, | ||
| 87 | /* pl022 not yet supports dma */ | ||
| 88 | .enable_dma = 0, | ||
| 89 | /* on this platform, gpio 31,142,144,214 & | ||
| 90 | * 224 are connected as chip selects | ||
| 91 | */ | ||
| 92 | .num_chipselect = 5, | ||
| 93 | }; | ||
| 94 | |||
| 95 | static struct amba_device pl022_device = { | ||
| 96 | .dev = { | ||
| 97 | .coherent_dma_mask = ~0, | ||
| 98 | .init_name = "pl022", | ||
| 99 | .platform_data = &ssp0_platform_data, | ||
| 100 | }, | ||
| 101 | .res = { | ||
| 102 | .start = U8500_SSP0_BASE, | ||
| 103 | .end = U8500_SSP0_BASE + SZ_4K - 1, | ||
| 104 | .flags = IORESOURCE_MEM, | ||
| 105 | }, | ||
| 106 | .irq = {IRQ_SSP0, NO_IRQ }, | ||
| 107 | /* ST-Ericsson modified id */ | ||
| 108 | .periphid = SSP_PER_ID, | ||
| 109 | }; | ||
| 110 | |||
| 111 | static struct amba_device *amba_devs[] __initdata = { | ||
| 112 | &uart0_device, | ||
| 113 | &uart1_device, | ||
| 114 | &uart2_device, | ||
| 115 | &pl022_device, | ||
| 116 | }; | ||
| 117 | |||
| 118 | static void __init u8500_timer_init(void) | ||
| 119 | { | ||
| 120 | #ifdef CONFIG_LOCAL_TIMERS | ||
| 121 | /* Setup the local timer base */ | ||
| 122 | twd_base = __io_address(U8500_TWD_BASE); | ||
| 123 | #endif | ||
| 124 | /* Setup the MTU base */ | ||
| 125 | mtu_base = __io_address(U8500_MTU0_BASE); | ||
| 126 | |||
| 127 | nmdk_timer_init(); | ||
| 128 | } | ||
| 129 | |||
| 130 | static struct sys_timer u8500_timer = { | ||
| 131 | .init = u8500_timer_init, | ||
| 132 | }; | ||
| 133 | |||
| 134 | static void __init u8500_init_machine(void) | ||
| 135 | { | ||
| 136 | int i; | ||
| 137 | |||
| 138 | /* Register the active AMBA devices on this board */ | ||
| 139 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) | ||
| 140 | amba_device_register(amba_devs[i], &iomem_resource); | ||
| 141 | |||
| 142 | spi_register_board_info(u8500_spi_devices, | ||
| 143 | ARRAY_SIZE(u8500_spi_devices)); | ||
| 144 | |||
| 145 | u8500_init_devices(); | ||
| 146 | } | ||
| 147 | |||
| 148 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") | ||
| 149 | /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */ | ||
| 150 | .phys_io = U8500_UART2_BASE, | ||
| 151 | .io_pg_offst = (IO_ADDRESS(U8500_UART2_BASE) >> 18) & 0xfffc, | ||
| 152 | .boot_params = 0x100, | ||
| 153 | .map_io = u8500_map_io, | ||
| 154 | .init_irq = u8500_init_irq, | ||
| 155 | /* we re-use nomadik timer here */ | ||
| 156 | .timer = &u8500_timer, | ||
| 157 | .init_machine = u8500_init_machine, | ||
| 158 | MACHINE_END | ||
diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c new file mode 100644 index 000000000000..5f05e5850f71 --- /dev/null +++ b/arch/arm/mach-ux500/cpu-u8500.c | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008-2009 ST-Ericsson | ||
| 3 | * | ||
| 4 | * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2, as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | #include <linux/types.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/device.h> | ||
| 14 | #include <linux/amba/bus.h> | ||
| 15 | #include <linux/irq.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | |||
| 18 | #include <asm/hardware/gic.h> | ||
| 19 | #include <asm/mach/map.h> | ||
| 20 | #include <mach/hardware.h> | ||
| 21 | |||
| 22 | /* add any platform devices here - TODO */ | ||
| 23 | static struct platform_device *platform_devs[] __initdata = { | ||
| 24 | /* yet to be added, add i2c0, gpio.. */ | ||
| 25 | }; | ||
| 26 | |||
| 27 | #define __IO_DEV_DESC(x, sz) { \ | ||
| 28 | .virtual = IO_ADDRESS(x), \ | ||
| 29 | .pfn = __phys_to_pfn(x), \ | ||
| 30 | .length = sz, \ | ||
| 31 | .type = MT_DEVICE, \ | ||
| 32 | } | ||
| 33 | |||
| 34 | /* minimum static i/o mapping required to boot U8500 platforms */ | ||
| 35 | static struct map_desc u8500_io_desc[] __initdata = { | ||
| 36 | __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K), | ||
| 37 | __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K), | ||
| 38 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), | ||
| 39 | __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K), | ||
| 40 | __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), | ||
| 41 | __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), | ||
| 42 | }; | ||
| 43 | |||
| 44 | void __init u8500_map_io(void) | ||
| 45 | { | ||
| 46 | iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); | ||
| 47 | } | ||
| 48 | |||
| 49 | void __init u8500_init_irq(void) | ||
| 50 | { | ||
| 51 | gic_dist_init(0, __io_address(U8500_GIC_DIST_BASE), 29); | ||
| 52 | gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE)); | ||
| 53 | } | ||
| 54 | |||
| 55 | /* | ||
| 56 | * This function is called from the board init | ||
| 57 | */ | ||
| 58 | void __init u8500_init_devices(void) | ||
| 59 | { | ||
| 60 | /* Register the platform devices */ | ||
| 61 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | ||
| 62 | |||
| 63 | return ; | ||
| 64 | } | ||
diff --git a/arch/arm/mach-ux500/headsmp.S b/arch/arm/mach-ux500/headsmp.S new file mode 100644 index 000000000000..a6be2cdf2b2f --- /dev/null +++ b/arch/arm/mach-ux500/headsmp.S | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2009 ST-Ericsson | ||
| 3 | * This file is based ARM Realview platform | ||
| 4 | * Copyright (c) 2003 ARM Limited | ||
| 5 | * All Rights Reserved | ||
| 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 | #include <linux/linkage.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | |||
| 14 | __INIT | ||
| 15 | |||
| 16 | /* | ||
| 17 | * U8500 specific entry point for secondary CPUs. | ||
| 18 | */ | ||
| 19 | ENTRY(u8500_secondary_startup) | ||
| 20 | mrc p15, 0, r0, c0, c0, 5 | ||
| 21 | and r0, r0, #15 | ||
| 22 | adr r4, 1f | ||
| 23 | ldmia r4, {r5, r6} | ||
| 24 | sub r4, r4, r5 | ||
| 25 | add r6, r6, r4 | ||
| 26 | dsb | ||
| 27 | pen: ldr r7, [r6] | ||
| 28 | cmp r7, r0 | ||
| 29 | bne pen | ||
| 30 | |||
| 31 | /* | ||
| 32 | * we've been released from the holding pen: secondary_stack | ||
| 33 | * should now contain the SVC stack for this core | ||
| 34 | */ | ||
| 35 | b secondary_startup | ||
| 36 | |||
| 37 | 1: .long . | ||
| 38 | .long pen_release | ||
diff --git a/arch/arm/mach-ux500/include/mach/debug-macro.S b/arch/arm/mach-ux500/include/mach/debug-macro.S new file mode 100644 index 000000000000..8f21b6a95dce --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/debug-macro.S | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* | ||
| 2 | * Debugging macro include header | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 ST-Ericsson | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | .macro addruart,rx | ||
| 12 | mrc p15, 0, \rx, c1, c0 | ||
| 13 | tst \rx, #1 @MMU enabled? | ||
| 14 | moveq \rx, #0x80000000 @MMU off, Physical address | ||
| 15 | movne \rx, #0xF0000000 @MMU on, Virtual address | ||
| 16 | orr \rx, \rx, #0x7000 | ||
| 17 | .endm | ||
| 18 | |||
| 19 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/mach-ux500/include/mach/entry-macro.S b/arch/arm/mach-ux500/include/mach/entry-macro.S new file mode 100644 index 000000000000..eece3301fef7 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/entry-macro.S | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | /* | ||
| 2 | * Low-level IRQ helper macros for U8500 platforms | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 ST-Ericsson. | ||
| 5 | * | ||
| 6 | * This file is a copy of ARM Realview platform. | ||
| 7 | * -just satisfied checkpatch script. | ||
| 8 | * | ||
| 9 | * This file is licensed under the terms of the GNU General Public | ||
| 10 | * License version 2. This program is licensed "as is" without any | ||
| 11 | * warranty of any kind, whether express or implied. | ||
| 12 | */ | ||
| 13 | #include <mach/hardware.h> | ||
| 14 | #include <asm/hardware/gic.h> | ||
| 15 | |||
| 16 | .macro disable_fiq | ||
| 17 | .endm | ||
| 18 | |||
| 19 | .macro get_irqnr_preamble, base, tmp | ||
| 20 | ldr \base, =IO_ADDRESS(U8500_GIC_CPU_BASE) | ||
| 21 | .endm | ||
| 22 | |||
| 23 | .macro arch_ret_to_user, tmp1, tmp2 | ||
| 24 | .endm | ||
| 25 | |||
| 26 | /* | ||
| 27 | * The interrupt numbering scheme is defined in the | ||
| 28 | * interrupt controller spec. To wit: | ||
| 29 | * | ||
| 30 | * Interrupts 0-15 are IPI | ||
| 31 | * 16-28 are reserved | ||
| 32 | * 29-31 are local. We allow 30 to be used for the watchdog. | ||
| 33 | * 32-1020 are global | ||
| 34 | * 1021-1022 are reserved | ||
| 35 | * 1023 is "spurious" (no interrupt) | ||
| 36 | * | ||
| 37 | * For now, we ignore all local interrupts so only return an | ||
| 38 | * interrupt if it's between 30 and 1020. The test_for_ipi | ||
| 39 | * routine below will pick up on IPIs. | ||
| 40 | * | ||
| 41 | * A simple read from the controller will tell us the number | ||
| 42 | * of the highest priority enabled interrupt. We then just | ||
| 43 | * need to check whether it is in the valid range for an | ||
| 44 | * IRQ (30-1020 inclusive). | ||
| 45 | */ | ||
| 46 | |||
| 47 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
| 48 | |||
| 49 | /* bits 12-10 = src CPU, 9-0 = int # */ | ||
| 50 | ldr \irqstat, [\base, #GIC_CPU_INTACK] | ||
| 51 | |||
| 52 | ldr \tmp, =1021 | ||
| 53 | |||
| 54 | bic \irqnr, \irqstat, #0x1c00 | ||
| 55 | |||
| 56 | cmp \irqnr, #29 | ||
| 57 | cmpcc \irqnr, \irqnr | ||
| 58 | cmpne \irqnr, \tmp | ||
| 59 | cmpcs \irqnr, \irqnr | ||
| 60 | |||
| 61 | .endm | ||
| 62 | |||
| 63 | /* We assume that irqstat (the raw value of the IRQ | ||
| 64 | * acknowledge register) is preserved from the macro above. | ||
| 65 | * If there is an IPI, we immediately signal end of | ||
| 66 | * interrupt on the controller, since this requires the | ||
| 67 | * original irqstat value which we won't easily be able | ||
| 68 | * to recreate later. | ||
| 69 | */ | ||
| 70 | |||
| 71 | .macro test_for_ipi, irqnr, irqstat, base, tmp | ||
| 72 | bic \irqnr, \irqstat, #0x1c00 | ||
| 73 | cmp \irqnr, #16 | ||
| 74 | strcc \irqstat, [\base, #GIC_CPU_EOI] | ||
| 75 | cmpcs \irqnr, \irqnr | ||
| 76 | .endm | ||
| 77 | |||
| 78 | /* As above, this assumes that irqstat and base | ||
| 79 | * are preserved.. | ||
| 80 | */ | ||
| 81 | |||
| 82 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
| 83 | bic \irqnr, \irqstat, #0x1c00 | ||
| 84 | mov \tmp, #0 | ||
| 85 | cmp \irqnr, #29 | ||
| 86 | moveq \tmp, #1 | ||
| 87 | streq \irqstat, [\base, #GIC_CPU_EOI] | ||
| 88 | cmp \tmp, #0 | ||
| 89 | .endm | ||
diff --git a/arch/arm/mach-ux500/include/mach/memory.h b/arch/arm/mach-ux500/include/mach/memory.h new file mode 100644 index 000000000000..510571a59e25 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/memory.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 ST-Ericsson | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | */ | ||
| 9 | #ifndef __ASM_ARCH_MEMORY_H | ||
| 10 | #define __ASM_ARCH_MEMORY_H | ||
| 11 | |||
| 12 | /* | ||
| 13 | * Physical DRAM offset. | ||
| 14 | */ | ||
| 15 | #define PHYS_OFFSET UL(0x00000000) | ||
| 16 | #define BUS_OFFSET UL(0x00000000) | ||
| 17 | |||
| 18 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h new file mode 100644 index 000000000000..cf0ce1687f24 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/setup.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 ST-Ericsson. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * These symbols are needed for board-specific files to call their | ||
| 9 | * own cpu-specific files | ||
| 10 | */ | ||
| 11 | #ifndef __ASM_ARCH_SETUP_H | ||
| 12 | #define __ASM_ARCH_SETUP_H | ||
| 13 | |||
| 14 | #include <asm/mach/time.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | |||
| 17 | extern void u8500_map_io(void); | ||
| 18 | extern void u8500_init_devices(void); | ||
| 19 | extern void u8500_init_irq(void); | ||
| 20 | /* We re-use nomadik_timer for this platform */ | ||
| 21 | extern void nmdk_timer_init(void); | ||
| 22 | |||
| 23 | #endif /* __ASM_ARCH_SETUP_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h new file mode 100644 index 000000000000..b59f7bc9725d --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/smp.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* | ||
| 2 | * This file is based ARM realview platform. | ||
| 3 | * Copyright (C) ARM Limited. | ||
| 4 | * | ||
| 5 | * This file is licensed under the terms of the GNU General Public | ||
| 6 | * License version 2. This program is licensed "as is" without any | ||
| 7 | * warranty of any kind, whether express or implied. | ||
| 8 | */ | ||
| 9 | #ifndef ASMARM_ARCH_SMP_H | ||
| 10 | #define ASMARM_ARCH_SMP_H | ||
| 11 | |||
| 12 | #include <asm/hardware/gic.h> | ||
| 13 | |||
| 14 | /* This is required to wakeup the secondary core */ | ||
| 15 | extern void u8500_secondary_startup(void); | ||
| 16 | |||
| 17 | #define hard_smp_processor_id() \ | ||
| 18 | ({ \ | ||
| 19 | unsigned int cpunum; \ | ||
| 20 | __asm__("mrc p15, 0, %0, c0, c0, 5" \ | ||
| 21 | : "=r" (cpunum)); \ | ||
| 22 | cpunum &= 0x0F; \ | ||
| 23 | }) | ||
| 24 | |||
| 25 | /* | ||
| 26 | * We use IRQ1 as the IPI | ||
| 27 | */ | ||
| 28 | static inline void smp_cross_call(const struct cpumask *mask) | ||
| 29 | { | ||
| 30 | gic_raise_softirq(mask, 1); | ||
| 31 | } | ||
| 32 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/system.h b/arch/arm/mach-ux500/include/mach/system.h new file mode 100644 index 000000000000..c0cd8006f1a2 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/system.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 ST-Ericsson. | ||
| 3 | * | ||
| 4 | * This file is licensed under the terms of the GNU General Public | ||
| 5 | * License version 2. This program is licensed "as is" without any | ||
| 6 | * warranty of any kind, whether express or implied. | ||
| 7 | */ | ||
| 8 | #ifndef __ASM_ARCH_SYSTEM_H | ||
| 9 | #define __ASM_ARCH_SYSTEM_H | ||
| 10 | |||
| 11 | static inline void arch_idle(void) | ||
| 12 | { | ||
| 13 | /* | ||
| 14 | * This should do all the clock switching | ||
| 15 | * and wait for interrupt tricks | ||
| 16 | */ | ||
| 17 | cpu_do_idle(); | ||
| 18 | } | ||
| 19 | |||
| 20 | static inline void arch_reset(char mode, const char *cmd) | ||
| 21 | { | ||
| 22 | /* yet to be implemented - TODO */ | ||
| 23 | } | ||
| 24 | |||
| 25 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/timex.h b/arch/arm/mach-ux500/include/mach/timex.h new file mode 100644 index 000000000000..d0942c174018 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/timex.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef __ASM_ARCH_TIMEX_H | ||
| 2 | #define __ASM_ARCH_TIMEX_H | ||
| 3 | |||
| 4 | #define CLOCK_TICK_RATE 110000000 | ||
| 5 | |||
| 6 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h new file mode 100644 index 000000000000..8552eb188b50 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/uncompress.h | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 ST-Ericsson | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | */ | ||
| 18 | #ifndef __ASM_ARCH_UNCOMPRESS_H | ||
| 19 | #define __ASM_ARCH_UNCOMPRESS_H | ||
| 20 | |||
| 21 | #include <asm/setup.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | #include <mach/hardware.h> | ||
| 24 | |||
| 25 | #define U8500_UART_DR 0x80007000 | ||
| 26 | #define U8500_UART_LCRH 0x8000702c | ||
| 27 | #define U8500_UART_CR 0x80007030 | ||
| 28 | #define U8500_UART_FR 0x80007018 | ||
| 29 | |||
| 30 | static void putc(const char c) | ||
| 31 | { | ||
| 32 | /* Do nothing if the UART is not enabled. */ | ||
| 33 | if (!(readb(U8500_UART_CR) & 0x1)) | ||
| 34 | return; | ||
| 35 | |||
| 36 | if (c == '\n') | ||
| 37 | putc('\r'); | ||
| 38 | |||
| 39 | while (readb(U8500_UART_FR) & (1 << 5)) | ||
| 40 | barrier(); | ||
| 41 | writeb(c, U8500_UART_DR); | ||
| 42 | } | ||
| 43 | |||
| 44 | static void flush(void) | ||
| 45 | { | ||
| 46 | if (!(readb(U8500_UART_CR) & 0x1)) | ||
| 47 | return; | ||
| 48 | while (readb(U8500_UART_FR) & (1 << 3)) | ||
| 49 | barrier(); | ||
| 50 | } | ||
| 51 | |||
| 52 | static inline void arch_decomp_setup(void) | ||
| 53 | { | ||
| 54 | } | ||
| 55 | |||
| 56 | #define arch_decomp_wdog() /* nothing to do here */ | ||
| 57 | |||
| 58 | #endif /* __ASM_ARCH_UNCOMPRESS_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/vmalloc.h b/arch/arm/mach-ux500/include/mach/vmalloc.h new file mode 100644 index 000000000000..86cdbbce1842 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/vmalloc.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 ST-Ericsson | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | */ | ||
| 18 | #define VMALLOC_END 0xf0000000 | ||
diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c new file mode 100644 index 000000000000..2288f6a7c518 --- /dev/null +++ b/arch/arm/mach-ux500/localtimer.c | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008-2009 ST-Ericsson | ||
| 3 | * Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | ||
| 4 | * | ||
| 5 | * This file is heavily based on relaview platform, almost a copy. | ||
| 6 | * | ||
| 7 | * Copyright (C) 2002 ARM Ltd. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/smp.h> | ||
| 15 | #include <linux/clockchips.h> | ||
| 16 | |||
| 17 | #include <asm/irq.h> | ||
| 18 | #include <asm/smp_twd.h> | ||
| 19 | #include <asm/localtimer.h> | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Setup the local clock events for a CPU. | ||
| 23 | */ | ||
| 24 | void __cpuinit local_timer_setup(struct clock_event_device *evt) | ||
| 25 | { | ||
| 26 | evt->irq = IRQ_LOCALTIMER; | ||
| 27 | twd_timer_setup(evt); | ||
| 28 | } | ||
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c new file mode 100644 index 000000000000..8dfe7ca245d8 --- /dev/null +++ b/arch/arm/mach-ux500/platsmp.c | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2002 ARM Ltd. | ||
| 3 | * Copyright (C) 2008 STMicroelctronics. | ||
| 4 | * Copyright (C) 2009 ST-Ericsson. | ||
| 5 | * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | ||
| 6 | * | ||
| 7 | * This file is based on arm realview platform | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/errno.h> | ||
| 15 | #include <linux/delay.h> | ||
| 16 | #include <linux/device.h> | ||
| 17 | #include <linux/smp.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | |||
| 20 | #include <asm/cacheflush.h> | ||
| 21 | #include <asm/localtimer.h> | ||
| 22 | #include <asm/smp_scu.h> | ||
| 23 | #include <mach/hardware.h> | ||
| 24 | |||
| 25 | /* | ||
| 26 | * control for which core is the next to come out of the secondary | ||
| 27 | * boot "holding pen" | ||
| 28 | */ | ||
| 29 | volatile int __cpuinitdata pen_release = -1; | ||
| 30 | |||
| 31 | static unsigned int __init get_core_count(void) | ||
| 32 | { | ||
| 33 | return scu_get_core_count(__io_address(U8500_SCU_BASE)); | ||
| 34 | } | ||
| 35 | |||
| 36 | static DEFINE_SPINLOCK(boot_lock); | ||
| 37 | |||
| 38 | void __cpuinit platform_secondary_init(unsigned int cpu) | ||
| 39 | { | ||
| 40 | trace_hardirqs_off(); | ||
| 41 | |||
| 42 | /* | ||
| 43 | * if any interrupts are already enabled for the primary | ||
| 44 | * core (e.g. timer irq), then they will not have been enabled | ||
| 45 | * for us: do so | ||
| 46 | */ | ||
| 47 | gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE)); | ||
| 48 | |||
| 49 | /* | ||
| 50 | * let the primary processor know we're out of the | ||
| 51 | * pen, then head off into the C entry point | ||
| 52 | */ | ||
| 53 | pen_release = -1; | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Synchronise with the boot thread. | ||
| 57 | */ | ||
| 58 | spin_lock(&boot_lock); | ||
| 59 | spin_unlock(&boot_lock); | ||
| 60 | } | ||
| 61 | |||
| 62 | int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
| 63 | { | ||
| 64 | unsigned long timeout; | ||
| 65 | |||
| 66 | /* | ||
| 67 | * set synchronisation state between this boot processor | ||
| 68 | * and the secondary one | ||
| 69 | */ | ||
| 70 | spin_lock(&boot_lock); | ||
| 71 | |||
| 72 | /* | ||
| 73 | * The secondary processor is waiting to be released from | ||
| 74 | * the holding pen - release it, then wait for it to flag | ||
| 75 | * that it has been released by resetting pen_release. | ||
| 76 | */ | ||
| 77 | pen_release = cpu; | ||
| 78 | flush_cache_all(); | ||
| 79 | |||
| 80 | timeout = jiffies + (1 * HZ); | ||
| 81 | while (time_before(jiffies, timeout)) { | ||
| 82 | if (pen_release == -1) | ||
| 83 | break; | ||
| 84 | } | ||
| 85 | |||
| 86 | /* | ||
| 87 | * now the secondary core is starting up let it run its | ||
| 88 | * calibrations, then wait for it to finish | ||
| 89 | */ | ||
| 90 | spin_unlock(&boot_lock); | ||
| 91 | |||
| 92 | return pen_release != -1 ? -ENOSYS : 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | static void __init wakeup_secondary(void) | ||
| 96 | { | ||
| 97 | /* nobody is to be released from the pen yet */ | ||
| 98 | pen_release = -1; | ||
| 99 | |||
| 100 | /* | ||
| 101 | * write the address of secondary startup into the backup ram register | ||
| 102 | * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the | ||
| 103 | * backup ram register at offset 0x1FF0, which is what boot rom code | ||
| 104 | * is waiting for. This would wake up the secondary core from WFE | ||
| 105 | */ | ||
| 106 | #define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4 | ||
| 107 | __raw_writel(virt_to_phys(u8500_secondary_startup), | ||
| 108 | (void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) + | ||
| 109 | U8500_CPU1_JUMPADDR_OFFSET); | ||
| 110 | |||
| 111 | #define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0 | ||
| 112 | __raw_writel(0xA1FEED01, | ||
| 113 | (void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) + | ||
| 114 | U8500_CPU1_WAKEMAGIC_OFFSET); | ||
| 115 | |||
| 116 | /* make sure write buffer is drained */ | ||
| 117 | mb(); | ||
| 118 | } | ||
| 119 | |||
| 120 | /* | ||
| 121 | * Initialise the CPU possible map early - this describes the CPUs | ||
| 122 | * which may be present or become present in the system. | ||
| 123 | */ | ||
| 124 | void __init smp_init_cpus(void) | ||
| 125 | { | ||
| 126 | unsigned int i, ncores = get_core_count(); | ||
| 127 | |||
| 128 | for (i = 0; i < ncores; i++) | ||
| 129 | set_cpu_possible(i, true); | ||
| 130 | } | ||
| 131 | |||
| 132 | void __init smp_prepare_cpus(unsigned int max_cpus) | ||
| 133 | { | ||
| 134 | unsigned int ncores = get_core_count(); | ||
| 135 | unsigned int cpu = smp_processor_id(); | ||
| 136 | int i; | ||
| 137 | |||
| 138 | /* sanity check */ | ||
| 139 | if (ncores == 0) { | ||
| 140 | printk(KERN_ERR | ||
| 141 | "U8500: strange CM count of 0? Default to 1\n"); | ||
| 142 | ncores = 1; | ||
| 143 | } | ||
| 144 | |||
| 145 | if (ncores > num_possible_cpus()) { | ||
| 146 | printk(KERN_WARNING | ||
| 147 | "U8500: no. of cores (%d) greater than configured " | ||
| 148 | "maximum of %d - clipping\n", | ||
| 149 | ncores, num_possible_cpus()); | ||
| 150 | ncores = num_possible_cpus(); | ||
| 151 | } | ||
| 152 | |||
| 153 | smp_store_cpu_info(cpu); | ||
| 154 | |||
| 155 | /* | ||
| 156 | * are we trying to boot more cores than exist? | ||
| 157 | */ | ||
| 158 | if (max_cpus > ncores) | ||
| 159 | max_cpus = ncores; | ||
| 160 | |||
| 161 | /* | ||
| 162 | * Initialise the present map, which describes the set of CPUs | ||
| 163 | * actually populated at the present time. | ||
| 164 | */ | ||
| 165 | for (i = 0; i < max_cpus; i++) | ||
| 166 | set_cpu_present(i, true); | ||
| 167 | |||
| 168 | if (max_cpus > 1) { | ||
| 169 | /* | ||
| 170 | * Enable the local timer or broadcast device for the | ||
| 171 | * boot CPU, but only if we have more than one CPU. | ||
| 172 | */ | ||
| 173 | percpu_timer_setup(); | ||
| 174 | scu_enable(__io_address(U8500_SCU_BASE)); | ||
| 175 | wakeup_secondary(); | ||
| 176 | } | ||
| 177 | } | ||
