diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2013-03-04 09:21:54 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-03-04 09:21:54 +0100 |
commit | 13b4e37c1cec01079858bbd3429b0a45812c01b8 (patch) | |
tree | 01035424cda2e4c6fe8334312526c1d0d3faaff1 | |
parent | 678832e17a401819349bbea0425de44c7cdd288c (diff) | |
parent | 64b873ccba69a6311e03de1c68585f32f5a86524 (diff) | |
download | barebox-13b4e37c1cec01079858bbd3429b0a45812c01b8.tar.gz barebox-13b4e37c1cec01079858bbd3429b0a45812c01b8.tar.xz |
Merge branch 'for-next/vexpress'
28 files changed, 950 insertions, 7 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 975b525fa..7ac134e15 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -114,6 +114,15 @@ config ARCH_VERSATILE select CPU_ARM926T select GPIOLIB +config ARCH_VEXPRESS + bool "ARM Vexpres boards" + select HAS_DEBUG_LL + select CPU_V7 + select ARM_AMBA + select AMBA_SP804 + select CLKDEV_LOOKUP + select COMMON_CLK + config ARCH_TEGRA bool "Nvidia Tegra-based boards" select CPU_ARM926T @@ -135,6 +144,7 @@ source arch/arm/mach-omap/Kconfig source arch/arm/mach-pxa/Kconfig source arch/arm/mach-samsung/Kconfig source arch/arm/mach-versatile/Kconfig +source arch/arm/mach-vexpress/Kconfig source arch/arm/mach-tegra/Kconfig config ARM_ASM_UNIFIED diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 9d4c86626..b98d6b86a 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -64,6 +64,7 @@ machine-$(CONFIG_ARCH_OMAP) := omap machine-$(CONFIG_ARCH_PXA) := pxa machine-$(CONFIG_ARCH_SAMSUNG) := samsung machine-$(CONFIG_ARCH_VERSATILE) := versatile +machine-$(CONFIG_ARCH_VEXPRESS) := vexpress machine-$(CONFIG_ARCH_TEGRA) := tegra # Board directory name. This list is sorted alphanumerically @@ -148,6 +149,7 @@ board-$(CONFIG_MACH_USB_A9260) := usb-a926x board-$(CONFIG_MACH_USB_A9263) := usb-a926x board-$(CONFIG_MACH_USB_A9G20) := usb-a926x board-$(CONFIG_MACH_VERSATILEPB) := versatile +board-$(CONFIG_MACH_VEXPRESS) := vexpress board-$(CONFIG_MACH_TX25) := karo-tx25 board-$(CONFIG_MACH_TQMA53) := tqma53 board-$(CONFIG_MACH_TX51) := karo-tx51 diff --git a/arch/arm/boards/vexpress/Kconfig b/arch/arm/boards/vexpress/Kconfig new file mode 100644 index 000000000..24289014c --- /dev/null +++ b/arch/arm/boards/vexpress/Kconfig @@ -0,0 +1,10 @@ + +if MACH_VERSATILEPB + +config ARCH_TEXT_BASE + hex + default 0x01000000 + +config BOARDINFO + default "ARM Versatile/PB (ARM926EJ-S)" +endif diff --git a/arch/arm/boards/vexpress/Makefile b/arch/arm/boards/vexpress/Makefile new file mode 100644 index 000000000..98921a48b --- /dev/null +++ b/arch/arm/boards/vexpress/Makefile @@ -0,0 +1,4 @@ +obj-y += init.o + +obj-y += lowlevel.o +pbl-y += lowlevel.o diff --git a/arch/arm/boards/vexpress/config.h b/arch/arm/boards/vexpress/config.h new file mode 100644 index 000000000..25bb18f78 --- /dev/null +++ b/arch/arm/boards/vexpress/config.h @@ -0,0 +1,5 @@ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#endif /* __CONFIG_H */ diff --git a/arch/arm/boards/vexpress/env/config b/arch/arm/boards/vexpress/env/config new file mode 100644 index 000000000..852f2428c --- /dev/null +++ b/arch/arm/boards/vexpress/env/config @@ -0,0 +1,40 @@ +#!/bin/sh + +# use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration +ip=dhcp +# set in c +#global.hostname=vexpress +global.dhcp.vendor_id=barebox-${global.hostname} + +# or set your networking parameters here +#eth0.ipaddr=a.b.c.d +#eth0.netmask=a.b.c.d +#eth0.gateway=a.b.c.d +#eth0.serverip=a.b.c.d + +# can be either 'nfs', 'tftp' or 'nor' +kernel_loc=tftp +# can be either 'net', 'nor' or 'initrd' +rootfs_loc=initrd + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root.$rootfs_type + +kernelimage=zImage +#kernelimage=uImage +#kernelimage=Image +#kernelimage=Image.lzo + +nfsroot="$eth0.serverip:/opt/work/busybox/arm9/rootfs_arm" + +nor_parts="256k(barebox)ro,64k(bareboxenv),1536k(kernel),-(root)" +rootfs_mtdblock_nor=3 + +autoboot_timeout=3 + +bootargs="console=ttyAMA0,115200n8 CONSOLE=/dev/ttyAMA0" + +# set a fancy prompt (if support is compiled in) +PS1="\e[1;31m[barebox@\h]:\w\e[0m\n# " diff --git a/arch/arm/boards/vexpress/init.c b/arch/arm/boards/vexpress/init.c new file mode 100644 index 000000000..2b2d085a5 --- /dev/null +++ b/arch/arm/boards/vexpress/init.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * GPLv2 only + */ + +#include <common.h> +#include <init.h> +#include <asm/armlinux.h> +#include <asm/system_info.h> +#include <generated/mach-types.h> +#include <mach/devices.h> +#include <environment.h> +#include <partition.h> +#include <sizes.h> +#include <io.h> +#include <globalvar.h> +#include <linux/amba/sp804.h> + +struct vexpress_init { + void (*core_init)(void); + void (*mem_init)(void); + void (*console_init)(void); + void (*devices_init)(void); + char *hostname; +}; + +struct vexpress_init *v2m_init; + +static void vexpress_ax_mem_init(void) +{ + vexpress_add_ddram(SZ_512M); +} + +#define V2M_SYS_FLASH 0x03c + +static void vexpress_ax_devices_init(void) +{ + add_cfi_flash_device(0, 0x08000000, SZ_64M, 0); + add_cfi_flash_device(1, 0x0c000000, SZ_64M, 0); + add_generic_device("smc911x", DEVICE_ID_DYNAMIC, NULL, 0x1a000000, + 64 * 1024, IORESOURCE_MEM, NULL); + armlinux_set_bootparams((void *)(0x80000100)); +} + +static void vexpress_ax_console_init(void) +{ + vexpress_register_uart(0); + vexpress_register_uart(1); + vexpress_register_uart(2); + vexpress_register_uart(3); +} + +struct vexpress_init vexpress_init_ax = { + .core_init = vexpress_init, + .mem_init = vexpress_ax_mem_init, + .console_init = vexpress_ax_console_init, + .devices_init = vexpress_ax_devices_init, +}; + +static void vexpress_a9_legacy_mem_init(void) +{ + vexpress_a9_legacy_add_ddram(SZ_512M, SZ_512M); +} + +static void vexpress_a9_legacy_devices_init(void) +{ + add_cfi_flash_device(0, 0x40000000, SZ_64M, 0); + add_cfi_flash_device(1, 0x44000000, SZ_64M, 0); + add_generic_device("smc911x", DEVICE_ID_DYNAMIC, NULL, 0x4e000000, + 64 * 1024, IORESOURCE_MEM, NULL); + + armlinux_set_architecture(MACH_TYPE_VEXPRESS); + armlinux_set_bootparams((void *)(0x60000100)); +} + +static void vexpress_a9_legacy_console_init(void) +{ + vexpress_a9_legacy_register_uart(0); + vexpress_a9_legacy_register_uart(1); + vexpress_a9_legacy_register_uart(2); + vexpress_a9_legacy_register_uart(3); +} + +struct vexpress_init vexpress_init_a9_legacy = { + .core_init = vexpress_a9_legacy_init, + .mem_init = vexpress_a9_legacy_mem_init, + .console_init = vexpress_a9_legacy_console_init, + .devices_init = vexpress_a9_legacy_devices_init, + .hostname = "vexpress-a9-legacy", +}; + +static int vexpress_mem_init(void) +{ + v2m_init->mem_init(); + + return 0; +} +mem_initcall(vexpress_mem_init); + +static int vexpress_devices_init(void) +{ + writel(1, v2m_sysreg_base + V2M_SYS_FLASH); + v2m_init->devices_init(); + + devfs_add_partition("nor0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self"); + devfs_add_partition("nor0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env0"); + + + globalvar_add_simple("hostname"); + setenv("global.hostname", v2m_init->hostname); + + return 0; +} +device_initcall(vexpress_devices_init); + +static int vexpress_console_init(void) +{ + v2m_init->console_init(); + + return 0; +} +console_initcall(vexpress_console_init); + +static int vexpress_core_init(void) +{ + if (amba_is_arm_sp804(IOMEM(0x10011000))) { + v2m_init = &vexpress_init_a9_legacy; + } else { + v2m_init = &vexpress_init_ax; + if (cpu_is_cortex_a5()) + v2m_init->hostname = "vexpress-a5"; + else if (cpu_is_cortex_a7()) + v2m_init->hostname = "vexpress-a7"; + else if (cpu_is_cortex_a9()) + v2m_init->hostname = "vexpress-a9"; + else if (cpu_is_cortex_a15()) + v2m_init->hostname = "vexpress-a15"; + } + + v2m_init->core_init(); + + return 0; +} +postcore_initcall(vexpress_core_init); diff --git a/arch/arm/boards/vexpress/lowlevel.c b/arch/arm/boards/vexpress/lowlevel.c new file mode 100644 index 000000000..a296352cf --- /dev/null +++ b/arch/arm/boards/vexpress/lowlevel.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * GPLv2 only + */ + +#include <common.h> +#include <sizes.h> +#include <asm/barebox-arm-head.h> +#include <asm/barebox-arm.h> +#include <asm/system_info.h> +#include <linux/amba/sp804.h> + +void __naked barebox_arm_reset_vector(void) +{ + arm_cpu_lowlevel_init(); + + if (amba_is_arm_sp804(IOMEM(0x10011000))) + barebox_arm_entry(0x60000000, SZ_512M, 0); + else + barebox_arm_entry(0x80000000, SZ_512M, 0); +} diff --git a/arch/arm/configs/vexpress_ca9_defconfig b/arch/arm/configs/vexpress_ca9_defconfig new file mode 100644 index 000000000..f16a8ca5e --- /dev/null +++ b/arch/arm/configs/vexpress_ca9_defconfig @@ -0,0 +1,61 @@ +CONFIG_ARCH_VEXPRESS=y +CONFIG_MACH_VEXPRESS +CONFIG_AEABI=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_TEXT_BASE=0x63f00000 +CONFIG_MALLOC_TLSF=y +CONFIG_PROMPT="vexpress: " +CONFIG_LONGHELP=y +CONFIG_GLOB=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_PARTITION=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/vexpress/env" +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_MENU=y +CONFIG_CMD_MENU_MANAGEMENT=y +CONFIG_CMD_PASSWD=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTM_VERBOSE=y +CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_BOO +CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y +CONFIG_CMD_UIMAGE=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_MTEST=y +CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_CLK=y +CONFIG_NET=y +CONFIG_NET_DHCP=y +CONFIG_NET_NFS=y +CONFIG_NET_PING=y +CONFIG_NET_NETCONSOLE=y +CONFIG_NET_RESOLV=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_DRIVER_NET_SMC91111=y +# CONFIG_SPI is not set +CONFIG_DRIVER_CFI=y +# CONFIG_DRIVER_CFI_AMD is not set +# CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set +# CONFIG_DRIVER_CFI_BANK_WIDTH_2 is not set +CONFIG_FS_TFTP=y +CONFIG_SHA1=y +CONFIG_SHA256=y diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig new file mode 100644 index 000000000..e1660783d --- /dev/null +++ b/arch/arm/configs/vexpress_defconfig @@ -0,0 +1,60 @@ +CONFIG_ARCH_VEXPRESS=y +CONFIG_MACH_VEXPRESS +CONFIG_AEABI=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_MALLOC_TLSF=y +CONFIG_PROMPT="vexpress: " +CONFIG_LONGHELP=y +CONFIG_GLOB=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_PARTITION=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/vexpress/env" +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_MENU=y +CONFIG_CMD_MENU_MANAGEMENT=y +CONFIG_CMD_PASSWD=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTM_VERBOSE=y +CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_BOO +CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y +CONFIG_CMD_UIMAGE=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_MTEST=y +CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_CLK=y +CONFIG_NET=y +CONFIG_NET_DHCP=y +CONFIG_NET_NFS=y +CONFIG_NET_PING=y +CONFIG_NET_NETCONSOLE=y +CONFIG_NET_RESOLV=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_DRIVER_NET_SMC91111=y +# CONFIG_SPI is not set +CONFIG_DRIVER_CFI=y +# CONFIG_DRIVER_CFI_AMD is not set +# CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set +# CONFIG_DRIVER_CFI_BANK_WIDTH_2 is not set +CONFIG_FS_TFTP=y +CONFIG_SHA1=y +CONFIG_SHA256=y diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h index 0433279b8..8a58390a1 100644 --- a/arch/arm/include/asm/hardware/arm_timer.h +++ b/arch/arm/include/asm/hardware/arm_timer.h @@ -12,7 +12,12 @@ * * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview * can have 16-bit or 32-bit selectable via a bit in the control register. + * + * Every SP804 contains two identical timers. */ +#define TIMER_1_BASE 0x00 +#define TIMER_2_BASE 0x20 + #define TIMER_LOAD 0x00 /* ACVR rw */ #define TIMER_VALUE 0x04 /* ACVR ro */ #define TIMER_CTRL 0x08 /* ACVR rw */ diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h new file mode 100644 index 000000000..3e3996a99 --- /dev/null +++ b/arch/arm/include/asm/hardware/sp810.h @@ -0,0 +1,68 @@ +/* + * arch/arm/include/asm/hardware/sp810.h + * + * ARM PrimeXsys System Controller SP810 header file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar <viresh.linux@gmail.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __ASM_ARM_SP810_H +#define __ASM_ARM_SP810_H + +#include <io.h> + +/* sysctl registers offset */ +#define SCCTRL 0x000 +#define SCSYSSTAT 0x004 +#define SCIMCTRL 0x008 +#define SCIMSTAT 0x00C +#define SCXTALCTRL 0x010 +#define SCPLLCTRL 0x014 +#define SCPLLFCTRL 0x018 +#define SCPERCTRL0 0x01C +#define SCPERCTRL1 0x020 +#define SCPEREN 0x024 +#define SCPERDIS 0x028 +#define SCPERCLKEN 0x02C +#define SCPERSTAT 0x030 +#define SCSYSID0 0xEE0 +#define SCSYSID1 0xEE4 +#define SCSYSID2 0xEE8 +#define SCSYSID3 0xEEC +#define SCITCR 0xF00 +#define SCITIR0 0xF04 +#define SCITIR1 0xF08 +#define SCITOR 0xF0C +#define SCCNTCTRL 0xF10 +#define SCCNTDATA 0xF14 +#define SCCNTSTEP 0xF18 +#define SCPERIPHID0 0xFE0 +#define SCPERIPHID1 0xFE4 +#define SCPERIPHID2 0xFE8 +#define SCPERIPHID3 0xFEC +#define SCPCELLID0 0xFF0 +#define SCPCELLID1 0xFF4 +#define SCPCELLID2 0xFF8 +#define SCPCELLID3 0xFFC + +#define SCCTRL_TIMEREN0SEL_REFCLK (0 << 15) +#define SCCTRL_TIMEREN0SEL_TIMCLK (1 << 15) + +#define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17) +#define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17) + +static inline void sysctl_soft_reset(void __iomem *base) +{ + /* switch to slow mode */ + writel(0x2, base + SCCTRL); + + /* writing any value to SCSYSSTAT reg will reset system */ + writel(0, base + SCSYSSTAT); +} + +#endif /* __ASM_ARM_SP810_H */ diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h index 5b676313c..56ebb11a2 100644 --- a/arch/arm/include/asm/system_info.h +++ b/arch/arm/include/asm/system_info.h @@ -1,6 +1,8 @@ #ifndef __ASM_ARM_SYSTEM_INFO_H #define __ASM_ARM_SYSTEM_INFO_H +#include <asm/cputype.h> + #define CPU_ARCH_UNKNOWN 0 #define CPU_ARCH_ARMv3 1 #define CPU_ARCH_ARMv4 2 @@ -12,12 +14,56 @@ #define CPU_ARCH_ARMv6 8 #define CPU_ARCH_ARMv7 9 +#define CPU_IS_ARM920 0x41009200 +#define CPU_IS_ARM920_MASK 0xff00fff0 + +#define CPU_IS_ARM926 0x41069260 +#define CPU_IS_ARM926_MASK 0xff0ffff0 + +#define CPU_IS_ARM1176 0x410fb767 +#define CPU_IS_ARM1176_MASK 0xff0ffff0 + +#define CPU_IS_CORTEX_A8 0x410fc080 +#define CPU_IS_CORTEX_A8_MASK 0xff0ffff0 + +#define CPU_IS_CORTEX_A5 0x410fc050 +#define CPU_IS_CORTEX_A5_MASK 0xff0ffff0 + +#define CPU_IS_CORTEX_A9 0x410fc090 +#define CPU_IS_CORTEX_A9_MASK 0xff0ffff0 + +#define CPU_IS_CORTEX_A7 0x410fc070 +#define CPU_IS_CORTEX_A7_MASK 0xff0ffff0 + +#define CPU_IS_CORTEX_A15 0x410fc0f0 +#define CPU_IS_CORTEX_A15_MASK 0xff0ffff0 + +#define CPU_IS_PXA250 0x69052100 +#define CPU_IS_PXA250_MASK 0xfffff7f0 + +#define CPU_IS_PXA255 0x69052d00 +#define CPU_IS_PXA255_MASK 0xfffffff0 + +#define CPU_IS_PXA270 0x69054110 +#define CPU_IS_PXA270_MASK 0xfffff7f0 + +#define cpu_is_arm(core) ((read_cpuid_id() & CPU_IS_##core##_MASK) == CPU_IS_##core) + #ifdef CONFIG_CPU_32v4T #ifdef ARM_ARCH #define ARM_MULTIARCH #else #define ARM_ARCH CPU_ARCH_ARMv4T #endif +#define cpu_is_arm920() cpu_is_arm(ARM920) +#define cpu_is_pxa250() cpu_is_arm(PXA250) +#define cpu_is_pxa255() cpu_is_arm(PXA255) +#define cpu_is_pxa270() cpu_is_arm(PXA270) +#else +#define cpu_is_arm920() (0) +#define cpu_is_pxa250() (0) +#define cpu_is_pxa255() (0) +#define cpu_is_pxa270() (0) #endif #ifdef CONFIG_CPU_32v5 @@ -26,6 +72,9 @@ #else #define ARM_ARCH CPU_ARCH_ARMv5 #endif +#define cpu_is_arm926() cpu_is_arm(ARM926) +#else +#define cpu_is_arm926() (0) #endif #ifdef CONFIG_CPU_32v6 @@ -34,6 +83,9 @@ #else #define ARM_ARCH CPU_ARCH_ARMv6 #endif +#define cpu_is_arm1176() cpu_is_arm(ARM1176) +#else +#define cpu_is_arm1176() (0) #endif #ifdef CONFIG_CPU_32v7 @@ -42,6 +94,17 @@ #else #define ARM_ARCH CPU_ARCH_ARMv7 #endif +#define cpu_is_cortex_a8() cpu_is_arm(CORTEX_A8) +#define cpu_is_cortex_a5() cpu_is_arm(CORTEX_A5) +#define cpu_is_cortex_a9() cpu_is_arm(CORTEX_A9) +#define cpu_is_cortex_a7() cpu_is_arm(CORTEX_A7) +#define cpu_is_cortex_a15() cpu_is_arm(CORTEX_A15) +#else +#define cpu_is_cortex_a8() (0) +#define cpu_is_cortex_a5() (0) +#define cpu_is_cortex_a9() (0) +#define cpu_is_cortex_a7() (0) +#define cpu_is_cortex_a15() (0) #endif #ifndef __ASSEMBLY__ diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig new file mode 100644 index 000000000..c595494b6 --- /dev/null +++ b/arch/arm/mach-vexpress/Kconfig @@ -0,0 +1,18 @@ +if ARCH_VEXPRESS + +config ARCH_TEXT_BASE + hex + default 0x83f00000 + +config BOARDINFO + default "ARM Vexpress" if MACH_VEXPRESS + +choice + prompt "ARM Board type" + +config MACH_VEXPRESS + bool "ARM Vexpress" + +endchoice + +endif diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile new file mode 100644 index 000000000..74b4a0feb --- /dev/null +++ b/arch/arm/mach-vexpress/Makefile @@ -0,0 +1,3 @@ +obj-y += v2m.o +obj-y += devices.o +obj-y += reset.o diff --git a/arch/arm/mach-vexpress/devices.c b/arch/arm/mach-vexpress/devices.c new file mode 100644 index 000000000..6ccce5261 --- /dev/null +++ b/arch/arm/mach-vexpress/devices.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * GPLv2 only + */ + +#include <common.h> + +#include <linux/amba/bus.h> + +#include <asm/memory.h> + +#include <mach/devices.h> + +void vexpress_a9_legacy_add_ddram(u32 ddr0_size, u32 ddr1_size) +{ + arm_add_mem_device("ram0", 0x60000000, ddr0_size); + + if (ddr1_size) + arm_add_mem_device("ram1", 0x80000000, ddr1_size); +} + + +void vexpress_a9_legacy_register_uart(unsigned id) +{ + resource_size_t start; + + switch (id) { + case 0: + start = 0x10009000; + break; + case 1: + start = 0x1000a000; + break; + case 2: + start = 0x1000b000; + break; + case 3: + start = 0x1000c000; + break; + default: + return; + } + amba_apb_device_add(NULL, "uart-pl011", id, start, 4096, NULL, 0); +} + +void vexpress_add_ddram(u32 size) +{ + arm_add_mem_device("ram1", 0x80000000, size); +} + +void vexpress_register_uart(unsigned id) +{ + resource_size_t start; + + switch (id) { + case 0: + start = 0x1c090000; + break; + case 1: + start = 0x1c0a0000; + break; + case 2: + start = 0x1c0b0000; + break; + case 3: + start = 0x1c0c0000; + break; + default: + return; + } + amba_apb_device_add(NULL, "uart-pl011", id, start, 4096, NULL, 0); +} diff --git a/arch/arm/mach-vexpress/include/mach/clkdev.h b/arch/arm/mach-vexpress/include/mach/clkdev.h new file mode 100644 index 000000000..04b37a898 --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/clkdev.h @@ -0,0 +1,7 @@ +#ifndef __ASM_MACH_CLKDEV_H +#define __ASM_MACH_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/debug_ll.h b/arch/arm/mach-vexpress/include/mach/debug_ll.h new file mode 100644 index 000000000..15d6e8523 --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/debug_ll.h @@ -0,0 +1,33 @@ +/* + * Copyright 2013 Jean-Christophe PLAGNIOL-VILLARD <plagniol@jcrosoft.com> + * + * GPLv2 only + */ + +#ifndef __MACH_DEBUG_LL_H__ +#define __MACH_DEBUG_LL_H__ + +#include <linux/amba/serial.h> +#include <io.h> + +#define DEBUG_LL_PHYS_BASE 0x10000000 +#define DEBUG_LL_PHYS_BASE_RS1 0x1c000000 + +#ifdef MP +#define UART_BASE DEBUG_LL_PHYS_BASE +#else +#define UART_BASE DEBUG_LL_PHYS_BASE_RS1 +#endif + +static inline void PUTC_LL(char c) +{ + /* Wait until there is space in the FIFO */ + while (readl(UART_BASE + UART01x_FR) & UART01x_FR_TXFF); + + /* Send the character */ + writel(c, UART_BASE + UART01x_DR); + + /* Wait to make sure it hits the line, in case we die too soon. */ + while (readl(UART_BASE + UART01x_FR) & UART01x_FR_TXFF); +} +#endif diff --git a/arch/arm/mach-vexpress/include/mach/devices.h b/arch/arm/mach-vexpress/include/mach/devices.h new file mode 100644 index 000000000..3146a475e --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/devices.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * GPLv2 only + */ + +#ifndef __ASM_ARCH_DEVICES_H__ +#define __ASM_ARCH_DEVICES_H__ + +void vexpress_a9_legacy_add_ddram(u32 ddr0_size, u32 ddr1_size); +void vexpress_add_ddram(u32 size); + +void vexpress_a9_legacy_register_uart(unsigned id); +void vexpress_register_uart(unsigned id); + +void vexpress_a9_legacy_init(void); +void vexpress_init(void); + +extern void *v2m_wdt_base; +extern void *v2m_sysreg_base; + +#endif /* __ASM_ARCH_DEVICES_H__ */ diff --git a/arch/arm/mach-vexpress/reset.c b/arch/arm/mach-vexpress/reset.c new file mode 100644 index 000000000..ad6e06fe5 --- /dev/null +++ b/arch/arm/mach-vexpress/reset.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * GPLv2 only + */ + +#include <common.h> +#include <io.h> +#include <linux/amba/sp805.h> + +#include <mach/devices.h> + +void __iomem *v2m_wdt_base; + +void reset_cpu(ulong addr) +{ + writel(LOAD_MIN, v2m_wdt_base + WDTLOAD); + writeb(RESET_ENABLE, v2m_wdt_base + WDTCONTROL); + + while (1) + ; +} diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c new file mode 100644 index 000000000..d6dde83e4 --- /dev/null +++ b/arch/arm/mach-vexpress/v2m.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * GPLv2 only + */ + +#include <common.h> +#include <init.h> +#include <io.h> + +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/amba/bus.h> + +#include <asm/hardware/arm_timer.h> +#include <asm/hardware/sp810.h> + +#include <mach/devices.h> + +void __iomem *v2m_sysreg_base; + +static const char *v2m_osc2_periphs[] = { + "mb:uart0", "uart-pl0110", /* PL011 UART0 */ + "mb:uart1", "uart-pl0111", /* PL011 UART1 */ + "mb:uart2", "uart-pl0112", /* PL011 UART2 */ + "mb:uart3", "uart-pl0113", /* PL011 UART3 */ +}; + +static void v2m_clk_init(void) +{ + struct clk *clk; + int i; + + clk = clk_fixed("dummy_apb_pclk", 0); + clk_register_clkdev(clk, "apb_pclk", NULL); + + clk = clk_fixed("mb:sp804_clk", 1000000); + clk_register_clkdev(clk, NULL, "sp804"); + + clk = clk_fixed("mb:osc2", 24000000); + for (i = 0; i < ARRAY_SIZE(v2m_osc2_periphs); i++) + clk_register_clkdev(clk, NULL, v2m_osc2_periphs[i]); + +} + +static void v2m_sysctl_init(void __iomem *base) +{ + u32 scctrl; + + if (WARN_ON(!base)) + return; + + /* Select 1MHz TIMCLK as the reference clock for SP804 timers */ + scctrl = readl(base + SCCTRL); + scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK; + scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK; + writel(scctrl, base + SCCTRL); +} + +static void __init v2m_sp804_init(void __iomem *base) +{ + writel(0, base + TIMER_1_BASE + TIMER_CTRL); + + amba_apb_device_add(NULL, "sp804", DEVICE_ID_SINGLE, (resource_size_t)base, 4096, NULL, 0); +} + +void vexpress_a9_legacy_init(void) +{ + v2m_wdt_base = IOMEM(0x1000f000); + v2m_sysreg_base = IOMEM(0x10001000); + v2m_sysctl_init(IOMEM(0x10001000)); + v2m_clk_init(); + + v2m_sp804_init(IOMEM(0x10011000)); +} + +void vexpress_init(void) +{ + v2m_wdt_base = IOMEM(0x1c0f0000); + v2m_sysreg_base = IOMEM(0x1c020000); + v2m_sysctl_init(IOMEM(0x1c020000)); + v2m_clk_init(); + + v2m_sp804_init(IOMEM(0x1c110000)); +} diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index dcb52bf73..7d7a6541a 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -104,7 +104,7 @@ int amba_device_add(struct amba_device *dev) { u32 size; void __iomem *tmp; - int i, ret; + int ret; struct resource *res = NULL; dev->dev.bus = &amba_bustype; @@ -135,12 +135,8 @@ int amba_device_add(struct amba_device *dev) * Read pid and cid based on size of resource * they are located at end of region */ - for (pid = 0, i = 0; i < 4; i++) - pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << - (i * 8); - for (cid = 0, i = 0; i < 4; i++) - cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << - (i * 8); + pid = amba_device_get_pid(tmp, size); + cid = amba_device_get_cid(tmp, size); if (cid == AMBA_CID) dev->periphid = pid; diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 09acdd74c..3f27cf243 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -1,3 +1,7 @@ +config AMBA_SP804 + bool + depends on ARM_AMBA + config ARM_SMP_TWD bool depends on ARM && CPU_V7 diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 92d7c1344..b0bc8bd7d 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_AMBA_SP804) += amba-sp804.o obj-$(CONFIG_ARM_SMP_TWD) += arm_smp_twd.o obj-$(CONFIG_CLOCKSOURCE_BCM2835) += bcm2835.o obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o diff --git a/drivers/clocksource/amba-sp804.c b/drivers/clocksource/amba-sp804.c new file mode 100644 index 000000000..fedcb6483 --- /dev/null +++ b/drivers/clocksource/amba-sp804.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPL v2 + */ +#include <common.h> +#include <init.h> +#include <clock.h> +#include <io.h> +#include <driver.h> +#include <errno.h> +#include <linux/amba/sp804.h> +#include <linux/clk.h> +#include <linux/err.h> + +#include <asm/hardware/arm_timer.h> + +static __iomem void *sp804_base; +static struct clk *sp804_clk; + +static uint64_t sp804_read(void) +{ + return ~readl(sp804_base + TIMER_VALUE); +} + +static struct clocksource sp804_clksrc = { + .read = sp804_read, + .shift = 20, + .mask = CLOCKSOURCE_MASK(32), +}; + +static int sp804_probe(struct amba_device *dev, const struct amba_id *id) +{ + u32 tick_rate; + int ret; + + if (sp804_base) { + dev_err(&dev->dev, "single instance driver\n"); + return -EBUSY; + } + + sp804_clk = clk_get(&dev->dev, NULL); + if (IS_ERR(sp804_clk)) { + ret = PTR_ERR(sp804_clk); + dev_err(&dev->dev, "clock not found: %d\n", ret); + return ret; + } + + ret = clk_enable(sp804_clk); + if (ret < 0) { + dev_err(&dev->dev, "clock failed to enable: %d\n", ret); + clk_put(sp804_clk); + return ret; + } + + sp804_base = amba_get_mem_region(dev); + + tick_rate = clk_get_rate(sp804_clk); + + /* setup timer 0 as free-running clocksource */ + writel(0, sp804_base + TIMER_CTRL); + writel(0xffffffff, sp804_base + TIMER_LOAD); + writel(0xffffffff, sp804_base + TIMER_VALUE); + writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, + sp804_base + TIMER_CTRL); + + sp804_clksrc.mult = clocksource_hz2mult(tick_rate, sp804_clksrc.shift); + + init_clock(&sp804_clksrc); + + return 0; +} + +static struct amba_id sp804_ids[] = { + { + .id = AMBA_ARM_SP804_ID, + .mask = AMBA_ARM_SP804_ID_MASK, + }, + { 0, 0 }, +}; + +struct amba_driver sp804_driver = { + .drv = { + .name = "sp804", + }, + .probe = sp804_probe, + .id_table = sp804_ids, +}; + +static int sp804_init(void) +{ + return amba_driver_register(&sp804_driver); +} +coredevice_initcall(sp804_init); diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index cb3e3bd3b..a7bbae0bd 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -150,4 +150,32 @@ struct amba_device name##_device = { \ .periphid = id, \ } +#include <io.h> +/* + * Read pid and cid based on size of resource + * they are located at end of region + */ +static inline u32 amba_device_get_pid(void *base, u32 size) +{ + int i; + u32 pid; + + for (pid = 0, i = 0; i < 4; i++) + pid |= (readl(base + size - 0x20 + 4 * i) & 255) << + (i * 8); + + return pid; +} + +static inline u32 amba_device_get_cid(void *base, u32 size) +{ + int i; + u32 cid; + + for (cid = 0, i = 0; i < 4; i++) + cid |= (readl(base + size - 0x10 + 4 * i) & 255) << + (i * 8); + + return cid; +} #endif diff --git a/include/linux/amba/sp804.h b/include/linux/amba/sp804.h new file mode 100644 index 000000000..aba550c37 --- /dev/null +++ b/include/linux/amba/sp804.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * GPLv2 only + */ + +#ifndef __AMBA_SP804_H__ +#define __AMBA_SP804_H__ + +#include <linux/amba/bus.h> +#include <sizes.h> + +#define AMBA_ARM_SP804_ID 0x00141804 +#define AMBA_ARM_SP804_ID_MASK 0x00ffffff + +static inline bool amba_is_arm_sp804(void __iomem *base) +{ + u32 pid, cid; + u32 size = SZ_4K; + + cid = amba_device_get_cid(base, size); + + if (cid != AMBA_CID) + return false; + + pid = amba_device_get_pid(base, size); + + return (pid & AMBA_ARM_SP804_ID_MASK) == AMBA_ARM_SP804_ID; +} +#endif /* __AMBA_SP804_H__ */ diff --git a/include/linux/amba/sp805.h b/include/linux/amba/sp805.h new file mode 100644 index 000000000..b0ff29025 --- /dev/null +++ b/include/linux/amba/sp805.h @@ -0,0 +1,32 @@ +/* + * Watchdog driver for ARM SP805 watchdog module + * + * Copyright (C) 2010 ST Microelectronics + * Viresh Kumar <viresh.linux@gmail.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2 or later. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __AMBA_SP805_H__ +#define __AMBA_SP805_H__ + +/* watchdog register offsets and masks */ +#define WDTLOAD 0x000 + #define LOAD_MIN 0x00000001 + #define LOAD_MAX 0xFFFFFFFF +#define WDTVALUE 0x004 +#define WDTCONTROL 0x008 + /* control register masks */ + #define INT_ENABLE (1 << 0) + #define RESET_ENABLE (1 << 1) +#define WDTINTCLR 0x00C +#define WDTRIS 0x010 +#define WDTMIS 0x014 + #define INT_MASK (1 << 0) +#define WDTLOCK 0xC00 + #define UNLOCK 0x1ACCE551 + #define LOCK 0x00000001 + +#endif /* __AMBA_SP805_H__ */ |