summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2017-10-19 15:07:38 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2017-10-19 15:07:38 +0200
commitb7893351580db1a4cc34a69a16624a5ef121c888 (patch)
treea234a098b307d0cd0957d5a7d9e2844d09e48aed
parent020d19ddc5beb6385220e4492f856e6db3fb6187 (diff)
parent06cf2ad027fa8a334077958d223ea888226cccff (diff)
downloadbarebox-b7893351580db1a4cc34a69a16624a5ef121c888.tar.gz
barebox-b7893351580db1a4cc34a69a16624a5ef121c888.tar.xz
Merge branch 'for-next/arm'
-rw-r--r--Documentation/boards/arm-qemu-vexpress.rst20
-rw-r--r--arch/arm/boards/vexpress/Makefile2
-rw-r--r--arch/arm/boards/vexpress/defaultenv-vexpress/config38
-rw-r--r--arch/arm/boards/vexpress/init.c144
-rw-r--r--arch/arm/boards/vexpress/lowlevel.c36
-rw-r--r--arch/arm/configs/vexpress_ca9_defconfig52
-rw-r--r--arch/arm/configs/vexpress_defconfig17
-rw-r--r--arch/arm/dts/Makefile2
-rw-r--r--arch/arm/dts/socfpga_cyclone5_sockit.dts108
-rw-r--r--arch/arm/dts/vexpress-v2p-ca15.dts27
-rw-r--r--arch/arm/dts/vexpress-v2p-ca9.dts90
-rw-r--r--arch/arm/mach-vexpress/Kconfig7
-rw-r--r--arch/arm/mach-vexpress/Makefile1
-rw-r--r--arch/arm/mach-vexpress/devices.c83
-rw-r--r--arch/arm/mach-vexpress/include/mach/devices.h9
-rw-r--r--arch/arm/mach-vexpress/v2m.c38
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/vexpress/Makefile1
-rw-r--r--drivers/clk/vexpress/clk-sp810.c136
-rw-r--r--drivers/clk/vexpress/clk-vexpress-osc.c42
-rw-r--r--drivers/clocksource/amba-sp804.c4
-rw-r--r--drivers/mci/mmci.c39
-rw-r--r--drivers/of/base.c18
-rw-r--r--images/Makefile1
-rw-r--r--images/Makefile.vexpress11
-rw-r--r--include/of.h2
26 files changed, 474 insertions, 455 deletions
diff --git a/Documentation/boards/arm-qemu-vexpress.rst b/Documentation/boards/arm-qemu-vexpress.rst
new file mode 100644
index 0000000000..dcbac8e625
--- /dev/null
+++ b/Documentation/boards/arm-qemu-vexpress.rst
@@ -0,0 +1,20 @@
+QEMU vexpress
+=======
+
+ARM Qemu vexpress
+-----------------
+
+Running barebox on QEMU vexpress machine
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Usage::
+
+ $ qemu-system-arm -m 1024M \
+ -machine vexpress-a9 -cpu cortex-a9 \
+ -nographic -no-reboot \
+ -kernel images/barebox-vexpress-ca9.img
+
+ $ qemu-system-arm -m 1024M \
+ -machine vexpress-a15 -cpu cortex-a15 \
+ -nographic -no-reboot \
+ -kernel images/barebox-vexpress-ca15.img
diff --git a/arch/arm/boards/vexpress/Makefile b/arch/arm/boards/vexpress/Makefile
index c89d7bf182..2da0494d49 100644
--- a/arch/arm/boards/vexpress/Makefile
+++ b/arch/arm/boards/vexpress/Makefile
@@ -1,4 +1,2 @@
obj-y += init.o
-
lwl-y += lowlevel.o
-bbenv-$(CONFIG_DEFAULT_ENVIRONMENT_GENERIC) += defaultenv-vexpress
diff --git a/arch/arm/boards/vexpress/defaultenv-vexpress/config b/arch/arm/boards/vexpress/defaultenv-vexpress/config
deleted file mode 100644
index 6c0abda40c..0000000000
--- a/arch/arm/boards/vexpress/defaultenv-vexpress/config
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-# use 'dhcp' to do dhcp in barebox and in kernel
-# use 'none' if you want to skip kernel ip autoconfiguration
-ip=dhcp
-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
index f89dff9392..946385393f 100644
--- a/arch/arm/boards/vexpress/init.c
+++ b/arch/arm/boards/vexpress/init.c
@@ -11,129 +11,23 @@
#include <generated/mach-types.h>
#include <mach/devices.h>
#include <environment.h>
-#include <partition.h>
#include <linux/sizes.h>
#include <io.h>
#include <envfs.h>
#include <globalvar.h>
#include <linux/amba/sp804.h>
-#include <mci.h>
-
-struct vexpress_init {
- void (*core_init)(void);
- void (*mem_init)(void);
- void (*console_init)(void);
- void (*devices_init)(void);
-};
-
-struct mmci_platform_data mmci_plat = {
- .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
- .clkdiv_init = SDI_CLKCR_CLKDIV_INIT,
-};
-
-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);
- vexpress_register_mmc(&mmci_plat);
- add_generic_device("smc911x", DEVICE_ID_DYNAMIC, NULL, 0x1a000000,
- 64 * 1024, IORESOURCE_MEM, NULL);
-}
-
-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);
- vexpress_a9_legacy_register_mmc(&mmci_plat);
- armlinux_set_architecture(MACH_TYPE_VEXPRESS);
-}
-
-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,
-};
-
-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");
-
- if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC))
- defaultenv_append_directory(defaultenv_vexpress);
-
- 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)
{
char *hostname = "vexpress-unknown";
if (amba_is_arm_sp804(IOMEM(0x10011000))) {
- v2m_init = &vexpress_init_a9_legacy;
+ vexpress_a9_legacy_init();
hostname = "vexpress-a9-legacy";
} else {
- v2m_init = &vexpress_init_ax;
+ vexpress_init();
if (cpu_is_cortex_a5())
hostname = "vexpress-a5";
else if (cpu_is_cortex_a7())
@@ -144,11 +38,39 @@ static int vexpress_core_init(void)
hostname = "vexpress-a15";
}
- barebox_set_model("ARM Vexpress");
- barebox_set_hostname(hostname);
+ writel(1, v2m_sysreg_base + V2M_SYS_FLASH);
- v2m_init->core_init();
+ barebox_set_hostname(hostname);
return 0;
}
postcore_initcall(vexpress_core_init);
+
+static int of_fixup_virtio_mmio(struct device_node *root, void *unused)
+{
+ struct device_node *barebox_root, *np, *parent;
+
+ barebox_root = of_get_root_node();
+ if (root == barebox_root)
+ return 0;
+
+ for_each_compatible_node_from(np, barebox_root, NULL, "virtio,mmio") {
+ if (of_get_parent(np) == barebox_root)
+ parent = root;
+ else
+ parent = of_find_node_by_path_from(root,
+ of_get_parent(np)->full_name);
+ if (!parent)
+ return -EINVAL;
+
+ of_copy_node(parent, np);
+ }
+
+ return 0;
+}
+
+static int of_register_virtio_mmio_fixup(void)
+{
+ return of_register_fixup(of_fixup_virtio_mmio, NULL);
+}
+late_initcall(of_register_virtio_mmio_fixup);
diff --git a/arch/arm/boards/vexpress/lowlevel.c b/arch/arm/boards/vexpress/lowlevel.c
index 204d29d8f0..9fe7c836b7 100644
--- a/arch/arm/boards/vexpress/lowlevel.c
+++ b/arch/arm/boards/vexpress/lowlevel.c
@@ -9,14 +9,44 @@
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <asm/system_info.h>
+#include <asm/unaligned.h>
#include <linux/amba/sp804.h>
-void __naked barebox_arm_reset_vector(void)
+static inline void start_vexpress_common(void *internal_dt)
{
+ void *fdt = internal_dt - get_runtime_offset();
+ unsigned long membase, memsize = SZ_512M;
+
arm_cpu_lowlevel_init();
if (amba_is_arm_sp804(IOMEM(0x10011000)))
- barebox_arm_entry(0x60000000, SZ_512M, NULL);
+ membase = 0x60000000;
else
- barebox_arm_entry(0x80000000, SZ_512M, NULL);
+ membase = 0x80000000;
+
+ /* QEMU may put a DTB at the start of RAM */
+ if (IS_ENABLED(CONFIG_OFDEVICE) &&
+ get_unaligned_be32((void*)membase) == FDT_MAGIC) {
+ fdt = (void*)membase;
+ /*
+ * Need to move membase a bit as the PBL wants to relocate
+ * to the start of RAM, which would overwrite the DTB.
+ */
+ membase += SZ_4M;
+ memsize -= SZ_4M;
+ }
+
+ barebox_arm_entry(membase, memsize, fdt);
+}
+
+extern char __dtb_vexpress_v2p_ca9_start[];
+ENTRY_FUNCTION(start_vexpress_ca9, r0, r1, r2)
+{
+ start_vexpress_common(__dtb_vexpress_v2p_ca9_start);
+}
+
+extern char __dtb_vexpress_v2p_ca15_start[];
+ENTRY_FUNCTION(start_vexpress_ca15, r0, r1, r2)
+{
+ start_vexpress_common(__dtb_vexpress_v2p_ca15_start);
}
diff --git a/arch/arm/configs/vexpress_ca9_defconfig b/arch/arm/configs/vexpress_ca9_defconfig
deleted file mode 100644
index a1c42512d2..0000000000
--- a/arch/arm/configs/vexpress_ca9_defconfig
+++ /dev/null
@@ -1,52 +0,0 @@
-CONFIG_ARCH_VEXPRESS=y
-CONFIG_AEABI=y
-CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
-CONFIG_TEXT_BASE=0x63f00000
-CONFIG_MALLOC_TLSF=y
-CONFIG_PROMPT="vexpress: "
-CONFIG_GLOB=y
-CONFIG_HUSH_FANCY_PROMPT=y
-CONFIG_CMDLINE_EDITING=y
-CONFIG_AUTO_COMPLETE=y
-CONFIG_MENU=y
-CONFIG_BOOTM_SHOW_TYPE=y
-CONFIG_BOOTM_VERBOSE=y
-CONFIG_BOOTM_INITRD=y
-CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
-CONFIG_LONGHELP=y
-CONFIG_CMD_MEMINFO=y
-# CONFIG_CMD_BOOTU is not set
-CONFIG_CMD_GO=y
-CONFIG_CMD_LOADB=y
-CONFIG_CMD_RESET=y
-CONFIG_CMD_UIMAGE=y
-CONFIG_CMD_PARTITION=y
-CONFIG_CMD_EXPORT=y
-CONFIG_CMD_PRINTENV=y
-CONFIG_CMD_SAVEENV=y
-CONFIG_CMD_UNCOMPRESS=y
-CONFIG_CMD_SLEEP=y
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_TFTP=y
-CONFIG_CMD_ECHO_E=y
-CONFIG_CMD_EDIT=y
-CONFIG_CMD_LOGIN=y
-CONFIG_CMD_MENU=y
-CONFIG_CMD_MENU_MANAGEMENT=y
-CONFIG_CMD_PASSWD=y
-CONFIG_CMD_READLINE=y
-CONFIG_CMD_TIMEOUT=y
-CONFIG_CMD_CLK=y
-CONFIG_CMD_OFTREE=y
-CONFIG_NET=y
-CONFIG_NET_NFS=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_FS_TFTP=y
-CONFIG_DIGEST_SHA1_GENERIC=y
-CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig
index 94fe1eaa72..f6a57de75c 100644
--- a/arch/arm/configs/vexpress_defconfig
+++ b/arch/arm/configs/vexpress_defconfig
@@ -1,9 +1,9 @@
CONFIG_ARCH_VEXPRESS=y
CONFIG_AEABI=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MALLOC_SIZE=0x0
CONFIG_MALLOC_TLSF=y
CONFIG_PROMPT="vexpress: "
-CONFIG_GLOB=y
CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
@@ -11,9 +11,10 @@ CONFIG_MENU=y
CONFIG_BOOTM_SHOW_TYPE=y
CONFIG_BOOTM_VERBOSE=y
CONFIG_BOOTM_INITRD=y
-CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_CMD_DMESG=y
CONFIG_LONGHELP=y
+CONFIG_CMD_IOMEM=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_BOOTU is not set
CONFIG_CMD_GO=y
@@ -37,15 +38,25 @@ CONFIG_CMD_MENU_MANAGEMENT=y
CONFIG_CMD_PASSWD=y
CONFIG_CMD_READLINE=y
CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
CONFIG_CMD_CLK=y
+CONFIG_CMD_DETECT=y
CONFIG_CMD_OFTREE=y
CONFIG_NET=y
CONFIG_NET_NFS=y
CONFIG_NET_NETCONSOLE=y
CONFIG_NET_RESOLV=y
+CONFIG_OF_BAREBOX_DRIVERS=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_DRIVER_NET_SMC91111=y
# CONFIG_SPI is not set
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_DRIVER_CFI=y
+CONFIG_MCI=y
+CONFIG_MCI_MMCI=y
+# CONFIG_PINCTRL is not set
CONFIG_FS_TFTP=y
CONFIG_DIGEST_SHA1_GENERIC=y
CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index cf9d8ea940..b5601a61c5 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -91,6 +91,8 @@ pbl-dtb-$(CONFIG_MACH_TURRIS_OMNIA) += armada-385-turris-omnia-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o
pbl-dtb-$(CONFIG_MACH_USI_TOPKICK) += kirkwood-topkick-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o
+pbl-dtb-$(CONFIG_MACH_VEXPRESS) += vexpress-v2p-ca9.dtb.o
+pbl-dtb-$(CONFIG_MACH_VEXPRESS) += vexpress-v2p-ca15.dtb.o
pbl-dtb-$(CONFIG_MACH_VSCOM_BALTOS) += am335x-baltos-minimal.dtb.o
pbl-dtb-$(CONFIG_MACH_WARP7) += imx7s-warp.dtb.o
pbl-dtb-$(CONFIG_MACH_VF610_TWR) += vf610-twr.dtb.o
diff --git a/arch/arm/dts/socfpga_cyclone5_sockit.dts b/arch/arm/dts/socfpga_cyclone5_sockit.dts
index 8df5ed4775..7cb9b96005 100644
--- a/arch/arm/dts/socfpga_cyclone5_sockit.dts
+++ b/arch/arm/dts/socfpga_cyclone5_sockit.dts
@@ -25,112 +25,4 @@
chosen {
stdout-path = &uart0;
};
-
- leds: gpio-leds {
- };
-
- buttons: gpio-keys {
- };
-};
-
-&gpio1 {
- status = "okay";
-};
-
-&gpio2 {
- status = "okay";
-};
-
-&leds {
- compatible = "gpio-leds";
-
- led@0 {
- label = "0";
- gpios = <&portb 24 0>;
- linux,default-trigger = "heartbeat";
- };
-
- led@1 {
- label = "1";
- gpios = <&portb 25 0>;
- };
-
- led@2 {
- label = "2";
- gpios = <&portb 26 0>;
- };
-
- led@3 {
- label = "3";
- gpios = <&portb 27 0>;
- };
-};
-
-&buttons {
- compatible = "gpio-keys";
-
- key@0 {
- label = "F1";
- gpios = <&portc 21 0>;
- linux,code = <59>;
- };
-
- key@1 {
- label = "F2";
- gpios = <&portc 22 0>;
- linux,code = <60>;
- };
-
- key@2 {
- label = "F3";
- gpios = <&portc 23 0>;
- linux,code = <61>;
- };
-
- key@3 {
- label = "F4";
- gpios = <&portc 24 0>;
- linux,code = <62>;
- };
-};
-
-&i2c0 {
- status = "disabled";
-
- eeprom@51 {
- compatible = "atmel,24c32";
- reg = <0x51>;
- pagesize = <0x20>;
- };
-};
-
-&i2c1 {
- status = "disabled";
-
- adxl345@53 {
- compatible = "adi,adxl34x";
- reg = <0x53>;
- interrupt-parent = <0x2>;
- interrupts = <0x0 0xa6 0x4>;
- };
-};
-
-&qspi {
- status = "okay";
-
- flash: flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "n25q00";
- reg = <0>;
- spi-max-frequency = <108000000>;
- m25p,fast-read;
- cdns,page-size = <256>;
- cdns,block-size = <16>;
- cdns,read-delay = <4>;
- cdns,tshsl-ns = <50>;
- cdns,tsd2d-ns = <50>;
- cdns,tchsh-ns = <4>;
- cdns,tslch-ns = <4>;
- };
};
diff --git a/arch/arm/dts/vexpress-v2p-ca15.dts b/arch/arm/dts/vexpress-v2p-ca15.dts
new file mode 100644
index 0000000000..211eaccb62
--- /dev/null
+++ b/arch/arm/dts/vexpress-v2p-ca15.dts
@@ -0,0 +1,27 @@
+#include <arm/vexpress-v2p-ca15_a7.dts>
+
+/ {
+ barebox_environment {
+ compatible = "barebox,environment";
+ device-path = &barebox_env;
+ };
+
+ smb@8000000 {
+ motherboard {
+ flash@0,00000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "barebox";
+ reg = <0x0 0x80000>;
+ };
+
+ barebox_env: partition@80000 {
+ label = "barebox-environment";
+ reg = <0x80000 0x80000>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/dts/vexpress-v2p-ca9.dts b/arch/arm/dts/vexpress-v2p-ca9.dts
new file mode 100644
index 0000000000..d0975330f2
--- /dev/null
+++ b/arch/arm/dts/vexpress-v2p-ca9.dts
@@ -0,0 +1,90 @@
+#include <arm/vexpress-v2p-ca9.dts>
+
+/ {
+ barebox_environment {
+ compatible = "barebox,environment";
+ device-path = &barebox_env;
+ };
+
+ aliases {
+ state = &state;
+ };
+
+ smb@4000000 {
+ motherboard {
+ flash@0,00000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "barebox";
+ reg = <0x0 0x80000>;
+ };
+
+ barebox_env: partition@80000 {
+ label = "barebox-environment";
+ reg = <0x80000 0x80000>;
+ };
+
+ state_storage: partition@100000 {
+ label = "barebox-state";
+ reg = <0x100000 0x100000>;
+ };
+ };
+ };
+ };
+
+ /* State: mutable part */
+ state: state {
+ magic = <0x4d433230>;
+ compatible = "barebox,state";
+ backend-type = "raw";
+ backend = <&state_storage>;
+ backend-stridesize = <0x40>;
+ backend-storage-type = "circular";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ bootstate {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ system0 { /* the node's name here must match the subnode's name in the 'bootstate' node */
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ remaining_attempts@0 {
+ reg = <0x0 0x4>;
+ type = "uint32";
+ default = <3>;
+ };
+ priority@4 {
+ reg = <0x4 0x4>;
+ type = "uint32";
+ default = <20>;
+ };
+ };
+
+ system1 { /* the node's name here must match the subnode's name in the 'bootstate' node */
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ remaining_attempts@8 {
+ reg = <0x8 0x4>;
+ type = "uint32";
+ default = <3>;
+ };
+ priority@c {
+ reg = <0xC 0x4>;
+ type = "uint32";
+ default = <20>;
+ };
+ };
+
+ last_chosen@10 {
+ reg = <0x10 0x4>;
+ type = "uint32";
+ };
+ };
+ };
+};
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index bf1dd5a791..aaa535f073 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -2,13 +2,18 @@ if ARCH_VEXPRESS
config ARCH_TEXT_BASE
hex
- default 0x83f00000
+ default 0x0
choice
prompt "ARM Board type"
config MACH_VEXPRESS
bool "ARM Vexpress"
+ select RELOCATABLE
+ select HAVE_PBL_MULTI_IMAGES
+ select OFTREE
+ select OFDEVICE
+ select COMMON_CLK_OF_PROVIDER
endchoice
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 74b4a0feb2..9a06e648a6 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -1,3 +1,2 @@
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
deleted file mode 100644
index 5b53011924..0000000000
--- a/arch/arm/mach-vexpress/devices.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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_a9_legacy_register_mmc(struct mmci_platform_data *plat)
-{
- amba_apb_device_add(NULL, "mmci-pl18x", DEVICE_ID_SINGLE, 0x10005000,
- 4096, plat, 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);
-}
-
-void vexpress_register_mmc(struct mmci_platform_data *plat)
-{
- amba_apb_device_add(NULL, "mmci-pl18x", DEVICE_ID_SINGLE, 0x1c050000, 4096, plat, 0);
-}
diff --git a/arch/arm/mach-vexpress/include/mach/devices.h b/arch/arm/mach-vexpress/include/mach/devices.h
index 96d1400501..bef8c8b94f 100644
--- a/arch/arm/mach-vexpress/include/mach/devices.h
+++ b/arch/arm/mach-vexpress/include/mach/devices.h
@@ -9,18 +9,9 @@
#include <linux/amba/mmci.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);
-void vexpress_a9_legacy_register_mmc(struct mmci_platform_data *plat);
-void vexpress_register_mmc(struct mmci_platform_data *plat);
-
extern void *v2m_wdt_base;
extern void *v2m_sysreg_base;
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 025bbb17fc..3535262848 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -19,31 +19,6 @@
void __iomem *v2m_sysreg_base;
-static const char *v2m_osc2_periphs[] = {
- "mb:mmci", "mmci-pl18x", /* PL180 MMCI */
- "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;
@@ -58,21 +33,11 @@ static void v2m_sysctl_init(void __iomem *base)
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)
@@ -80,7 +45,4 @@ 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/clk/Makefile b/drivers/clk/Makefile
index b5abe1cdf5..a36a8db03b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_CLK_SOCFPGA) += socfpga/
obj-$(CONFIG_MACH_MIPS_ATH79) += clk-ar933x.o
obj-$(CONFIG_ARCH_IMX) += imx/
obj-$(CONFIG_COMMON_CLK_AT91) += at91/
+obj-$(CONFIG_MACH_VEXPRESS) += vexpress/
diff --git a/drivers/clk/vexpress/Makefile b/drivers/clk/vexpress/Makefile
new file mode 100644
index 0000000000..c6869bac83
--- /dev/null
+++ b/drivers/clk/vexpress/Makefile
@@ -0,0 +1 @@
+obj-y += clk-vexpress-osc.o clk-sp810.o
diff --git a/drivers/clk/vexpress/clk-sp810.c b/drivers/clk/vexpress/clk-sp810.c
new file mode 100644
index 0000000000..af72c74024
--- /dev/null
+++ b/drivers/clk/vexpress/clk-sp810.c
@@ -0,0 +1,136 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2013 ARM Limited
+ */
+
+#include <common.h>
+#include <io.h>
+#include <malloc.h>
+#include <of_address.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+/* sysctl registers offset */
+#define SCCTRL 0x000
+#define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2))
+
+struct clk_sp810;
+
+struct clk_sp810_timerclken {
+ struct clk hw;
+ struct clk_sp810 *sp810;
+ int channel;
+};
+
+static inline struct clk_sp810_timerclken *
+to_clk_sp810_timerclken(struct clk *clk)
+{
+ return container_of(clk, struct clk_sp810_timerclken, hw);
+}
+
+struct clk_sp810 {
+ struct device_node *node;
+ void __iomem *base;
+ struct clk_sp810_timerclken timerclken[4];
+};
+
+static int clk_sp810_timerclken_get_parent(struct clk *hw)
+{
+ struct clk_sp810_timerclken *timerclken = to_clk_sp810_timerclken(hw);
+ u32 val = readl(timerclken->sp810->base + SCCTRL);
+
+ return !!(val & (1 << SCCTRL_TIMERENnSEL_SHIFT(timerclken->channel)));
+}
+
+static int clk_sp810_timerclken_set_parent(struct clk *hw, u8 index)
+{
+ struct clk_sp810_timerclken *timerclken = to_clk_sp810_timerclken(hw);
+ struct clk_sp810 *sp810 = timerclken->sp810;
+ u32 val, shift = SCCTRL_TIMERENnSEL_SHIFT(timerclken->channel);
+
+ if (WARN_ON(index > 1))
+ return -EINVAL;
+
+ val = readl(sp810->base + SCCTRL);
+ val &= ~(1 << shift);
+ val |= index << shift;
+ writel(val, sp810->base + SCCTRL);
+
+ return 0;
+}
+
+static const struct clk_ops clk_sp810_timerclken_ops = {
+ .get_parent = clk_sp810_timerclken_get_parent,
+ .set_parent = clk_sp810_timerclken_set_parent,
+};
+
+static struct clk *clk_sp810_timerclken_of_get(struct of_phandle_args *clkspec,
+ void *data)
+{
+ struct clk_sp810 *sp810 = data;
+
+ if (WARN_ON(clkspec->args_count != 1 ||
+ clkspec->args[0] >= ARRAY_SIZE(sp810->timerclken)))
+ return NULL;
+
+ return &sp810->timerclken[clkspec->args[0]].hw;
+}
+
+static void clk_sp810_of_setup(struct device_node *node)
+{
+ struct clk_sp810 *sp810 = xzalloc(sizeof(*sp810));
+ const char *parent_names[2];
+ int num = ARRAY_SIZE(parent_names);
+ char name[12];
+ static int instance;
+ int i;
+ bool deprecated;
+
+ if (!sp810)
+ return;
+
+ if (of_clk_parent_fill(node, parent_names, num) != num) {
+ pr_warn("Failed to obtain parent clocks for SP810!\n");
+ kfree(sp810);
+ return;
+ }
+
+ sp810->node = node;
+ sp810->base = of_iomap(node, 0);
+
+ deprecated = !of_find_property(node, "assigned-clock-parents", NULL);
+
+ for (i = 0; i < ARRAY_SIZE(sp810->timerclken); i++) {
+ snprintf(name, sizeof(name), "sp810_%d_%d", instance, i);
+
+ sp810->timerclken[i].sp810 = sp810;
+ sp810->timerclken[i].channel = i;
+ sp810->timerclken[i].hw.name = strdup(name);
+ sp810->timerclken[i].hw.parent_names = parent_names;
+ sp810->timerclken[i].hw.num_parents = num;
+ sp810->timerclken[i].hw.ops = &clk_sp810_timerclken_ops;
+
+ /*
+ * If DT isn't setting the parent, force it to be
+ * the 1 MHz clock without going through the framework.
+ * We do this before clk_register() so that it can determine
+ * the parent and setup the tree properly.
+ */
+ if (deprecated)
+ clk_sp810_timerclken_set_parent(&sp810->timerclken[i].hw, 1);
+
+ clk_register(&sp810->timerclken[i].hw);
+ }
+
+ of_clk_add_provider(node, clk_sp810_timerclken_of_get, sp810);
+ instance++;
+}
+CLK_OF_DECLARE(sp810, "arm,sp810", clk_sp810_of_setup);
diff --git a/drivers/clk/vexpress/clk-vexpress-osc.c b/drivers/clk/vexpress/clk-vexpress-osc.c
new file mode 100644
index 0000000000..c0d6e6066e
--- /dev/null
+++ b/drivers/clk/vexpress/clk-vexpress-osc.c
@@ -0,0 +1,42 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+/*
+ * This represents the vexpress-osc as a fixed clock, which isn't really
+ * accurate, as this clock allows rate changes in real implementations. As those
+ * would need access to the config bus, a whole lot more infrastructure would be
+ * needed. We skip this complication for now, as we don't have a use-case, yet.
+ */
+static int vexpress_osc_setup(struct device_node *node)
+{
+ struct clk *clk;
+ u32 range[2];
+ const char *name;
+
+ if (of_property_read_u32_array(node, "freq-range", range,
+ ARRAY_SIZE(range)))
+ return -EINVAL;
+
+ if (of_property_read_string(node, "clock-output-names", &name))
+ return -EINVAL;
+
+ clk = clk_fixed(name, range[0]);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ return of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(vexpress_osc, "arm,vexpress-osc", vexpress_osc_setup);
diff --git a/drivers/clocksource/amba-sp804.c b/drivers/clocksource/amba-sp804.c
index c5ad9947cd..66e3988b4c 100644
--- a/drivers/clocksource/amba-sp804.c
+++ b/drivers/clocksource/amba-sp804.c
@@ -35,8 +35,8 @@ static int sp804_probe(struct amba_device *dev, const struct amba_id *id)
int ret;
if (sp804_base) {
- dev_err(&dev->dev, "single instance driver\n");
- return -EBUSY;
+ dev_dbg(&dev->dev, "skipping secondary instance\n");
+ return 0;
}
sp804_clk = clk_get(&dev->dev, NULL);
diff --git a/drivers/mci/mmci.c b/drivers/mci/mmci.c
index 7489ee03a1..f45557d4f7 100644
--- a/drivers/mci/mmci.c
+++ b/drivers/mci/mmci.c
@@ -532,9 +532,37 @@ static void mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
udelay(CLK_CHANGE_DELAY);
}
+static int mmci_of_parse(struct device_node *np,
+ struct mmci_platform_data *plat)
+{
+ if (!IS_ENABLED(CONFIG_OFDEVICE))
+ return 0;
+
+ if (of_get_property(np, "st,sig-dir-dat0", NULL))
+ plat->sigdir |= MCI_ST_DATA0DIREN;
+ if (of_get_property(np, "st,sig-dir-dat2", NULL))
+ plat->sigdir |= MCI_ST_DATA2DIREN;
+ if (of_get_property(np, "st,sig-dir-dat31", NULL))
+ plat->sigdir |= MCI_ST_DATA31DIREN;
+ if (of_get_property(np, "st,sig-dir-dat74", NULL))
+ plat->sigdir |= MCI_ST_DATA74DIREN;
+ if (of_get_property(np, "st,sig-dir-cmd", NULL))
+ plat->sigdir |= MCI_ST_CMDDIREN;
+ if (of_get_property(np, "st,sig-pin-fbclk", NULL))
+ plat->sigdir |= MCI_ST_FBCLKEN;
+
+ if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL))
+ plat->capabilities |= MMC_CAP_MMC_HIGHSPEED;
+ if (of_get_property(np, "mmc-cap-sd-highspeed", NULL))
+ plat->capabilities |= MMC_CAP_SD_HIGHSPEED;
+
+ return 0;
+}
+
static int mmci_probe(struct amba_device *dev, const struct amba_id *id)
{
struct device_d *hw_dev = &dev->dev;
+ struct device_node *np = hw_dev->device_node;
struct mmci_platform_data *plat = hw_dev->platform_data;
struct variant_data *variant = id->data;
u32 sdi_u32;
@@ -542,11 +570,16 @@ static int mmci_probe(struct amba_device *dev, const struct amba_id *id)
struct clk *clk;
int ret;
- if (!plat) {
- dev_err(hw_dev, "missing platform data\n");
+ if (!plat && !np) {
+ dev_err(hw_dev, "missing platform data or DT node\n");
return -EINVAL;
}
+ if (!plat)
+ plat = xzalloc(sizeof(*plat));
+
+ mmci_of_parse(np, plat);
+
host = xzalloc(sizeof(*host));
host->base = amba_get_mem_region(dev);
@@ -625,7 +658,7 @@ static int mmci_probe(struct amba_device *dev, const struct amba_id *id)
host->mci.max_req_size = (1 << variant->datalength_bits) - 1;
host->mci.host_caps = plat->capabilities;
- host->mci.voltages = plat->ocr_mask;
+ host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | plat->ocr_mask;
mci_register(&host->mci);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 95bea4ee83..3ca13ae44e 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1938,8 +1938,8 @@ int of_probe(void)
if (memory)
of_add_memory(memory, false);
- of_platform_populate(root_node, of_default_bus_match_table, NULL);
of_clk_init(root_node, NULL);
+ of_platform_populate(root_node, of_default_bus_match_table, NULL);
return 0;
}
@@ -1988,6 +1988,22 @@ out:
return dn;
}
+struct device_node *of_copy_node(struct device_node *parent, const struct device_node *other)
+{
+ struct device_node *np, *child;
+ struct property *pp;
+
+ np = of_new_node(parent, other->name);
+
+ list_for_each_entry(pp, &other->properties, list)
+ of_new_property(np, pp->name, pp->value, pp->length);
+
+ for_each_child_of_node(other, child)
+ of_copy_node(np, child);
+
+ return np;
+}
+
void of_delete_node(struct device_node *node)
{
struct device_node *n, *nt;
diff --git a/images/Makefile b/images/Makefile
index 705c8ad03e..5c4d99ac5a 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -111,6 +111,7 @@ include $(srctree)/images/Makefile.omap3
include $(srctree)/images/Makefile.rockchip
include $(srctree)/images/Makefile.socfpga
include $(srctree)/images/Makefile.tegra
+include $(srctree)/images/Makefile.vexpress
include $(srctree)/images/Makefile.at91
targets += $(image-y) pbl.lds barebox.x barebox.z
diff --git a/images/Makefile.vexpress b/images/Makefile.vexpress
new file mode 100644
index 0000000000..0f12dc12a5
--- /dev/null
+++ b/images/Makefile.vexpress
@@ -0,0 +1,11 @@
+#
+# barebox image generation Makefile for VExpress images
+#
+
+pblx-$(CONFIG_MACH_VEXPRESS) += start_vexpress_ca9
+FILE_barebox-vexpress-ca9.img = start_vexpress_ca9.pblx
+image-$(CONFIG_MACH_VEXPRESS) += barebox-vexpress-ca9.img
+
+pblx-$(CONFIG_MACH_VEXPRESS) += start_vexpress_ca15
+FILE_barebox-vexpress-ca15.img = start_vexpress_ca15.pblx
+image-$(CONFIG_MACH_VEXPRESS) += barebox-vexpress-ca15.img
diff --git a/include/of.h b/include/of.h
index 9ba771a395..18a423241b 100644
--- a/include/of.h
+++ b/include/of.h
@@ -144,6 +144,8 @@ extern struct device_node *of_new_node(struct device_node *parent,
const char *name);
extern struct device_node *of_create_node(struct device_node *root,
const char *path);
+extern struct device_node *of_copy_node(struct device_node *parent,
+ const struct device_node *other);
extern void of_delete_node(struct device_node *node);
extern int of_machine_is_compatible(const char *compat);