summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig23
-rw-r--r--arch/arm/boards/Makefile3
-rw-r--r--arch/arm/boards/element14-warp7/Makefile2
-rw-r--r--arch/arm/boards/element14-warp7/board.c35
-rw-r--r--arch/arm/boards/element14-warp7/flash-header-mx7-warp.imxcfg81
-rw-r--r--arch/arm/boards/element14-warp7/lowlevel.c48
-rw-r--r--arch/arm/boards/freescale-mx6-sabresd/lowlevel.c9
-rw-r--r--arch/arm/boards/freescale-vf610-twr/lowlevel.c6
-rw-r--r--arch/arm/boards/zii-imx6q-rdu2/Makefile2
-rw-r--r--arch/arm/boards/zii-imx6q-rdu2/board.c171
-rw-r--r--arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/init/automount17
-rw-r--r--arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/network/eth118
-rw-r--r--arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/nv/boot.default1
-rw-r--r--arch/arm/boards/zii-imx6q-rdu2/flash-header-imx6q-rdu2.imxcfg87
-rw-r--r--arch/arm/boards/zii-imx6q-rdu2/flash-header-imx6qp-rdu2.imxcfg132
-rw-r--r--arch/arm/boards/zii-imx6q-rdu2/lowlevel.c66
-rw-r--r--arch/arm/boards/zii-vf610-dev/Makefile3
-rw-r--r--arch/arm/boards/zii-vf610-dev/board.c149
-rw-r--r--arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/boot/sd4
-rw-r--r--arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/automount-sd13
-rw-r--r--arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/choose-dtb4
-rw-r--r--arch/arm/boards/zii-vf610-dev/flash-header-zii-vf610-dev.imxcfg243
-rw-r--r--arch/arm/boards/zii-vf610-dev/lowlevel.c137
-rw-r--r--arch/arm/configs/zii_vf610_dev_defconfig165
-rw-r--r--arch/arm/cpu/Makefile4
-rw-r--r--arch/arm/cpu/psci.c311
-rw-r--r--arch/arm/cpu/sm.c266
-rw-r--r--arch/arm/cpu/sm_as.S168
-rw-r--r--arch/arm/cpu/smccc-call.S64
-rw-r--r--arch/arm/dts/Makefile9
-rw-r--r--arch/arm/dts/imx6q-zii-rdu2.dts52
-rw-r--r--arch/arm/dts/imx6qdl-zii-rdu2.dtsi541
-rw-r--r--arch/arm/dts/imx6qp-zii-rdu2.dts52
-rw-r--r--arch/arm/dts/imx7s-warp.dts62
-rw-r--r--arch/arm/dts/imx7s.dtsi4
-rw-r--r--arch/arm/dts/vf610-zii-cfu1-rev-a.dts208
-rw-r--r--arch/arm/dts/vf610-zii-dev-rev-b.dts431
-rw-r--r--arch/arm/dts/vf610-zii-dev-rev-c.dts445
-rw-r--r--arch/arm/dts/vf610-zii-dev.dtsi436
-rw-r--r--arch/arm/dts/vf610-zii-scu4-aib-rev-c.dts457
-rw-r--r--arch/arm/dts/vf610-zii-spu3-rev-a.dts140
-rw-r--r--arch/arm/include/asm/arm-smccc.h104
-rw-r--r--arch/arm/include/asm/armlinux.h4
-rw-r--r--arch/arm/include/asm/gic.h110
-rw-r--r--arch/arm/include/asm/psci.h140
-rw-r--r--arch/arm/include/asm/ptrace.h1
-rw-r--r--arch/arm/include/asm/secure.h39
-rw-r--r--arch/arm/include/asm/unwind.h6
-rw-r--r--arch/arm/lib/bootm.c14
-rw-r--r--arch/arm/lib/bootu.c2
-rw-r--r--arch/arm/lib32/armlinux.c15
-rw-r--r--arch/arm/lib32/barebox.lds.S10
-rw-r--r--arch/arm/lib32/bootz.c2
-rw-r--r--arch/arm/lib64/armlinux.c3
-rw-r--r--arch/arm/mach-imx/Kconfig25
-rw-r--r--arch/arm/mach-imx/Makefile1
-rw-r--r--arch/arm/mach-imx/boot.c70
-rw-r--r--arch/arm/mach-imx/clocksource.c3
-rw-r--r--arch/arm/mach-imx/cpu_init.c5
-rw-r--r--arch/arm/mach-imx/esdctl.c3
-rw-r--r--arch/arm/mach-imx/imx.c8
-rw-r--r--arch/arm/mach-imx/imx6.c3
-rw-r--r--arch/arm/mach-imx/imx7.c202
-rw-r--r--arch/arm/mach-imx/include/mach/debug_ll.h3
-rw-r--r--arch/arm/mach-imx/include/mach/generic.h16
-rw-r--r--arch/arm/mach-imx/include/mach/imx6-fusemap.h42
-rw-r--r--arch/arm/mach-imx/include/mach/imx6.h59
-rw-r--r--arch/arm/mach-imx/include/mach/imx7-regs.h119
-rw-r--r--arch/arm/mach-imx/include/mach/imx7.h59
-rw-r--r--arch/arm/mach-imx/include/mach/imx_cpu_types.h1
-rw-r--r--arch/arm/mach-imx/include/mach/iomux-v3.h61
-rw-r--r--arch/arm/mach-imx/include/mach/iomux-vf610.h19
-rw-r--r--arch/arm/mach-imx/include/mach/ocotp-fusemap.h49
-rw-r--r--arch/arm/mach-imx/include/mach/ocotp.h1
-rw-r--r--arch/arm/mach-imx/include/mach/vf610-fusemap.h15
-rw-r--r--arch/arm/mach-imx/ocotp.c93
76 files changed, 6272 insertions, 104 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3e8ccf7..e4663ea 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -383,6 +383,29 @@ config ARM_SEMIHOSTING
the data on the host computer connected to the target via
debugging channel (JTAG, SWD). If unsure say N
+config ARM_SECURE_MONITOR
+ bool
+
+config ARM_PSCI
+ bool "enable Power State Coordination Interface (PSCI) support"
+ depends on CPU_V7
+ select ARM_SECURE_MONITOR
+ help
+ PSCI is used for controlling secondary CPU cores on some systems. Say
+ yes here if you have one of these.
+
+config ARM_PSCI_DEBUG
+ bool "Enable PSCI debugging"
+ depends on ARM_PSCI
+ help
+ This enables debug output from the PSCI functions during runtime of the
+ Kernel. This needs board specific help, the board needs to provide a putc
+ function using psci_set_putc(). This putc function will then be called
+ during runtime of the Kernel, so it must be able to cope with that. It may
+ happen for example that the Kernel has turned off some clocks needed in the
+ putc function.
+ Only use for debugging.
+
endmenu
source common/Kconfig
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index ff0a86f..250ccb8 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -140,4 +140,7 @@ obj-$(CONFIG_MACH_ZYLONITE) += zylonite/
obj-$(CONFIG_MACH_VARISCITE_MX6) += variscite-mx6/
obj-$(CONFIG_MACH_VSCOM_BALTOS) += vscom-baltos/
obj-$(CONFIG_MACH_QEMU_VIRT64) += qemu-virt64/
+obj-$(CONFIG_MACH_WARP7) += element14-warp7/
obj-$(CONFIG_MACH_VF610_TWR) += freescale-vf610-twr/
+obj-$(CONFIG_MACH_ZII_RDU2) += zii-imx6q-rdu2/
+obj-$(CONFIG_MACH_ZII_VF610_DEV) += zii-vf610-dev/
diff --git a/arch/arm/boards/element14-warp7/Makefile b/arch/arm/boards/element14-warp7/Makefile
new file mode 100644
index 0000000..01c7a25
--- /dev/null
+++ b/arch/arm/boards/element14-warp7/Makefile
@@ -0,0 +1,2 @@
+obj-y += board.o
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/element14-warp7/board.c b/arch/arm/boards/element14-warp7/board.c
new file mode 100644
index 0000000..84fc885
--- /dev/null
+++ b/arch/arm/boards/element14-warp7/board.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <init.h>
+#include <environment.h>
+#include <mach/bbu.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <partition.h>
+#include <mach/generic.h>
+#include <linux/sizes.h>
+
+static int warp7_devices_init(void)
+{
+ if (!of_machine_is_compatible("warp,imx7s-warp"))
+ return 0;
+
+ imx6_bbu_internal_mmc_register_handler("mmc", "/dev/mmc2.boot0.barebox",
+ BBU_HANDLER_FLAG_DEFAULT);
+
+ return 0;
+}
+device_initcall(warp7_devices_init);
diff --git a/arch/arm/boards/element14-warp7/flash-header-mx7-warp.imxcfg b/arch/arm/boards/element14-warp7/flash-header-mx7-warp.imxcfg
new file mode 100644
index 0000000..a338921
--- /dev/null
+++ b/arch/arm/boards/element14-warp7/flash-header-mx7-warp.imxcfg
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 NXP Semiconductors
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * Refer docs/README.imxmage for more details about how-to configure
+ * and create imximage boot image
+ *
+ * The syntax is taken as close as possible with the kwbimage
+ */
+
+soc imx7
+loadaddr 0x80000000
+dcdofs 0x400
+
+wm 32 0x30340004 0x4F400005
+
+wm 32 0x30391000 0x00000002
+wm 32 0x307a0000 0x03040008
+wm 32 0x307a0064 0x00200038
+wm 32 0x307a0490 0x00000001
+wm 32 0x307a00d0 0x00350001
+wm 32 0x307a00dc 0x00c3000a
+wm 32 0x307a00e0 0x00010000
+wm 32 0x307a00e4 0x00110006
+wm 32 0x307a00f4 0x0000033f
+wm 32 0x307a0100 0x0a0e110b
+wm 32 0x307a0104 0x00020211
+wm 32 0x307a0108 0x03060708
+wm 32 0x307a010c 0x00a0500c
+wm 32 0x307a0110 0x05020307
+wm 32 0x307a0114 0x02020404
+wm 32 0x307a0118 0x02020003
+wm 32 0x307a011c 0x00000202
+wm 32 0x307a0120 0x00000202
+
+wm 32 0x307a0180 0x00600018
+wm 32 0x307a0184 0x00e00100
+wm 32 0x307a0190 0x02098205
+wm 32 0x307a0194 0x00060303
+wm 32 0x307a01a0 0x80400003
+wm 32 0x307a01a4 0x00100020
+wm 32 0x307a01a8 0x80100004
+
+wm 32 0x307a0200 0x00000015
+wm 32 0x307a0204 0x00161616
+wm 32 0x307a0210 0x00000f0f
+wm 32 0x307a0214 0x04040404
+wm 32 0x307a0218 0x0f0f0404
+
+wm 32 0x307a0240 0x06000600
+wm 32 0x307a0244 0x00000000
+wm 32 0x30391000 0x00000000
+wm 32 0x30790000 0x17421e40
+wm 32 0x30790004 0x10210100
+wm 32 0x30790008 0x00010000
+wm 32 0x30790010 0x0007080c
+wm 32 0x307900b0 0x1010007e
+
+wm 32 0x3079001C 0x01010000
+wm 32 0x3079009c 0x00000d6e
+
+wm 32 0x30790030 0x06060606
+wm 32 0x30790020 0x0a0a0a0a
+wm 32 0x30790050 0x01000008
+wm 32 0x30790050 0x00000008
+wm 32 0x30790018 0x0000000f
+wm 32 0x307900c0 0x0e487304
+wm 32 0x307900c0 0x0e4c7304
+wm 32 0x307900c0 0x0e4c7306
+wm 32 0x307900c0 0x0e4c7304
+
+check 32 while_any_bit_clear 0x307900c4 0x1
+
+wm 32 0x307900c0 0x0e487304
+
+wm 32 0x30384130 0x00000000
+wm 32 0x30340020 0x00000178
+wm 32 0x30384130 0x00000002
+
+check 32 while_any_bit_clear 0x307a0004 0x1
diff --git a/arch/arm/boards/element14-warp7/lowlevel.c b/arch/arm/boards/element14-warp7/lowlevel.c
new file mode 100644
index 0000000..38b7745
--- /dev/null
+++ b/arch/arm/boards/element14-warp7/lowlevel.c
@@ -0,0 +1,48 @@
+#define DEBUG
+#include <io.h>
+#include <common.h>
+#include <linux/sizes.h>
+#include <mach/generic.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <mach/debug_ll.h>
+#include <asm/cache.h>
+
+extern char __dtb_imx7s_warp_start[];
+
+static noinline void warp7_start(void)
+{
+ void __iomem *iomuxbase = IOMEM(MX7_IOMUXC_BASE_ADDR);
+ void __iomem *uart = IOMEM(MX7_UART1_BASE_ADDR);
+ void __iomem *ccmbase = IOMEM(MX7_CCM_BASE_ADDR);
+ void *fdt;
+
+ writel(0x3, ccmbase + 0x4000 + 16 * 148 + 0x8);
+ writel(0x10000000, ccmbase + 0x8000 + 128 * 95);
+ writel(0x3, ccmbase + 0x4000 + 16 * 148 + 0x4);
+ writel(0x0, iomuxbase + 0x128);
+ writel(0x0, iomuxbase + 0x12c);
+
+ imx7_uart_setup(uart);
+
+ pbl_set_putc(imx_uart_putc, uart);
+
+ pr_debug("Element14 i.MX7 Warp\n");
+
+ fdt = __dtb_imx7s_warp_start - get_runtime_offset();
+
+ barebox_arm_entry(0x80000000, SZ_512M, fdt);
+}
+
+ENTRY_FUNCTION(start_imx7s_element14_warp7, r0, r1, r2)
+{
+ imx7_cpu_lowlevel_init();
+
+ arm_early_mmu_cache_invalidate();
+
+ relocate_to_current_adr();
+ setup_c();
+ barrier();
+
+ warp7_start();
+} \ No newline at end of file
diff --git a/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c b/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c
index b329f46..5743dbc 100644
--- a/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c
+++ b/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c
@@ -2,6 +2,7 @@
#include <common.h>
#include <linux/sizes.h>
#include <mach/generic.h>
+#include <mach/iomux-mx6.h>
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
@@ -11,12 +12,8 @@ static inline void setup_uart(void)
imx6_ungate_all_peripherals();
- writel(0x1b0b1, iomuxbase + 0x0650);
- writel(3, iomuxbase + 0x0280);
-
- writel(0x1b0b1, iomuxbase + 0x0654);
- writel(3, iomuxbase + 0x0284);
- writel(1, iomuxbase + 0x0920);
+ imx_setup_pad(iomuxbase, MX6Q_PAD_CSI0_DAT10__UART1_TXD);
+ imx_setup_pad(iomuxbase, MX6Q_PAD_CSI0_DAT11__UART1_RXD);
imx6_uart_setup_ll();
diff --git a/arch/arm/boards/freescale-vf610-twr/lowlevel.c b/arch/arm/boards/freescale-vf610-twr/lowlevel.c
index 6504273..53c7b3a 100644
--- a/arch/arm/boards/freescale-vf610-twr/lowlevel.c
+++ b/arch/arm/boards/freescale-vf610-twr/lowlevel.c
@@ -27,16 +27,10 @@ extern char __dtb_vf610_twr_start[];
ENTRY_FUNCTION(start_vf610_twr, r0, r1, r2)
{
- int i;
void *fdt;
- void __iomem *mscm = IOMEM(VF610_MSCM_BASE_ADDR);
vf610_cpu_lowlevel_init();
- for (i = 0; i < VF610_MSCM_IRSPRC_NUM; i++)
- writew(VF610_MSCM_IRSPRC_CP0_EN,
- mscm + VF610_MSCM_IRSPRC(i));
-
if (IS_ENABLED(CONFIG_DEBUG_LL))
setup_uart();
diff --git a/arch/arm/boards/zii-imx6q-rdu2/Makefile b/arch/arm/boards/zii-imx6q-rdu2/Makefile
new file mode 100644
index 0000000..01c7a25
--- /dev/null
+++ b/arch/arm/boards/zii-imx6q-rdu2/Makefile
@@ -0,0 +1,2 @@
+obj-y += board.o
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/zii-imx6q-rdu2/board.c b/arch/arm/boards/zii-imx6q-rdu2/board.c
new file mode 100644
index 0000000..ee04517
--- /dev/null
+++ b/arch/arm/boards/zii-imx6q-rdu2/board.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2016 Zodiac Inflight Innovation
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <init.h>
+#include <environment.h>
+#include <mach/imx6-regs.h>
+#include <gpio.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <partition.h>
+#include <linux/phy.h>
+#include <asm/io.h>
+#include <asm/mmu.h>
+#include <mach/generic.h>
+#include <linux/sizes.h>
+#include <net.h>
+#include <mach/imx6.h>
+#include <mach/devices-imx6.h>
+#include <mach/iomux-mx6.h>
+#include <spi/spi.h>
+#include <mach/spi.h>
+#include <mach/usb.h>
+#include <mach/bbu.h>
+
+#define RDU2_DAC1_RESET IMX_GPIO_NR(1, 0)
+#define RDU2_DAC2_RESET IMX_GPIO_NR(1, 2)
+#define RDU2_RST_TOUCH IMX_GPIO_NR(1, 7)
+#define RDU2_NFC_RESET IMX_GPIO_NR(1, 17)
+#define RDU2_HPA1_SDn IMX_GPIO_NR(1, 4)
+#define RDU2_HPA2_SDn IMX_GPIO_NR(1, 5)
+
+static const struct gpio rdu2_reset_gpios[] = {
+ {
+ .gpio = RDU2_DAC1_RESET,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "dac1-reset",
+ },
+ {
+ .gpio = RDU2_DAC2_RESET,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "dac2-reset",
+ },
+ {
+ .gpio = RDU2_RST_TOUCH,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "rst-touch#",
+ },
+ {
+ .gpio = RDU2_NFC_RESET,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "nfc-reset",
+ },
+ {
+ .gpio = RDU2_HPA1_SDn,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "hpa1-sd-n",
+ },
+ {
+ .gpio = RDU2_HPA2_SDn,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "hpa2n-sd-n",
+ },
+};
+
+static int rdu2_reset_audio_touchscreen_nfc(void)
+{
+ int ret;
+
+ if (!of_machine_is_compatible("zii,imx6q-zii-rdu2") &&
+ !of_machine_is_compatible("zii,imx6qp-zii-rdu2"))
+ return 0;
+
+ ret = gpio_request_array(rdu2_reset_gpios,
+ ARRAY_SIZE(rdu2_reset_gpios));
+ if (ret) {
+ pr_err("Failed to request RDU2 reset gpios: %s\n",
+ strerror(-ret));
+ return ret;
+ }
+
+ mdelay(100);
+
+ gpio_direction_output(RDU2_DAC1_RESET, 1);
+ gpio_direction_output(RDU2_DAC2_RESET, 1);
+ gpio_direction_output(RDU2_RST_TOUCH, 1);
+ gpio_direction_output(RDU2_NFC_RESET, 0);
+ gpio_direction_output(RDU2_HPA1_SDn, 1);
+ gpio_direction_output(RDU2_HPA2_SDn, 1);
+
+ mdelay(100);
+
+ return 0;
+}
+/*
+ * When this function is called "hog" pingroup in device tree needs to
+ * be already initialized
+ */
+late_initcall(rdu2_reset_audio_touchscreen_nfc);
+
+static const struct gpio rdu2_front_panel_usb_gpios[] = {
+ {
+ .gpio = IMX_GPIO_NR(3, 19),
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "usb-emulation",
+ },
+ {
+ .gpio = IMX_GPIO_NR(3, 20),
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "usb-mode1",
+ },
+ {
+ .gpio = IMX_GPIO_NR(3, 22),
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "usb-pwr-ctrl-enn",
+ },
+ {
+ .gpio = IMX_GPIO_NR(3, 23),
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "usb-mode2",
+ },
+};
+
+static int rdu2_enable_front_panel_usb(void)
+{
+ int ret;
+
+ if (!of_machine_is_compatible("zii,imx6q-zii-rdu2") &&
+ !of_machine_is_compatible("zii,imx6qp-zii-rdu2"))
+ return 0;
+
+ ret = gpio_request_array(rdu2_front_panel_usb_gpios,
+ ARRAY_SIZE(rdu2_front_panel_usb_gpios));
+ if (ret) {
+ pr_err("Failed to request RDU2 front panel USB gpios: %s\n",
+ strerror(-ret));
+
+ }
+
+ return ret;
+}
+late_initcall(rdu2_enable_front_panel_usb);
+
+static int rdu2_devices_init(void)
+{
+ if (!of_machine_is_compatible("zii,imx6q-zii-rdu2") &&
+ !of_machine_is_compatible("zii,imx6qp-zii-rdu2"))
+ return 0;
+
+ barebox_set_hostname("rdu2");
+
+ imx6_bbu_internal_spi_i2c_register_handler("SPI", "/dev/m25p0.barebox",
+ BBU_HANDLER_FLAG_DEFAULT);
+
+ imx6_bbu_internal_mmc_register_handler("eMMC", "/dev/mmc3", 0);
+
+ return 0;
+}
+device_initcall(rdu2_devices_init);
diff --git a/arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/init/automount b/arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/init/automount
new file mode 100644
index 0000000..6c04eb4
--- /dev/null
+++ b/arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/init/automount
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# automount tftp server based on $eth0.serverip
+
+mkdir -p /mnt/tftp
+automount /mnt/tftp 'ifup eth1 && mount -t tftp $eth1.serverip /mnt/tftp'
+
+# automount nfs server's nfsroot
+
+mkdir -p /mnt/nfs
+automount /mnt/nfs 'ifup eth1 && mount -t nfs ${eth1.serverip}:/home/${global.user}/nfsroot/${global.hostname} /mnt/nfs'
+
+
+# FAT on usb disk example
+
+#mkdir -p /mnt/fat
+#automount -d /mnt/fat 'usb && [ -e /dev/disk0.0 ] && mount /dev/disk0.0 /mnt/fat'
diff --git a/arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/network/eth1 b/arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/network/eth1
new file mode 100644
index 0000000..33fe7c1
--- /dev/null
+++ b/arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/network/eth1
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# ip setting (static/dhcp)
+ip=dhcp
+global.dhcp.vendor_id=barebox-${global.hostname}
+
+# static setup used if ip=static
+ipaddr=
+netmask=
+gateway=
+serverip=
+
+# MAC address if needed
+#ethaddr=xx:xx:xx:xx:xx:xx
+
+# put code to discover eth0 (i.e. 'usb') to /env/network/eth0-discover
+
+exit 0
diff --git a/arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/nv/boot.default b/arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/nv/boot.default
new file mode 100644
index 0000000..3cfe9ba
--- /dev/null
+++ b/arch/arm/boards/zii-imx6q-rdu2/defaultenv-rdu2/nv/boot.default
@@ -0,0 +1 @@
+mmc1 \ No newline at end of file
diff --git a/arch/arm/boards/zii-imx6q-rdu2/flash-header-imx6q-rdu2.imxcfg b/arch/arm/boards/zii-imx6q-rdu2/flash-header-imx6q-rdu2.imxcfg
new file mode 100644
index 0000000..e37db50
--- /dev/null
+++ b/arch/arm/boards/zii-imx6q-rdu2/flash-header-imx6q-rdu2.imxcfg
@@ -0,0 +1,87 @@
+loadaddr 0x10000000
+soc imx6
+dcdofs 0x400
+
+wm 32 0x020e0798 0x000C0000
+wm 32 0x020e0758 0x00000000
+wm 32 0x020e0588 0x00000030
+wm 32 0x020e0594 0x00000030
+wm 32 0x020e056c 0x00000030
+wm 32 0x020e0578 0x00000030
+wm 32 0x020e074c 0x00000030
+wm 32 0x020e057c 0x00000030
+wm 32 0x020e058c 0x00000000
+wm 32 0x020e059c 0x00000030
+wm 32 0x020e05a0 0x00000030
+wm 32 0x020e078c 0x00000030
+wm 32 0x020e0750 0x00020000
+wm 32 0x020e05a8 0x00000028
+wm 32 0x020e05b0 0x00000028
+wm 32 0x020e0524 0x00000028
+wm 32 0x020e051c 0x00000028
+wm 32 0x020e0518 0x00000028
+wm 32 0x020e050c 0x00000028
+wm 32 0x020e05b8 0x00000028
+wm 32 0x020e05c0 0x00000028
+wm 32 0x020e0774 0x00020000
+wm 32 0x020e0784 0x00000028
+wm 32 0x020e0788 0x00000028
+wm 32 0x020e0794 0x00000028
+wm 32 0x020e079c 0x00000028
+wm 32 0x020e07a0 0x00000028
+wm 32 0x020e07a4 0x00000028
+wm 32 0x020e07a8 0x00000028
+wm 32 0x020e0748 0x00000028
+wm 32 0x020e05ac 0x00000028
+wm 32 0x020e05b4 0x00000028
+wm 32 0x020e0528 0x00000028
+wm 32 0x020e0520 0x00000028
+wm 32 0x020e0514 0x00000028
+wm 32 0x020e0510 0x00000028
+wm 32 0x020e05bc 0x00000028
+wm 32 0x020e05c4 0x00000028
+wm 32 0x021b0800 0xa1390003
+wm 32 0x021b080c 0x001F001F
+wm 32 0x021b0810 0x001F001F
+wm 32 0x021b480c 0x001F001F
+wm 32 0x021b4810 0x001F001F
+wm 32 0x021b083c 0x43260335
+wm 32 0x021b0840 0x031A030B
+wm 32 0x021b483c 0x4323033B
+wm 32 0x021b4840 0x0323026F
+wm 32 0x021b0848 0x483D4545
+wm 32 0x021b4848 0x44433E48
+wm 32 0x021b0850 0x41444840
+wm 32 0x021b4850 0x4835483E
+wm 32 0x021b081c 0x33333333
+wm 32 0x021b0820 0x33333333
+wm 32 0x021b0824 0x33333333
+wm 32 0x021b0828 0x33333333
+wm 32 0x021b481c 0x33333333
+wm 32 0x021b4820 0x33333333
+wm 32 0x021b4824 0x33333333
+wm 32 0x021b4828 0x33333333
+wm 32 0x021b08b8 0x00000800
+wm 32 0x021b48b8 0x00000800
+wm 32 0x021b0004 0x00020036
+wm 32 0x021b0008 0x09444040
+wm 32 0x021b000c 0x8A8F7955
+wm 32 0x021b0010 0xFF328F64
+wm 32 0x021b0014 0x01FF00DB
+wm 32 0x021b0018 0x00001740
+wm 32 0x021b001c 0x00008000
+wm 32 0x021b002c 0x000026d2
+wm 32 0x021b0030 0x008F1023
+wm 32 0x021b0040 0x00000047
+wm 32 0x021b0000 0x841A0000
+wm 32 0x021b001c 0x04088032
+wm 32 0x021b001c 0x00008033
+wm 32 0x021b001c 0x00048031
+wm 32 0x021b001c 0x09408030
+wm 32 0x021b001c 0x04008040
+wm 32 0x021b0020 0x00005800
+wm 32 0x021b0818 0x00011117
+wm 32 0x021b4818 0x00011117
+wm 32 0x021b0004 0x00025576
+wm 32 0x021b0404 0x00011006
+wm 32 0x021b001c 0x00000000
diff --git a/arch/arm/boards/zii-imx6q-rdu2/flash-header-imx6qp-rdu2.imxcfg b/arch/arm/boards/zii-imx6q-rdu2/flash-header-imx6qp-rdu2.imxcfg
new file mode 100644
index 0000000..03e764b
--- /dev/null
+++ b/arch/arm/boards/zii-imx6q-rdu2/flash-header-imx6qp-rdu2.imxcfg
@@ -0,0 +1,132 @@
+loadaddr 0x10000000
+soc imx6
+dcdofs 0x400
+
+wm 32 0x020e0798 0x000C0000
+wm 32 0x020e0758 0x00000000
+
+wm 32 0x020e0588 0x00020030
+wm 32 0x020e0594 0x00020030
+
+wm 32 0x020e056c 0x00020030
+wm 32 0x020e0578 0x00020030
+wm 32 0x020e074c 0x00020030
+
+wm 32 0x020e057c 0x00020030
+wm 32 0x020e058c 0x00000000
+wm 32 0x020e059c 0x00020030
+wm 32 0x020e05a0 0x00020030
+wm 32 0x020e078c 0x00020030
+
+wm 32 0x020e0750 0x00020000
+wm 32 0x020e05a8 0x00020030
+wm 32 0x020e05b0 0x00020030
+wm 32 0x020e0524 0x00020030
+wm 32 0x020e051c 0x00020030
+wm 32 0x020e0518 0x00020030
+wm 32 0x020e050c 0x00020030
+wm 32 0x020e05b8 0x00020030
+wm 32 0x020e05c0 0x00020030
+
+wm 32 0x020e0534 0x00018200
+wm 32 0x020e0538 0x00008000
+wm 32 0x020e053c 0x00018200
+wm 32 0x020e0540 0x00018200
+wm 32 0x020e0544 0x00018200
+wm 32 0x020e0548 0x00018200
+wm 32 0x020e054c 0x00018200
+wm 32 0x020e0550 0x00018200
+
+wm 32 0x020e0774 0x00020000
+wm 32 0x020e0784 0x00020030
+wm 32 0x020e0788 0x00020030
+wm 32 0x020e0794 0x00020030
+wm 32 0x020e079c 0x00020030
+wm 32 0x020e07a0 0x00020030
+wm 32 0x020e07a4 0x00020030
+wm 32 0x020e07a8 0x00020030
+wm 32 0x020e0748 0x00020030
+
+wm 32 0x020e05ac 0x00020030
+wm 32 0x020e05b4 0x00020030
+wm 32 0x020e0528 0x00020030
+wm 32 0x020e0520 0x00020030
+wm 32 0x020e0514 0x00020030
+wm 32 0x020e0510 0x00020030
+wm 32 0x020e05bc 0x00020030
+wm 32 0x020e05c4 0x00020030
+
+wm 32 0x021b001c 0x00008000
+
+wm 32 0x021b0800 0xA1390003
+
+wm 32 0x021b080c 0x002A001F
+wm 32 0x021b0810 0x002F002A
+wm 32 0x021b480c 0x001F0031
+wm 32 0x021b4810 0x001B0022
+
+wm 32 0x021b083c 0x433C0354
+wm 32 0x021b0840 0x03380330
+wm 32 0x021b483c 0x43440358
+wm 32 0x021b4840 0x03340300
+
+wm 32 0x021b0848 0x483A4040
+wm 32 0x021b4848 0x3E383648
+
+wm 32 0x021b0850 0x3C424048
+wm 32 0x021b4850 0x4C425042
+
+wm 32 0x021b081c 0x33333333
+wm 32 0x021b0820 0x33333333
+wm 32 0x021b0824 0x33333333
+wm 32 0x021b0828 0x33333333
+wm 32 0x021b481c 0x33333333
+wm 32 0x021b4820 0x33333333
+wm 32 0x021b4824 0x33333333
+wm 32 0x021b4828 0x33333333
+
+wm 32 0x021b08c0 0x24912489
+wm 32 0x021b48c0 0x24914452
+
+wm 32 0x021b08b8 0x00000800
+wm 32 0x021b48b8 0x00000800
+
+wm 32 0x021b0004 0x00020036
+wm 32 0x021b0008 0x09444040
+wm 32 0x021b000c 0x898E7955
+wm 32 0x021b0010 0xFF328F64
+wm 32 0x021b0014 0x01FF00DB
+
+wm 32 0x021b0018 0x00011740
+wm 32 0x021b001c 0x00008000
+wm 32 0x021b002c 0x000026D2
+wm 32 0x021b0030 0x008E1023
+wm 32 0x021b0040 0x00000047
+
+wm 32 0x021b0400 0x14420000
+wm 32 0x021b0000 0x841A0000
+wm 32 0x021b0890 0x00400c58
+
+wm 32 0x00bb0008 0x00000000
+wm 32 0x00bb000c 0x2891E41A
+wm 32 0x00bb0038 0x00000564
+wm 32 0x00bb0014 0x00000040
+wm 32 0x00bb0028 0x00000020
+wm 32 0x00bb002c 0x00000020
+
+wm 32 0x021b001c 0x02088032
+wm 32 0x021b001c 0x00008033
+wm 32 0x021b001c 0x00048031
+wm 32 0x021b001c 0x19408030
+wm 32 0x021b001c 0x04008040
+
+wm 32 0x021b0020 0x00007800
+
+wm 32 0x021b0818 0x00022227
+wm 32 0x021b4818 0x00022227
+
+wm 32 0x021b0004 0x00025576
+
+wm 32 0x021b0404 0x00011006
+
+wm 32 0x021b001c 0x00000000
diff --git a/arch/arm/boards/zii-imx6q-rdu2/lowlevel.c b/arch/arm/boards/zii-imx6q-rdu2/lowlevel.c
new file mode 100644
index 0000000..0d3520d
--- /dev/null
+++ b/arch/arm/boards/zii-imx6q-rdu2/lowlevel.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 Zodiac Inflight Innovation
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <debug_ll.h>
+#include <common.h>
+#include <mach/esdctl.h>
+#include <mach/generic.h>
+#include <mach/imx6.h>
+#include <asm/barebox-arm.h>
+
+static inline void setup_uart(void)
+{
+ void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR);
+
+ imx6_ungate_all_peripherals();
+
+ writel(0x1b0b1, iomuxbase + 0x0650);
+ writel(3, iomuxbase + 0x0280);
+
+ writel(0x1b0b1, iomuxbase + 0x0654);
+ writel(3, iomuxbase + 0x0284);
+ writel(1, iomuxbase + 0x0920);
+
+ imx6_uart_setup_ll();
+
+ putc_ll('>');
+}
+
+extern char __dtb_imx6q_zii_rdu2_start[];
+extern char __dtb_imx6qp_zii_rdu2_start[];
+
+ENTRY_FUNCTION(start_imx6q_zii_rdu2, r0, r1, r2)
+{
+ void *fdt = __dtb_imx6q_zii_rdu2_start;
+
+ imx6_cpu_lowlevel_init();
+
+ if (IS_ENABLED(CONFIG_DEBUG_LL))
+ setup_uart();
+
+ imx6q_barebox_entry(fdt - get_runtime_offset());
+}
+
+ENTRY_FUNCTION(start_imx6qp_zii_rdu2, r0, r1, r2)
+{
+ void *fdt = __dtb_imx6qp_zii_rdu2_start;
+
+ imx6_cpu_lowlevel_init();
+
+ if (IS_ENABLED(CONFIG_DEBUG_LL))
+ setup_uart();
+
+ imx6q_barebox_entry(fdt - get_runtime_offset());
+}
diff --git a/arch/arm/boards/zii-vf610-dev/Makefile b/arch/arm/boards/zii-vf610-dev/Makefile
new file mode 100644
index 0000000..1297d81
--- /dev/null
+++ b/arch/arm/boards/zii-vf610-dev/Makefile
@@ -0,0 +1,3 @@
+obj-y += board.o
+lwl-y += lowlevel.o
+bbenv-y += defaultenv-zii-vf610-dev
diff --git a/arch/arm/boards/zii-vf610-dev/board.c b/arch/arm/boards/zii-vf610-dev/board.c
new file mode 100644
index 0000000..eea3828
--- /dev/null
+++ b/arch/arm/boards/zii-vf610-dev/board.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 Zodiac Inflight Innovation
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <linux/clk.h>
+#include <dt-bindings/clock/vf610-clock.h>
+#include <envfs.h>
+
+
+static int expose_signals(const struct gpio *signals,
+ size_t signal_num)
+{
+ int ret, i;
+
+ ret = gpio_request_array(signals, signal_num);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < signal_num; i++)
+ export_env_ull(signals[i].label, signals[i].gpio);
+
+ return 0;
+}
+
+static int zii_vf610_cfu1_expose_signals(void)
+{
+ static const struct gpio signals[] = {
+ {
+ .gpio = 132,
+ .flags = GPIOF_IN,
+ .label = "fim_sd",
+ },
+ {
+ .gpio = 118,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "fim_tdis",
+ },
+ };
+
+ if (!of_machine_is_compatible("zii,vf610cfu1-a"))
+ return 0;
+
+ return expose_signals(signals, ARRAY_SIZE(signals));
+}
+late_initcall(zii_vf610_cfu1_expose_signals);
+
+static int zii_vf610_cfu1_spu3_expose_signals(void)
+{
+ static const struct gpio signals[] = {
+ {
+ .gpio = 107,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "soc_sw_rstn",
+ },
+ {
+ .gpio = 98,
+ .flags = GPIOF_IN,
+ .label = "e6352_intn",
+ },
+ };
+
+ if (!of_machine_is_compatible("zii,vf610spu3-a") &&
+ !of_machine_is_compatible("zii,vf610cfu1-a"))
+ return 0;
+
+ return expose_signals(signals, ARRAY_SIZE(signals));
+}
+late_initcall(zii_vf610_cfu1_spu3_expose_signals);
+
+static int zii_vf610_dev_print_clocks(void)
+{
+ int i;
+ struct clk *clk;
+ struct device_node *ccm_np;
+ const unsigned long MHz = 1000000;
+ const char *clk_names[] = { "cpu", "ddr", "bus", "ipg" };
+
+ if (!of_machine_is_compatible("zii,vf610dev"))
+ return 0;
+
+ ccm_np = of_find_compatible_node(NULL, NULL, "fsl,vf610-ccm");
+ if (!ccm_np) {
+ pr_err("Couln't get CCM node\n");
+ return -ENOENT;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(clk_names); i++) {
+ unsigned long rate;
+ const char *name = clk_names[i];
+
+ clk = of_clk_get_by_name(ccm_np, name);
+ if (IS_ERR(clk)) {
+ pr_err("Failed to get '%s' clock (%ld)\n",
+ name, PTR_ERR(clk));
+ return PTR_ERR(clk);
+ }
+
+ rate = clk_get_rate(clk);
+
+ pr_info("%s clock : %8lu MHz\n", name, rate / MHz);
+ }
+
+ return 0;
+}
+late_initcall(zii_vf610_dev_print_clocks);
+
+static int zii_vf610_dev_set_hostname(void)
+{
+ size_t i;
+ static const struct {
+ const char *compatible;
+ const char *hostname;
+ } boards[] = {
+ { "zii,vf610spu3-a", "spu3-rev-a" },
+ { "zii,vf610cfu1-a", "cfu1-rev-a" },
+ { "zii,vf610dev-b", "dev-rev-b" },
+ { "zii,vf610dev-c", "dev-rev-c" },
+ { "zii,vf610scu4-aib-c", "scu4-aib-rev-c" },
+ };
+
+ if (!of_machine_is_compatible("zii,vf610dev"))
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(boards); i++) {
+ if (of_machine_is_compatible(boards[i].compatible)) {
+ barebox_set_hostname(boards[i].hostname);
+ break;
+ }
+ }
+
+ defaultenv_append_directory(defaultenv_zii_vf610_dev);
+ return 0;
+}
+late_initcall(zii_vf610_dev_set_hostname);
diff --git a/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/boot/sd b/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/boot/sd
new file mode 100644
index 0000000..cf8eec3
--- /dev/null
+++ b/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/boot/sd
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+global.bootm.image=/mnt/sd/zImage
+global.bootm.oftree=/mnt/sd/${global.bootm.oftree}
diff --git a/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/automount-sd b/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/automount-sd
new file mode 100644
index 0000000..f44dab3
--- /dev/null
+++ b/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/automount-sd
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+if [ x${global.hostname} = xdev-rev-b -o x${global.hostname} = xdev-rev-c ];
+then
+ global sd=0
+else
+ global sd=1
+fi
+
+mkdir -p /mnt/sd
+automount /mnt/sd 'mci${global.sd}.probe=1 && mount /dev/disk${global.sd}.0 /mnt/sd'
+
+exit 0
diff --git a/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/choose-dtb b/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/choose-dtb
new file mode 100644
index 0000000..41a74c3
--- /dev/null
+++ b/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/choose-dtb
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+global.bootm.oftree=vf610-zii-${global.hostname}.dtb
+
diff --git a/arch/arm/boards/zii-vf610-dev/flash-header-zii-vf610-dev.imxcfg b/arch/arm/boards/zii-vf610-dev/flash-header-zii-vf610-dev.imxcfg
new file mode 100644
index 0000000..177f4e8
--- /dev/null
+++ b/arch/arm/boards/zii-vf610-dev/flash-header-zii-vf610-dev.imxcfg
@@ -0,0 +1,243 @@
+soc vf610
+loadaddr 0x80000000
+dcdofs 0x400
+
+#define VF610_DDR_PAD_CTRL 0x00000180 /* 25 Ohm drive strength */
+#define VF610_DDR_PAD_CTRL_1 0x00010180 /* 25 Ohm drive strength + differential input */
+
+#define DDRMC_PHY_DQ_TIMING 0x00002613
+#define DDRMC_PHY_DQS_TIMING 0x00002615
+#define DDRMC_PHY_CTRL 0x00210000
+#define DDRMC_PHY_MASTER_CTRL 0x0001012a
+#define DDRMC_PHY_SLAVE_CTRL 0x00002000
+#define DDRMC_PHY_OFF 0x00000000
+#define DDRMC_PHY_PROC_PAD_ODT 0x00010101
+
+#define CHECKPOINT(n) wm 32 0x3f000000 n
+
+CHECKPOINT(1)
+
+/* ======================= Clock initialization =======================*/
+
+/*
+ * Ungate all IP block clocks
+ */
+wm 32 0x4006b040 0xffffffff
+wm 32 0x4006b044 0xffffffff
+wm 32 0x4006b048 0xffffffff
+wm 32 0x4006b04c 0xffffffff
+wm 32 0x4006b050 0xffffffff
+wm 32 0x4006b058 0xffffffff
+wm 32 0x4006b05c 0xffffffff
+wm 32 0x4006b060 0xffffffff
+wm 32 0x4006b064 0xffffffff
+wm 32 0x4006b068 0xffffffff
+wm 32 0x4006b06c 0xffffffff
+
+
+/*
+ * Turn PLL2 on
+ */
+wm 32 0x40050030 0x00002001 /* Fout = Fin * 22 */
+
+CHECKPOINT(2)
+
+/*
+ * Wait for PLLs to lock
+ */
+check 32 while_any_bit_clear 0x40050030 0x80000000
+
+
+CHECKPOINT(3)
+
+clear_bits 32 0x4006b008 0x00000040
+set_bits 32 0x4006b008 0x00002000
+
+
+
+/* ======================= DDR IOMUX =======================*/
+
+CHECKPOINT(4)
+
+wm 32 0x40048220 0x00000180
+wm 32 0x40048224 0x00000180
+wm 32 0x40048228 0x00000180
+wm 32 0x4004822c 0x00000180
+wm 32 0x40048230 0x00000180
+wm 32 0x40048234 0x00000180
+wm 32 0x40048238 0x00000180
+wm 32 0x4004823c 0x00000180
+wm 32 0x40048240 0x00000180
+wm 32 0x40048244 0x00000180
+wm 32 0x40048248 0x00000180
+wm 32 0x4004824c 0x00000180
+wm 32 0x40048250 0x00000180
+wm 32 0x40048254 0x00000180
+wm 32 0x40048258 0x00000180
+wm 32 0x4004825c 0x00000180
+wm 32 0x40048260 0x00000180
+wm 32 0x40048264 0x00000180
+wm 32 0x40048268 0x00000180
+wm 32 0x4004826c 0x00000180
+wm 32 0x40048270 0x00000180
+wm 32 0x40048274 0x00000180
+wm 32 0x40048278 0x00000180
+wm 32 0x4004827c 0x00010180
+wm 32 0x40048280 0x00010180
+wm 32 0x40048284 0x00010180
+wm 32 0x40048288 0x00010180
+wm 32 0x4004828c 0x00010180
+wm 32 0x40048290 0x00010180
+wm 32 0x40048294 0x00010180
+wm 32 0x40048298 0x00010180
+wm 32 0x4004829c 0x00010180
+wm 32 0x400482a0 0x00010180
+wm 32 0x400482a4 0x00010180
+wm 32 0x400482a8 0x00010180
+wm 32 0x400482ac 0x00010180
+wm 32 0x400482b0 0x00010180
+wm 32 0x400482b4 0x00010180
+wm 32 0x400482b8 0x00010180
+wm 32 0x400482bc 0x00010180
+wm 32 0x400482c0 0x00010180
+wm 32 0x400482c4 0x00010180
+wm 32 0x400482c8 0x00010180
+wm 32 0x400482cc 0x00000180
+wm 32 0x400482d0 0x00000180
+wm 32 0x400482d4 0x00000180
+wm 32 0x400482d8 0x00000180
+wm 32 0x4004821c 0x00000180
+
+/* ======================= DDR Controller =======================*/
+
+CHECKPOINT(5)
+wm 32 0x400ae000 0x00000600
+wm 32 0x400ae008 0x00000005
+wm 32 0x400ae028 0x00013880
+wm 32 0x400ae02c 0x00030d40
+wm 32 0x400ae030 0x00000506
+wm 32 0x400ae034 0x06040400
+wm 32 0x400ae038 0x1006040e
+wm 32 0x400ae040 0x04040000
+wm 32 0x400ae044 0x006db00c
+wm 32 0x400ae048 0x00000403
+wm 32 0x400ae050 0x01000000
+wm 32 0x400ae054 0x00060001
+wm 32 0x400ae058 0x000c0000
+wm 32 0x400ae05c 0x03000200
+wm 32 0x400ae060 0x00000006
+wm 32 0x400ae064 0x00010000
+wm 32 0x400ae068 0x0c300068
+wm 32 0x400ae070 0x00000000
+wm 32 0x400ae074 0x00000003
+wm 32 0x400ae078 0x0000000a
+wm 32 0x400ae07c 0x006c0200
+wm 32 0x400ae084 0x00010000
+wm 32 0x400ae088 0x00050500
+wm 32 0x400ae098 0x00000000
+wm 32 0x400ae09c 0x04001002
+wm 32 0x400ae0a4 0x00000001
+wm 32 0x400ae0c0 0x00460420
+wm 32 0x400ae0c4 0x00000000
+wm 32 0x400ae0cc 0x00000000
+wm 32 0x400ae0e4 0x02000000
+wm 32 0x400ae108 0x01000200
+wm 32 0x400ae10c 0x00000040
+wm 32 0x400ae114 0x00000200
+wm 32 0x400ae118 0x00000040
+wm 32 0x400ae120 0x00000000
+wm 32 0x400ae124 0x0a010100
+wm 32 0x400ae128 0x01014040
+wm 32 0x400ae12c 0x01010101
+wm 32 0x400ae130 0x03030000
+wm 32 0x400ae134 0x01000101
+wm 32 0x400ae138 0x0700000c
+wm 32 0x400ae13c 0x00000000
+wm 32 0x400ae148 0x10000000
+wm 32 0x400ae15c 0x01000000
+wm 32 0x400ae160 0x00040000
+wm 32 0x400ae164 0x00000002
+wm 32 0x400ae16c 0x00020000
+wm 32 0x400ae180 0x00002819
+wm 32 0x400ae184 0x01000000
+wm 32 0x400ae188 0x00000000
+wm 32 0x400ae18c 0x00000000
+wm 32 0x400ae198 0x00000000
+wm 32 0x400ae1a4 0x00000c00
+wm 32 0x400ae1a8 0x00000000
+wm 32 0x400ae1b8 0x0000000c
+wm 32 0x400ae1c8 0x00000000
+wm 32 0x400ae1cc 0x00000000
+wm 32 0x400ae1d4 0x00000000
+wm 32 0x400ae1d8 0x01010000
+wm 32 0x400ae1e0 0x02020000
+wm 32 0x400ae1e4 0x00000202
+wm 32 0x400ae1e8 0x01010064
+wm 32 0x400ae1ec 0x00010101
+wm 32 0x400ae1f0 0x00000064
+wm 32 0x400ae1f8 0x00000800
+wm 32 0x400ae210 0x00000506
+wm 32 0x400ae224 0x00020000
+wm 32 0x400ae228 0x01000000
+wm 32 0x400ae22c 0x04070303
+wm 32 0x400ae230 0x00000040
+wm 32 0x400ae23c 0x06000080
+wm 32 0x400ae240 0x04070303
+wm 32 0x400ae244 0x00000040
+wm 32 0x400ae248 0x00000040
+wm 32 0x400ae24c 0x000f0000
+wm 32 0x400ae250 0x000f0000
+wm 32 0x400ae25c 0x00000101
+wm 32 0x400ae268 0x682c4000
+wm 32 0x400ae26c 0x00000012
+wm 32 0x400ae278 0x00000006
+wm 32 0x400ae284 0x00010202
+
+/* ======================= DDR PHY =======================*/
+
+CHECKPOINT(6)
+
+wm 32 0x400ae400 0x00002613
+wm 32 0x400ae440 0x00002613
+wm 32 0x400ae480 0x00002613
+wm 32 0x400ae404 0x00002615
+wm 32 0x400ae444 0x00002615
+wm 32 0x400ae408 0x00210000
+wm 32 0x400ae448 0x00210000
+wm 32 0x400ae488 0x00210000
+wm 32 0x400ae40c 0x0001012a
+wm 32 0x400ae44c 0x0001012a
+wm 32 0x400ae48c 0x0001012a
+wm 32 0x400ae410 0x00002000
+wm 32 0x400ae450 0x00002000
+wm 32 0x400ae490 0x00002000
+wm 32 0x400ae4c4 0x00000000
+wm 32 0x400ae4c8 0x00001100
+wm 32 0x400ae4d0 0x00010101
+wm 32 0x400ae000 0x00000601
+
+CHECKPOINT(7)
+
+check 32 while_any_bit_clear 0x400ae140 0x100
+# check 32 while_any_bit_clear 0x400ae42c 0x1
+# check 32 while_any_bit_clear 0x400ae46c 0x1
+# check 32 while_any_bit_clear 0x400ae4ac 0x1
+
+CHECKPOINT(8)
+
+wm 32 0x80000000 0xa5a5a5a5
+check 32 while_any_bit_clear 0x80000000 0xa5a5a5a5
+
+wm 32 0x400ae000 0x00000600
+wm 32 0x400ae000 0x00000601
+
+check 32 while_any_bit_clear 0x400ae140 0x100
+# check 32 while_any_bit_clear 0x400ae42c 0x1
+# check 32 while_any_bit_clear 0x400ae46c 0x1
+# check 32 while_any_bit_clear 0x400ae4ac 0x1
+
+/* wm 32 0x3f040000 0xf0
+ check 32 while_any_bit_clear 0x3f040000 0x0f */
+
+
+CHECKPOINT(9)
diff --git a/arch/arm/boards/zii-vf610-dev/lowlevel.c b/arch/arm/boards/zii-vf610-dev/lowlevel.c
new file mode 100644
index 0000000..95b68d5
--- /dev/null
+++ b/arch/arm/boards/zii-vf610-dev/lowlevel.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 Zodiac Inflight Innovation
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <linux/sizes.h>
+#include <mach/generic.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <mach/vf610-regs.h>
+#include <mach/clock-vf610.h>
+#include <mach/iomux-vf610.h>
+#include <debug_ll.h>
+
+static inline void setup_uart(void)
+{
+ void __iomem *iomux = IOMEM(VF610_IOMUXC_BASE_ADDR);
+
+ vf610_ungate_all_peripherals();
+ vf610_setup_pad(iomux, VF610_PAD_PTB10__UART0_TX);
+ vf610_uart_setup_ll();
+
+ putc_ll('>');
+}
+
+enum zii_platform_vf610_type {
+ ZII_PLATFORM_VF610_DEV_REV_B = 0x01,
+ ZII_PLATFORM_VF610_SCU4_AIB = 0x02,
+ ZII_PLATFORM_VF610_SPU3 = 0x03,
+ ZII_PLATFORM_VF610_CFU1 = 0x04,
+ ZII_PLATFORM_VF610_DEV_REV_C = 0x05,
+};
+
+unsigned int get_system_type(void)
+{
+#define GPIO_PDIR 0x10
+
+ u32 pdir;
+ void __iomem *gpio2 = IOMEM(VF610_GPIO2_BASE_ADDR);
+ void __iomem *iomux = IOMEM(VF610_IOMUXC_BASE_ADDR);
+ unsigned low, high;
+
+ /*
+ * System type is encoded as a 4-bit number specified by the
+ * following pins (pulled up or down with resistors on the
+ * board).
+ */
+ vf610_setup_pad(iomux, VF610_PAD_PTD16__GPIO_78);
+ vf610_setup_pad(iomux, VF610_PAD_PTD17__GPIO_77);
+ vf610_setup_pad(iomux, VF610_PAD_PTD18__GPIO_76);
+ vf610_setup_pad(iomux, VF610_PAD_PTD19__GPIO_75);
+
+ pdir = readl(gpio2 + GPIO_PDIR);
+
+ low = 75 % 32;
+ high = 78 % 32;
+
+ pdir &= GENMASK(high, low);
+ pdir >>= low;
+
+ return pdir;
+}
+
+extern char __dtb_vf610_zii_dev_rev_b_start[];
+extern char __dtb_vf610_zii_dev_rev_c_start[];
+extern char __dtb_vf610_zii_cfu1_rev_a_start[];
+extern char __dtb_vf610_zii_spu3_rev_a_start[];
+extern char __dtb_vf610_zii_scu4_aib_rev_c_start[];
+
+ENTRY_FUNCTION(start_zii_vf610_dev, r0, r1, r2)
+{
+ void *fdt;
+ const unsigned int system_type = get_system_type();
+
+ vf610_cpu_lowlevel_init();
+
+ if (IS_ENABLED(CONFIG_DEBUG_LL))
+ setup_uart();
+
+ switch (system_type) {
+ default:
+ /*
+ * GCC can be smart enough to, when DEBUG_LL is
+ * disabled, reduce this switch statement to a LUT
+ * fetch. Unfortunately here, this early in the boot
+ * process before any relocation/address fixups could
+ * happen, the address of that LUT used by the code is
+ * incorrect and any access to it would result in
+ * bogus values.
+ *
+ * Adding the following barrier() statement seem to
+ * force the compiler to always translate this block
+ * to a sequence of consecutive checks and jumps with
+ * relative fetches, which should work with or without
+ * relocation/fixups.
+ */
+ barrier();
+
+ if (IS_ENABLED(CONFIG_DEBUG_LL)) {
+ relocate_to_current_adr();
+ setup_c();
+ puts_ll("*********************************\n");
+ puts_ll("* Unknown system type: ");
+ puthex_ll(system_type);
+ puts_ll("\n* Assuming devboard revision B\n");
+ puts_ll("*********************************\n");
+ }
+ case ZII_PLATFORM_VF610_DEV_REV_B: /* FALLTHROUGH */
+ fdt = __dtb_vf610_zii_dev_rev_b_start;
+ break;
+ case ZII_PLATFORM_VF610_SCU4_AIB:
+ fdt = __dtb_vf610_zii_scu4_aib_rev_c_start;
+ break;
+ case ZII_PLATFORM_VF610_DEV_REV_C:
+ fdt = __dtb_vf610_zii_dev_rev_c_start;
+ break;
+ case ZII_PLATFORM_VF610_CFU1:
+ fdt = __dtb_vf610_zii_cfu1_rev_a_start;
+ break;
+ case ZII_PLATFORM_VF610_SPU3:
+ fdt = __dtb_vf610_zii_spu3_rev_a_start;
+ break;
+ }
+
+ barebox_arm_entry(0x80000000, SZ_512M, fdt - get_runtime_offset());
+}
diff --git a/arch/arm/configs/zii_vf610_dev_defconfig b/arch/arm/configs/zii_vf610_dev_defconfig
new file mode 100644
index 0000000..bda6044
--- /dev/null
+++ b/arch/arm/configs/zii_vf610_dev_defconfig
@@ -0,0 +1,165 @@
+CONFIG_ARCH_IMX=y
+CONFIG_IMX_MULTI_BOARDS=y
+CONFIG_MACH_SABRESD=y
+CONFIG_MACH_ZII_VF610_DEV=y
+CONFIG_IMX_IIM=y
+CONFIG_IMX_IIM_FUSE_BLOW=y
+CONFIG_THUMB2_BAREBOX=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_ARM_UNWIND=y
+CONFIG_MMU=y
+CONFIG_TEXT_BASE=0x0
+CONFIG_MALLOC_SIZE=0x0
+CONFIG_MALLOC_TLSF=y
+CONFIG_KALLSYMS=y
+CONFIG_RELOCATABLE=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_BOOTM_OFTREE=y
+CONFIG_BOOTM_OFTREE_UIMAGE=y
+CONFIG_BLSPEC=y
+CONFIG_PARTITION_DISK_EFI=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_RESET_SOURCE=y
+CONFIG_CMD_DMESG=y
+CONFIG_LONGHELP=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_IMD=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_ARM_MMUINFO=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_MMC_EXTCSD=y
+# CONFIG_CMD_BOOTU is not set
+CONFIG_CMD_GO=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_UBIFORMAT=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_FILETYPE=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_LET=y
+CONFIG_CMD_MSLEEP=y
+CONFIG_CMD_READF=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_TFTP=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_MENUTREE=y
+CONFIG_CMD_SPLASH=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MM=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DETECT=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_LED=y
+CONFIG_CMD_NANDTEST=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_LED_TRIGGER=y
+CONFIG_CMD_USBGADGET=y
+CONFIG_CMD_WD=y
+CONFIG_CMD_BAREBOX_UPDATE=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIME=y
+CONFIG_NET=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_OF_BAREBOX_DRIVERS=y
+CONFIG_DRIVER_NET_FEC_IMX=y
+CONFIG_AT803X_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_NET_USB=y
+CONFIG_NET_USB_ASIX=y
+CONFIG_NET_USB_SMSC95XX=y
+CONFIG_DRIVER_SPI_IMX=y
+CONFIG_DRIVER_SPI_DSPI=y
+CONFIG_I2C=y
+CONFIG_I2C_IMX=y
+CONFIG_MTD=y
+CONFIG_MTD_RAW_DEVICE=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SST25L=y
+CONFIG_NAND=y
+CONFIG_NAND_ALLOW_ERASE_BAD=y
+CONFIG_NAND_IMX=y
+CONFIG_NAND_IMX_BBM=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_DISK_AHCI=y
+CONFIG_DISK_AHCI_IMX=y
+CONFIG_DISK_INTF_PLATFORM_IDE=y
+CONFIG_DISK_PATA_IMX=y
+CONFIG_USB_HOST=y
+CONFIG_USB_IMX_CHIPIDEA=y
+CONFIG_USB_EHCI=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DFU=y
+CONFIG_USB_GADGET_SERIAL=y
+CONFIG_USB_GADGET_FASTBOOT=y
+CONFIG_VIDEO=y
+CONFIG_DRIVER_VIDEO_IMX_IPUV3=y
+CONFIG_DRIVER_VIDEO_IMX_IPUV3_LVDS=y
+CONFIG_DRIVER_VIDEO_IMX_IPUV3_HDMI=y
+CONFIG_DRIVER_VIDEO_SIMPLEFB=y
+CONFIG_DRIVER_VIDEO_EDID=y
+CONFIG_MCI=y
+CONFIG_MCI_MMC_BOOT_PARTITIONS=y
+CONFIG_MCI_IMX_ESDHC=y
+CONFIG_MFD_MC13XXX=y
+CONFIG_MFD_MC34704=y
+CONFIG_MFD_MC9SDZ60=y
+CONFIG_MFD_STMPE=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_LED_GPIO_OF=y
+CONFIG_LED_TRIGGERS=y
+CONFIG_EEPROM_AT25=y
+CONFIG_EEPROM_AT24=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_IMX=y
+CONFIG_PWM=y
+CONFIG_PWM_IMX=y
+CONFIG_GPIO_STMPE=y
+CONFIG_GPIO_SX150X=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED=y
+CONFIG_GENERIC_PHY=y
+CONFIG_USB_NOP_XCEIV=y
+CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_FAT_LFN=y
+CONFIG_FS_UBIFS=y
+CONFIG_FS_UBIFS_COMPRESSION_LZO=y
+CONFIG_PNG=y
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index d8cb187..13b4f95 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -34,6 +34,10 @@ ifeq ($(CONFIG_MMU),)
obj-y += no-mmu.o
endif
+obj-$(CONFIG_ARM_PSCI) += psci.o
+obj-$(CONFIG_ARM_SECURE_MONITOR) += smccc-call.o
+obj-$(CONFIG_ARM_SECURE_MONITOR) += sm.o sm_as.o
+
obj-$(CONFIG_CPU_32v4T) += cache-armv4.o
pbl-$(CONFIG_CPU_32v4T) += cache-armv4.o
obj-$(CONFIG_CPU_32v5) += cache-armv5.o
diff --git a/arch/arm/cpu/psci.c b/arch/arm/cpu/psci.c
new file mode 100644
index 0000000..d650c23
--- /dev/null
+++ b/arch/arm/cpu/psci.c
@@ -0,0 +1,311 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "psci: " fmt
+
+#include <common.h>
+#include <asm/psci.h>
+#include <asm/arm-smccc.h>
+#include <asm/secure.h>
+#include <asm/system.h>
+#include <restart.h>
+#include <globalvar.h>
+#include <init.h>
+#include <magicvar.h>
+
+#ifdef CONFIG_ARM_PSCI_DEBUG
+
+/*
+ * PSCI debugging functions. Board code can specify a putc() function
+ * which is used for debugging output. Beware that this function is
+ * called while the kernel is running. This means the kernel could have
+ * turned off clocks, configured other baudrates and other stuff that
+ * might confuse the putc function. So it can well be that the debugging
+ * code itself is the problem when somethings not working. You have been
+ * warned.
+ */
+
+static void (*__putc)(void *ctx, int c);
+static void *putc_ctx;
+
+void psci_set_putc(void (*putcf)(void *ctx, int c), void *ctx)
+{
+ __putc = putcf;
+ putc_ctx = ctx;
+}
+
+void psci_putc(char c)
+{
+ if (__putc)
+ __putc(putc_ctx, c);
+}
+
+int psci_puts(const char *str)
+{
+ int n = 0;
+
+ while (*str) {
+ if (*str == '\n')
+ psci_putc('\r');
+
+ psci_putc(*str);
+ str++;
+ n++;
+ }
+
+ return n;
+}
+
+int psci_printf(const char *fmt, ...)
+{
+ va_list args;
+ uint i;
+ char printbuffer[128];
+
+ va_start(args, fmt);
+ i = vsprintf(printbuffer, fmt, args);
+ va_end(args);
+
+ psci_puts(printbuffer);
+
+ return i;
+}
+#endif
+
+static struct psci_ops *psci_ops;
+
+void psci_set_ops(struct psci_ops *ops)
+{
+ psci_ops = ops;
+}
+
+static unsigned long psci_version(void)
+{
+ psci_printf("%s\n", __func__);
+ return ARM_PSCI_VER_1_0;
+}
+
+static unsigned long psci_cpu_suspend(u32 power_state, unsigned long entry,
+ u32 context_id)
+{
+ psci_printf("%s\n", __func__);
+
+ if (psci_ops->cpu_off)
+ return psci_ops->cpu_suspend(power_state, entry, context_id);
+
+ return ARM_PSCI_RET_NOT_SUPPORTED;
+}
+
+static unsigned long psci_cpu_off(void)
+{
+ psci_printf("%s\n", __func__);
+
+ if (psci_ops->cpu_off)
+ return psci_ops->cpu_off();
+
+ return ARM_PSCI_RET_NOT_SUPPORTED;
+}
+
+static unsigned long cpu_entry[ARM_SECURE_MAX_CPU];
+static unsigned long context[ARM_SECURE_MAX_CPU];
+
+static unsigned long psci_cpu_on(u32 cpu_id, unsigned long entry, u32 context_id)
+{
+ psci_printf("%s: %d 0x%08lx\n", __func__, cpu_id, entry);
+
+ if (cpu_id >= ARM_SECURE_MAX_CPU)
+ return ARM_PSCI_RET_INVAL;
+
+ cpu_entry[cpu_id] = entry;
+ context[cpu_id] = context_id;
+ dsb();
+
+ if (psci_ops->cpu_on)
+ return psci_ops->cpu_on(cpu_id);
+
+ return ARM_PSCI_RET_NOT_SUPPORTED;
+}
+
+static unsigned long psci_system_off(void)
+{
+ psci_printf("%s\n", __func__);
+
+ if (psci_ops->system_reset)
+ psci_ops->system_reset();
+
+ while(1);
+
+ return 0;
+}
+
+static unsigned long psci_system_reset(void)
+{
+ psci_printf("%s\n", __func__);
+
+ if (psci_ops->system_reset)
+ psci_ops->system_reset();
+
+ restart_machine();
+}
+
+void psci_entry(u32 r0, u32 r1, u32 r2, u32 r3, u32 r4, u32 r5, u32 r6,
+ struct arm_smccc_res *res)
+{
+ int mmuon;
+ unsigned long ttb;
+
+ mmuon = get_cr() & CR_M;
+ asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r"(ttb));
+
+ psci_printf("%s entry, function: 0x%08x\n", __func__, r0);
+
+ switch (r0) {
+ case ARM_PSCI_0_2_FN_PSCI_VERSION:
+ res->a0 = psci_version();
+ break;
+ case ARM_PSCI_0_2_FN_CPU_SUSPEND:
+ res->a0 = psci_cpu_suspend(r1, r2, r3);
+ break;
+ case ARM_PSCI_0_2_FN_CPU_OFF:
+ res->a0 = psci_cpu_off();
+ break;
+ case ARM_PSCI_0_2_FN_CPU_ON:
+ res->a0 = psci_cpu_on(r1, r2, r3);
+ break;
+ case ARM_PSCI_0_2_FN_SYSTEM_OFF:
+ psci_system_off();
+ break;
+ case ARM_PSCI_0_2_FN_SYSTEM_RESET:
+ psci_system_reset();
+ break;
+ default:
+ res->a0 = ARM_PSCI_RET_NOT_SUPPORTED;
+ break;
+ }
+}
+
+static int of_psci_fixup(struct device_node *root, void *unused)
+{
+ struct device_node *psci;
+ int ret;
+
+ if (bootm_arm_security_state() < ARM_STATE_NONSECURE)
+ return 0;
+
+ psci = of_create_node(root, "/psci");
+ if (!psci)
+ return -EINVAL;
+
+ ret = of_set_property(psci, "compatible", "arm,psci-1.0",
+ strlen("arm,psci-1.0") + 1, 1);
+ if (ret)
+ return ret;
+
+ ret = of_set_property(psci, "method", "smc",
+ strlen("smc") + 1, 1);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int psci_cpu_entry_c(void)
+{
+ void (*entry)(u32 context);
+ int cpu;
+ u32 context_id;
+
+ __armv7_secure_monitor_install();
+ cpu = psci_get_cpu_id();
+ entry = (void *)cpu_entry[cpu];
+ context_id = context[cpu];
+
+ if (bootm_arm_security_state() == ARM_STATE_HYP)
+ armv7_switch_to_hyp();
+
+ psci_printf("core #%d enter function 0x%p\n", cpu, entry);
+
+ entry(context_id);
+
+ while (1);
+}
+
+static int armv7_psci_init(void)
+{
+ return of_register_fixup(of_psci_fixup, NULL);
+}
+device_initcall(armv7_psci_init);
+
+#ifdef DEBUG
+
+#include <command.h>
+#include <getopt.h>
+#include "mmu.h"
+
+void second_entry(void)
+{
+ struct arm_smccc_res res;
+
+ psci_printf("2nd CPU online, now turn off again\n");
+
+ arm_smccc_smc(ARM_PSCI_0_2_FN_CPU_OFF,
+ 0, 0, 0, 0, 0, 0, 0, &res);
+
+ psci_printf("2nd CPU still alive?\n");
+
+ while (1);
+}
+
+static int do_smc(int argc, char *argv[])
+{
+ int opt;
+ struct arm_smccc_res res = {
+ .a0 = 0xdeadbee0,
+ .a1 = 0xdeadbee1,
+ .a2 = 0xdeadbee2,
+ .a3 = 0xdeadbee3,
+ };
+
+ while ((opt = getopt(argc, argv, "nicz")) > 0) {
+ switch (opt) {
+ case 'n':
+ armv7_secure_monitor_install();
+ break;
+ case 'i':
+ arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION,
+ 0, 0, 0, 0, 0, 0, 0, &res);
+ printf("found psci version %ld.%ld\n", res.a0 >> 16, res.a0 & 0xffff);
+ break;
+ case 'c':
+ arm_smccc_smc(ARM_PSCI_0_2_FN_CPU_ON,
+ 1, (unsigned long)second_entry, 0, 0, 0, 0, 0, &res);
+ break;
+ }
+ }
+
+
+ return 0;
+}
+BAREBOX_CMD_HELP_START(smc)
+BAREBOX_CMD_HELP_TEXT("Secure monitor code test command")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT ("-n", "Install secure monitor and switch to nonsecure mode")
+BAREBOX_CMD_HELP_OPT ("-i", "Show information about installed PSCI version")
+BAREBOX_CMD_HELP_OPT ("-c", "Start secondary CPU core")
+BAREBOX_CMD_HELP_OPT ("-z", "Turn off secondary CPU core")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(smc)
+ .cmd = do_smc,
+ BAREBOX_CMD_DESC("secure monitor test command")
+BAREBOX_CMD_END
+#endif \ No newline at end of file
diff --git a/arch/arm/cpu/sm.c b/arch/arm/cpu/sm.c
new file mode 100644
index 0000000..5808dfd
--- /dev/null
+++ b/arch/arm/cpu/sm.c
@@ -0,0 +1,266 @@
+/*
+ * (C) Copyright 2013
+ * Andre Przywara, Linaro <andre.przywara@linaro.org>
+ *
+ * Routines to transition ARMv7 processors from secure into non-secure state
+ * and from non-secure SVC into HYP mode
+ * needed to enable ARMv7 virtualization for current hypervisors
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#define pr_fmt(fmt) "secure: " fmt
+
+#include <common.h>
+#include <io.h>
+#include <asm/gic.h>
+#include <asm/system.h>
+#include <init.h>
+#include <globalvar.h>
+#include <asm/arm-smccc.h>
+#include <asm-generic/sections.h>
+#include <asm/secure.h>
+
+#include "mmu.h"
+
+/* valid bits in CBAR register / PERIPHBASE value */
+#define CBAR_MASK 0xFFFF8000
+
+static unsigned int read_id_pfr1(void)
+{
+ unsigned int reg;
+
+ asm("mrc p15, 0, %0, c0, c1, 1\n" : "=r"(reg));
+ return reg;
+}
+
+static u32 read_nsacr(void)
+{
+ unsigned int reg;
+
+ asm("mrc p15, 0, %0, c1, c1, 2\n" : "=r"(reg));
+ return reg;
+}
+
+static void write_nsacr(u32 val)
+{
+ asm("mcr p15, 0, %0, c1, c1, 2" : : "r"(val));
+}
+
+static void write_mvbar(u32 val)
+{
+ asm("mcr p15, 0, %0, c12, c0, 1" : : "r"(val));
+}
+
+static unsigned long get_cbar(void)
+{
+ unsigned periphbase;
+
+ /* get the GIC base address from the CBAR register */
+ asm("mrc p15, 4, %0, c15, c0, 0\n" : "=r" (periphbase));
+
+ /* the PERIPHBASE can be mapped above 4 GB (lower 8 bits used to
+ * encode this). Bail out here since we cannot access this without
+ * enabling paging.
+ */
+ if ((periphbase & 0xff) != 0) {
+ pr_err("PERIPHBASE is above 4 GB, no access.\n");
+ return -1;
+ }
+
+ return periphbase & CBAR_MASK;
+}
+
+static unsigned long get_gicd_base_address(void)
+{
+ return get_cbar() + GIC_DIST_OFFSET;
+}
+
+static int cpu_is_virt_capable(void)
+{
+ return read_id_pfr1() & (1 << 12);
+}
+
+static unsigned long get_gicc_base_address(void)
+{
+ unsigned long adr = get_cbar();
+
+ if (cpu_is_virt_capable())
+ adr += GIC_CPU_OFFSET_A15;
+ else
+ adr += GIC_CPU_OFFSET_A9;
+
+ return adr;
+}
+
+#define GICD_IGROUPRn 0x0080
+
+int armv7_init_nonsec(void)
+{
+ void __iomem *gicd = IOMEM(get_gicd_base_address());
+ unsigned itlinesnr, i;
+ u32 val;
+
+ /*
+ * the SCR register will be set directly in the monitor mode handler,
+ * according to the spec one should not tinker with it in secure state
+ * in SVC mode. Do not try to read it once in non-secure state,
+ * any access to it will trap.
+ */
+
+ /* enable the GIC distributor */
+ val = readl(gicd + GICD_CTLR);
+ val |= 0x3;
+ writel(val, gicd + GICD_CTLR);
+
+ /* TYPER[4:0] contains an encoded number of available interrupts */
+ itlinesnr = readl(gicd + GICD_TYPER) & 0x1f;
+
+ /*
+ * Set all bits in the GIC group registers to one to allow access
+ * from non-secure state. The first 32 interrupts are private per
+ * CPU and will be set later when enabling the GIC for each core
+ */
+ for (i = 1; i <= itlinesnr; i++)
+ writel(0xffffffff, gicd + GICD_IGROUPRn + 4 * i);
+
+ return 0;
+}
+
+/*
+ * armv7_secure_monitor_install - install secure monitor
+ *
+ * This function is entered in secure mode. It installs the secure
+ * monitor code and enters it using a smc call. This function is executed
+ * on every CPU. We leave this function returns in nonsecure mode.
+ */
+int __armv7_secure_monitor_install(void)
+{
+ struct arm_smccc_res res;
+ void __iomem *gicd = IOMEM(get_gicd_base_address());
+ void __iomem *gicc = IOMEM(get_gicc_base_address());
+ u32 nsacr;
+
+ writel(0xffffffff, gicd + GICD_IGROUPRn);
+
+ writel(0x3, gicc + GICC_CTLR);
+ writel(0xff, gicc + GICC_PMR);
+
+ nsacr = read_nsacr();
+ nsacr |= 0x00043fff; /* all copros allowed in non-secure mode */
+ write_nsacr(nsacr);
+
+ write_mvbar((unsigned long)secure_monitor_init_vectors);
+
+ isb();
+
+ /* Initialize the secure monitor */
+ arm_smccc_smc(0, 0, 0, 0, 0, 0, 0, 0, &res);
+
+ /* We're in nonsecure mode now */
+
+ return 0;
+}
+
+static bool armv7_have_security_extensions(void)
+{
+ return (read_id_pfr1() & 0xf0) != 0;
+}
+
+/*
+ * armv7_secure_monitor_install - install secure monitor
+ *
+ * This function is entered in secure mode. It installs the secure
+ * monitor code and enters it using a smc call. This function is executed
+ * once on the primary CPU only. We leave this function returns in nonsecure
+ * mode.
+ */
+int armv7_secure_monitor_install(void)
+{
+ int mmuon;
+ unsigned long ttb, vbar;
+
+ if (!armv7_have_security_extensions()) {
+ pr_err("Security extensions not implemented.\n");
+ return -EINVAL;
+ }
+
+ mmuon = get_cr() & CR_M;
+
+ vbar = get_vbar();
+
+ asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r"(ttb));
+
+ armv7_init_nonsec();
+ __armv7_secure_monitor_install();
+
+ asm volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r"(ttb));
+
+ set_vbar(vbar);
+
+ if (mmuon) {
+ /*
+ * If the MMU was already turned on in secure mode, enable it in
+ * non-secure mode aswell
+ */
+ __mmu_cache_on();
+ }
+
+ pr_debug("Initialized secure monitor\n");
+
+ return 0;
+}
+
+/*
+ * of_secure_monitor_fixup - reserve memory region for secure monitor
+ *
+ * We currently do not support putting the secure monitor into onchip RAM,
+ * hence it runs in SDRAM and we must reserve the memory region so that we
+ * won't get overwritten from the Kernel.
+ * Beware: despite the name this is not secure in any way. The Kernel obeys
+ * the reserve map, but only because it's nice. It could always overwrite the
+ * secure monitor and hijack secure mode.
+ */
+static int of_secure_monitor_fixup(struct device_node *root, void *unused)
+{
+ unsigned long res_start, res_end;
+
+ res_start = (unsigned long)_stext;
+ res_end = (unsigned long)__bss_stop;
+
+ of_add_reserve_entry(res_start, res_end);
+
+ pr_debug("Reserved memory range from 0x%08lx to 0x%08lx\n", res_start, res_end);
+
+ return 0;
+}
+
+static enum arm_security_state bootm_secure_state;
+
+static const char * const bootm_secure_state_names[] = {
+ [ARM_STATE_SECURE] = "secure",
+ [ARM_STATE_NONSECURE] = "nonsecure",
+ [ARM_STATE_HYP] = "hyp",
+};
+
+enum arm_security_state bootm_arm_security_state(void)
+{
+ return bootm_secure_state;
+}
+
+const char *bootm_arm_security_state_name(enum arm_security_state state)
+{
+ return bootm_secure_state_names[state];
+}
+
+static int sm_init(void)
+{
+ of_register_fixup(of_secure_monitor_fixup, NULL);
+
+ globalvar_add_simple_enum("bootm.secure_state",
+ (unsigned int *)&bootm_secure_state,
+ bootm_secure_state_names,
+ ARRAY_SIZE(bootm_secure_state_names));
+
+ return 0;
+}
+device_initcall(sm_init); \ No newline at end of file
diff --git a/arch/arm/cpu/sm_as.S b/arch/arm/cpu/sm_as.S
new file mode 100644
index 0000000..09580e7
--- /dev/null
+++ b/arch/arm/cpu/sm_as.S
@@ -0,0 +1,168 @@
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm-generic/memory_layout.h>
+#include <asm/secure.h>
+#include <asm/system.h>
+
+.arch_extension sec
+.arch_extension virt
+
+ .section ".text","ax"
+ .arm
+
+ .align 5
+.globl secure_monitor_init_vectors
+secure_monitor_init_vectors:
+1: b 1b /* reset */
+1: b 1b /* undefined instruction */
+ b secure_monitor_init /* software interrupt (SWI) */
+1: b 1b /* prefetch abort */
+1: b 1b /* data abort */
+1: b 1b /* (reserved) */
+1: b 1b /* irq (interrupt) */
+1: b 1b /* fiq (fast interrupt) */
+
+#define CPUID_ARM_GENTIMER_MASK (0xF << CPUID_ARM_GENTIMER_SHIFT)
+#define CPUID_ARM_GENTIMER_SHIFT 16
+
+#define CPUID_ARM_VIRT_MASK (0xF << CPUID_ARM_VIRT_SHIFT)
+#define CPUID_ARM_VIRT_SHIFT 12
+
+.macro is_cpu_virt_capable tmp
+ mrc p15, 0, \tmp, c0, c1, 1 @ read ID_PFR1
+ and \tmp, \tmp, #CPUID_ARM_VIRT_MASK @ mask virtualization bits
+ cmp \tmp, #(1 << CPUID_ARM_VIRT_SHIFT)
+.endm
+
+@ Requires dense and single-cluster CPU ID space
+ENTRY(psci_get_cpu_id)
+ mrc p15, 0, r0, c0, c0, 5 /* read MPIDR */
+ and r0, r0, #0xff /* return CPU ID in cluster */
+ bx lr
+ENDPROC(psci_get_cpu_id)
+
+ENTRY(secure_monitor_stack_setup)
+ mrc p15, 0, r0, c0, c0, 5 /* read MPIDR */
+ and r0, r0, #0xff /* CPU ID => r0 */
+
+ @ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT)
+ ldr r1, =__secure_stack_end
+ sub r0, r1, r0, LSL #ARM_SECURE_STACK_SHIFT
+ sub r0, r0, #4 @ Save space for target PC
+
+ mov sp, r0
+ bx lr
+ENDPROC(secure_monitor_stack_setup)
+
+secure_monitor_init:
+ mov r3, lr
+
+ bl secure_monitor_stack_setup
+
+ push {r4-r7}
+ mov r7, r3
+ ldr r5, =secure_monitor_vectors @ Switch MVBAR to secure_monitor_vectors
+ mcr p15, 0, r5, c12, c0, 1
+ isb
+
+#ifdef CONFIG_MMU
+ mrc p15, 0, r5, c1, c0, 0
+ tst r5, #CR_M
+ beq 1f
+ bl __mmu_cache_off
+1:
+#endif
+ mrc p15, 0, r5, c1, c1, 0 @ read SCR
+ bic r5, r5, #0x4a @ clear IRQ, EA, nET bits
+ orr r5, r5, #0x31 @ enable NS, AW, FW bits
+ @ FIQ preserved for secure mode
+ mov r6, #SVC_MODE @ default mode is SVC
+
+ is_cpu_virt_capable r4
+
+ orreq r5, r5, #0x100 @ allow HVC instruction
+
+ mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set)
+ isb
+
+ mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value
+ mcreq p15, 4, r0, c12, c0, 0 @ write HVBAR
+
+ bne 1f
+
+ @ Reset CNTVOFF to 0 before leaving monitor mode
+ mrc p15, 0, r4, c0, c1, 1 @ read ID_PFR1
+ ands r4, r4, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits
+ movne r4, #0
+ mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero
+1:
+ mov lr, r7
+ mov ip, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT) @ Set A, I and F
+ tst lr, #1 @ Check for Thumb PC
+ orrne ip, ip, #PSR_T_BIT @ Set T if Thumb
+ orr ip, ip, r6 @ Slot target mode in
+ msr spsr_cxfs, ip @ Set full SPSR
+ pop {r4-r7}
+ movs pc, lr @ ERET to non-secure
+
+ .align 5
+secure_monitor_vectors:
+1: b 1b /* reset */
+1: b 1b /* undefined instruction */
+ b secure_monitor /* software interrupt (SWI) */
+1: b 1b /* prefetch abort */
+1: b 1b /* data abort */
+1: b hyp_trap /* (reserved) */
+1: b 1b /* irq (interrupt) */
+1: b 1b /* fiq (fast interrupt) */
+
+secure_monitor:
+ push {r4-r7,lr}
+
+ @ Switch to secure mode
+ mrc p15, 0, r7, c1, c1, 0
+ bic r4, r7, #1
+ mcr p15, 0, r4, c1, c1, 0
+ isb
+
+ /* r0-r6: Arguments */
+ sub sp, sp, #4*4 @ allocate result structure on stack
+ mov r12, sp
+ push {r4-r6, r12}
+ bl psci_entry
+ pop {r4-r6, r12}
+ ldm r12, {r0-r3}
+ add sp, sp, #4*4
+ /* r0-r3: results, r4-r14: preserved */
+
+ @ back to non-secure
+ mcr p15, 0, r7, c1, c1, 0
+
+ pop {r4-r7, lr}
+ movs pc, lr
+
+hyp_trap:
+ mrs lr, elr_hyp @ for older asm: .byte 0x00, 0xe3, 0x0e, 0xe1
+ mov pc, lr @ do no switch modes, but
+ @ return to caller
+
+ENTRY(armv7_switch_to_hyp)
+ mov r0, lr
+ mov r1, sp @ save SVC copy of LR and SP
+ isb
+ hvc #0 @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1
+ mov sp, r1
+ mov lr, r0 @ restore SVC copy of LR and SP
+
+ bx lr
+ENDPROC(armv7_switch_to_hyp)
+
+ENTRY(psci_cpu_entry)
+ mrc p15, 0, r0, c1, c0, 1 @ ACTLR
+ orr r0, r0, #(1 << 6) @ Set SMP bit
+ mcr p15, 0, r0, c1, c0, 1 @ ACTLR
+
+ bl secure_monitor_stack_setup
+ bl psci_cpu_entry_c
+
+ENDPROC(psci_cpu_entry)
diff --git a/arch/arm/cpu/smccc-call.S b/arch/arm/cpu/smccc-call.S
new file mode 100644
index 0000000..c2781b1
--- /dev/null
+++ b/arch/arm/cpu/smccc-call.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <linux/linkage.h>
+
+#include <asm/unwind.h>
+
+ .arch_extension sec
+ .arch_extension virt
+ .arm
+
+ /*
+ * Wrap c macros in asm macros to delay expansion until after the
+ * SMCCC asm macro is expanded.
+ */
+ .macro SMCCC_SMC
+ smc #0
+ .endm
+
+ .macro SMCCC_HVC
+ hvc #0
+ .endm
+
+ .macro SMCCC instr
+UNWIND( .fnstart)
+ mov r12, sp
+ push {r4-r7}
+UNWIND( .save {r4-r7})
+ ldm r12, {r4-r7}
+ \instr
+ pop {r4-r7}
+ ldr r12, [sp, #(4 * 4)]
+ stm r12, {r0-r3}
+ bx lr
+UNWIND( .fnend)
+ .endm
+
+/*
+ * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ * unsigned long a3, unsigned long a4, unsigned long a5,
+ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
+ */
+ENTRY(arm_smccc_smc)
+ SMCCC SMCCC_SMC
+ENDPROC(arm_smccc_smc)
+
+/*
+ * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ * unsigned long a3, unsigned long a4, unsigned long a5,
+ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
+ */
+ENTRY(arm_smccc_hvc)
+ SMCCC SMCCC_HVC
+ENDPROC(arm_smccc_hvc)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 8ba9957..70359d8 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -79,6 +79,15 @@ 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_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
+pbl-dtb-$(CONFIG_MACH_ZII_RDU2) += imx6q-zii-rdu2.dtb.o imx6qp-zii-rdu2.dtb.o
+pbl-dtb-$(CONFIG_MACH_ZII_VF610_DEV) += \
+ vf610-zii-dev-rev-b.dtb.o \
+ vf610-zii-dev-rev-c.dtb.o \
+ vf610-zii-cfu1-rev-a.dtb.o \
+ vf610-zii-spu3-rev-a.dtb.o \
+ vf610-zii-scu4-aib-rev-c.dtb.o
+
clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts *.dtb.lzo
diff --git a/arch/arm/dts/imx6q-zii-rdu2.dts b/arch/arm/dts/imx6q-zii-rdu2.dts
new file mode 100644
index 0000000..db75e29
--- /dev/null
+++ b/arch/arm/dts/imx6q-zii-rdu2.dts
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016 Zodiac Inflight Innovations
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <arm/imx6q.dtsi>
+#include "imx6q.dtsi"
+#include "imx6qdl-zii-rdu2.dtsi"
+
+/ {
+ model = "ZII RDU2 Board";
+ compatible = "zii,imx6q-zii-rdu2", "fsl,imx6q";
+};
diff --git a/arch/arm/dts/imx6qdl-zii-rdu2.dtsi b/arch/arm/dts/imx6qdl-zii-rdu2.dtsi
new file mode 100644
index 0000000..5b255e9
--- /dev/null
+++ b/arch/arm/dts/imx6qdl-zii-rdu2.dtsi
@@ -0,0 +1,541 @@
+/*
+ * Copyright 2016 Zodiac Inflight Innovations
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ linux,stdout-path = &uart1;
+
+ environment@0 {
+ compatible = "barebox,environment";
+ device-path = &nor_flash, "partname:barebox-environment";
+ };
+ };
+
+ mdio {
+ compatible = "virtual,mdio-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mdio1>;
+ gpios = <&gpio6 5 GPIO_ACTIVE_HIGH
+ &gpio6 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_28p0v: 28p0v {
+ /* main power in */
+ compatible = "regulator-fixed";
+ regulator-name = "28P0V";
+ regulator-min-microvolt = <28000000>;
+ regulator-max-microvolt = <28000000>;
+ regulator-always-on;
+ };
+
+ reg_12p0v: 12p0v {
+ /* main internal power */
+ compatible = "regulator-fixed";
+ vin-supply = <&reg_28p0v>;
+ regulator-name = "12P0V";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ };
+
+ reg_12p0v_periph: 12p0vperiph {
+ compatible = "regulator-fixed";
+ vin-supply = <&reg_28p0v>;
+ regulator-name = "12P0V-PERIPH";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ /* controlled via "environment processor" */
+ regulator-always-on;
+ };
+
+ reg_5p0v_main: 5p0vmain {
+ compatible = "regulator-fixed";
+ vin-supply = <&reg_12p0v>;
+ regulator-name = "5P0MAIN";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ /* controlled via "environment processor" */
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg_supply>;
+ vin-supply = <&reg_5p0v_main>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 GPIO_ACTIVE_LOW>;
+ startup-delay-us = <1000>;
+ };
+
+ reg_usb_h1_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ vin-supply = <&reg_5p0v_main>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+
+ imx6qdl-sabresd {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ /* USB Charging Controller */
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x1b0b0 /*USB_ATT_DETn*/
+ MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x1b0b0 /*USB_EMULATION*/
+ MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x1b0b0 /*USB_MODE1*/
+ MX6QDL_PAD_EIM_D21__GPIO3_IO21 0x1b0b0 /*USB_ALERTn*/
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /*USB_PWR_CTRL_ENn*/
+ MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x1b0b0 /*USB_MODE2*/
+
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13020 /*USB_OTG_ID*/
+
+ MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x1b0b0 /*INT_TOUCH_N*/
+
+ /* DAC */
+ MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0 /*DAC1_RESET*/
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0 /*DAC2_RESET*/
+
+ /* Need to Place */
+ MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x1b0b0 /*RMII_INTRPT*/
+ MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x1b8b0 /*SD_CARD_RESET - Open Drain Output*/
+
+ /* Test Points */
+ MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1b0b0 /*TP20*/
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /*TP21*/
+ MX6QDL_PAD_SD3_DAT6__GPIO6_IO18 0x1b0b0 /*TP22*/
+ MX6QDL_PAD_SD3_DAT7__GPIO6_IO17 0x1b0b0 /*TP23*/
+ MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 0x1b0b0 /*TP19*/
+ MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x1b0b0 /*TP26*/
+ MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0 /*TP27*/
+ MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x1b0b0 /*TP28*/
+ MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /*TP29*/
+ MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x1b0b0 /*TP30*/
+ MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x1b0b0 /*TP25*/
+ MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19 0x1b0b0 /*TP39*/
+ MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x1b0b0 /*TP40*/
+ MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x1b0b0 /*TP42*/
+ MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x1b0b0 /*TP43*/
+ MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x1b0b0 /*TP44*/
+ MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01 0x1b0b0 /*TP45*/
+ MX6QDL_PAD_CSI0_DAT16__GPIO6_IO02 0x1b0b0 /*TP46*/
+ MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x1b0b0 /*TP41*/
+
+ /* System Type */
+ MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x1b0b0 /*SYS_TYPE_3*/
+ MX6QDL_PAD_EIM_D27__GPIO3_IO27 0x1b0b0 /*SYS_TYPE_2*/
+ MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x1b0b0 /*SYS_TYPE_1*/
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0 /*SYS_TYPE_0*/
+
+ /* Boot Mode Selection Pins */
+ MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0x1b0b0 /*BT_CFG1_0*/
+ MX6QDL_PAD_EIM_DA1__GPIO3_IO01 0x1b0b0 /*BT_CFG1_1*/
+ MX6QDL_PAD_EIM_DA2__GPIO3_IO02 0x1b0b0 /*BT_CFG1_2*/
+ MX6QDL_PAD_EIM_DA3__GPIO3_IO03 0x1b0b0 /*BT_CFG1_3*/
+ MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x1b0b0 /*BT_CFG1_4*/
+ MX6QDL_PAD_EIM_DA5__GPIO3_IO05 0x1b0b0 /*BT_CFG1_5*/
+ MX6QDL_PAD_EIM_DA6__GPIO3_IO06 0x1b0b0 /*BT_CFG1_6*/
+ MX6QDL_PAD_EIM_DA7__GPIO3_IO07 0x1b0b0 /*BT_CFG1_7*/
+
+ MX6QDL_PAD_EIM_DA8__GPIO3_IO08 0x1b0b0 /*BT_CFG2_0*/
+ MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x1b0b0 /*BT_CFG2_1*/
+ MX6QDL_PAD_EIM_DA10__GPIO3_IO10 0x1b0b0 /*BT_CFG2_2*/
+ MX6QDL_PAD_EIM_DA11__GPIO3_IO11 0x1b0b0 /*BT_CFG2_3*/
+ MX6QDL_PAD_EIM_DA12__GPIO3_IO12 0x1b0b0 /*BT_CFG2_4*/
+ MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x1b0b0 /*BT_CFG2_5*/
+ MX6QDL_PAD_EIM_DA14__GPIO3_IO14 0x1b0b0 /*BT_CFG2_6*/
+ MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x1b0b0 /*BT_CFG2_7*/
+
+ MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x1b0b0 /*BT_CFG3_0*/
+ MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x1b0b0 /*BT_CFG3_1*/
+ MX6QDL_PAD_EIM_A18__GPIO2_IO20 0x1b0b0 /*BT_CFG3_2*/
+ MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x1b0b0 /*BT_CFG3_3*/
+ MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x1b0b0 /*BT_CFG3_4*/
+ MX6QDL_PAD_EIM_A21__GPIO2_IO17 0x1b0b0 /*BT_CFG3_5*/
+ MX6QDL_PAD_EIM_A22__GPIO2_IO16 0x1b0b0 /*BT_CFG3_6*/
+ MX6QDL_PAD_EIM_A23__GPIO6_IO06 0x1b0b0 /*BT_CFG3_7*/
+
+ MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x1b0b0 /*BT_CFG4_0*/
+ MX6QDL_PAD_EIM_WAIT__GPIO5_IO00 0x1b0b0 /*BT_CFG4_1*/
+ MX6QDL_PAD_EIM_LBA__GPIO2_IO27 0x1b0b0 /*BT_CFG4_2*/
+ MX6QDL_PAD_EIM_EB0__GPIO2_IO28 0x1b0b0 /*BT_CFG4_3*/
+ MX6QDL_PAD_EIM_EB1__GPIO2_IO29 0x1b0b0 /*BT_CFG4_4*/
+ MX6QDL_PAD_EIM_RW__GPIO2_IO26 0x1b0b0 /*BT_CFG4_5*/
+ MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x1b0b0 /*BT_CFG4_7*/
+
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0 /* HPA1_SDn */
+ MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x1b0b0 /* HPA2_SDn */
+ MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x1b0b0 /* RST_TOUCH# */
+ MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x1b0b0 /* NFC_RESET */
+ >;
+ };
+
+ pinctrl_usb_otg_supply: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x40000038
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ /*MX6QDL_PAD_EIM_D17__GPIO3_IO17 0x1b0b0*/
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ /*MX6QDL_PAD_EIM_EB2__ECSPI1_SS0 0x100b1*/
+ MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b1
+ /*MX6QDL_PAD_KEY_COL2__ECSPI1_SS1 0x1b0b1
+ MX6QDL_PAD_KEY_COL2__GPIO4_IO10*/
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
+ MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0
+ MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0
+
+ MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1b0b0
+ >;
+ };
+
+ pinctrl_ssi2: ssi3grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0
+ MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x130b0
+ MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+ MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3_gpio: i2c3grp_gpio {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x1b0b1
+ MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x1b0b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17069
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x17069
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17069
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17069
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17069
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17069
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17069
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x17069
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17069
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17069
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17069
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17069
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
+ MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
+ MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
+ MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
+ MX6QDL_PAD_NANDF_ALE__SD4_RESET 0x1b0b1
+ >;
+ };
+
+ pinctrl_mdio1: bitbangmdiogrp {
+ fsl,pins = <
+ /* Bitbang MDIO for DEB Switch */
+ MX6QDL_PAD_CSI0_DAT19__GPIO6_IO05 0x1b030 /*SWITCH_MDC*/
+ MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04 0x18830 /*SWITCH_MDIO*/
+ >;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio2 30 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ status = "okay";
+
+ nor_flash: m25p128@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p128";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+
+ partition@0 {
+ label = "barebox";
+ reg = <0x0 0xc0000>;
+ };
+
+ partition@e0000 {
+ label = "barebox-environment";
+ reg = <0xc0000 0x40000>;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+};
+
+&tempmon {
+ barebox,sensor-name = "TEMPMON";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ lm75@48 {
+ compatible = "national,lm75";
+ reg = <0x48>;
+ barebox,sensor-name = "Temp Sensor 1";
+ };
+
+ rtc: ds1341@68 {
+ compatible = "dallas,ds1341";
+ reg = <0x68>;
+ };
+
+ mx6_eeprom: at24@54 {
+ compatible = "at,24c128";
+ pagesize = <32>; /* TODO: VERIFY PAGE SIZE */
+ reg = <0x54>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_gpio>;
+ scl-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing_innolux_10_1>;
+ timing_innolux_10_1: innolux_10_1 {
+ clock-frequency = <71100000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hback-porch = <40>;
+ hfront-porch = <40>;
+ vback-porch = <10>;
+ vfront-porch = <3>;
+ hsync-len = <80>;
+ vsync-len = <10>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio7 12 0>;
+ status = "okay";
+};
+
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <8>;
+ non-removable;
+ no-1-8-v;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_h1_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ disable-over-current;
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio1 23 0>;
+ status = "okay";
+
+ fixed-link {
+ speed = <100>;
+ full-duplex;
+ };
+};
diff --git a/arch/arm/dts/imx6qp-zii-rdu2.dts b/arch/arm/dts/imx6qp-zii-rdu2.dts
new file mode 100644
index 0000000..fcf2ee5
--- /dev/null
+++ b/arch/arm/dts/imx6qp-zii-rdu2.dts
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016 Zodiac Inflight Innovations
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <arm/imx6qp.dtsi>
+#include "imx6q.dtsi"
+#include "imx6qdl-zii-rdu2.dtsi"
+
+/ {
+ model = "ZII RDU2+ Board";
+ compatible = "zii,imx6qp-zii-rdu2", "fsl,imx6qp";
+};
diff --git a/arch/arm/dts/imx7s-warp.dts b/arch/arm/dts/imx7s-warp.dts
new file mode 100644
index 0000000..a59823d
--- /dev/null
+++ b/arch/arm/dts/imx7s-warp.dts
@@ -0,0 +1,62 @@
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <arm/imx7s-warp.dts>
+#include "imx7s.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+
+ environment@0 {
+ compatible = "barebox,environment";
+ device-path = &bareboxenv;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>;
+ };
+};
+
+&usdhc3 {
+ boot0-partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ barebox@0 {
+ label = "barebox";
+ reg = <0x0 0x300000>;
+ };
+
+ bareboxenv: bareboxenv@300000 {
+ label = "bareboxenv";
+ reg = <0x300000 0x0>;
+ };
+ };
+};
+
+/*
+/* The watchdog pinctrl is attached to the wrong iomux controller in
+ * the upstream dts file. This can be removed once we pull in the
+ * corresponding fix from the upstream dts files.
+ */
+&wdog1 {
+ pinctrl-0 = <&pinctrl_wdog_lpsr>;
+};
+
+&iomuxc_lpsr {
+ pinctrl_wdog_lpsr: wdoggrp {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B 0x74
+ >;
+ };
+};
diff --git a/arch/arm/dts/imx7s.dtsi b/arch/arm/dts/imx7s.dtsi
new file mode 100644
index 0000000..95c7907
--- /dev/null
+++ b/arch/arm/dts/imx7s.dtsi
@@ -0,0 +1,4 @@
+&gpt1 {
+ clocks = <&clks IMX7D_GPT1_ROOT_CLK>,
+ <&clks IMX7D_GPT1_ROOT_CLK>;
+}; \ No newline at end of file
diff --git a/arch/arm/dts/vf610-zii-cfu1-rev-a.dts b/arch/arm/dts/vf610-zii-cfu1-rev-a.dts
new file mode 100644
index 0000000..4147d13
--- /dev/null
+++ b/arch/arm/dts/vf610-zii-cfu1-rev-a.dts
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2015, 2016 Zodiac Inflight Innovations
+ *
+ * Based on an original 'vf610-twr.dts' which is Copyright 2015,
+ * Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file 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 file 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+/dts-v1/;
+#include "vf610-zii-dev.dtsi"
+
+/ {
+ model = "ZII VF610 CFU1 Switch Management Board";
+ compatible = "zii,vf610cfu1-a", "zii,vf610dev", "fsl,vf610";
+
+ aliases {
+ /delete-property/ serial1;
+ /delete-property/ serial2;
+ };
+
+ gpio-leds {
+ debug {
+ gpios = <&gpio2 18 GPIO_ACTIVE_HIGH>;
+ };
+
+ fail {
+ label = "zii_fail";
+ gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ max-brightness = <1>;
+ };
+
+ status {
+ label = "zii_status";
+ gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ max-brightness = <1>;
+ };
+
+ status_a {
+ label = "zii_status_a";
+ gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ max-brightness = <1>;
+ };
+
+ status_b {
+ label = "zii_status_b";
+ gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ max-brightness = <1>;
+ };
+ };
+};
+
+&dspi1 {
+ bus-num = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dspi1>;
+ status = "okay";
+
+ m25p128@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p128", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+
+ partition@0 {
+ label = "m25p128-0";
+ reg = <0x0 0x01000000>;
+ };
+ };
+};
+
+&esdhc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc0>;
+ bus-width = <8>;
+ status = "okay";
+};
+
+&fec0 {
+ status = "disabled";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+
+ pca9554@22 {
+ compatible = "nxp,pca9554";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+/delete-node/ &i2c1;
+/delete-node/ &i2c2;
+/delete-node/ &uart1;
+/delete-node/ &uart2;
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ VF610_PAD_PTE2__GPIO_107 0x31c2 /* SOC_SW_RSTn */
+ VF610_PAD_PTB28__GPIO_98 0x31c1 /* E6352_INTn */
+
+ /* PTE27 is wired to signal SD on part CONN
+ * SFF-F4 via net FIM_DS. An active high
+ * on this indicates a received optical
+ * signal
+
+ * SPEED=0b11 HIGH, SRE=0b0, ODE=0b0, HYS=0b0
+ * DSE=0b001 150Ohm, PUS=0b10 100k UP
+ * PKE=0b0, PUE=0b0, OBE=0b0, IBE=0b1
+ */
+ VF610_PAD_PTE27__GPIO_132 0x3061
+
+ /*
+ * PTE13 is wired to signal T_DIS on part CONN
+ * SFF-F4 via net FIM_TDIS. Setting this high
+ * will disable optical output from the SFF-F4
+
+ * SPEED=0b11 HIGH, SRE=0b0, ODE=0b0, HYS=0b0
+ * DSE=0b001 150Ohm, PUS=0b00 100k DOWN
+ * PKE=0b0, PUE=0b0, OBE=0b1, IBE=0b1
+ * TODO: probably want IBE=0b0
+ */
+ VF610_PAD_PTE13__GPIO_118 0x3043
+ >;
+ };
+
+ pinctrl_dspi1: dspi1grp {
+ fsl,pins = <
+ VF610_PAD_PTD5__DSPI1_CS0 0x1182
+ VF610_PAD_PTC6__DSPI1_SIN 0x1181
+ VF610_PAD_PTC7__DSPI1_SOUT 0x1182
+ VF610_PAD_PTC8__DSPI1_SCK 0x1182
+ >;
+ };
+
+ pinctrl_esdhc0: esdhc0grp {
+ fsl,pins = <
+ VF610_PAD_PTC0__ESDHC0_CLK 0x31ef
+ VF610_PAD_PTC1__ESDHC0_CMD 0x31ef
+ VF610_PAD_PTC2__ESDHC0_DAT0 0x31ef
+ VF610_PAD_PTC3__ESDHC0_DAT1 0x31ef
+ VF610_PAD_PTC4__ESDHC0_DAT2 0x31ef
+ VF610_PAD_PTC5__ESDHC0_DAT3 0x31ef
+ VF610_PAD_PTD23__ESDHC0_DAT4 0x31ef
+ VF610_PAD_PTD22__ESDHC0_DAT5 0x31ef
+ VF610_PAD_PTD21__ESDHC0_DAT6 0x31ef
+ VF610_PAD_PTD20__ESDHC0_DAT7 0x31ef
+ >;
+ };
+
+ pinctrl_leds_debug: pinctrl-leds-debug {
+ fsl,pins = <
+ VF610_PAD_PTD3__GPIO_82 0x31c2
+ VF610_PAD_PTE3__GPIO_108 0x31c2
+ VF610_PAD_PTE4__GPIO_109 0x31c2
+ VF610_PAD_PTE5__GPIO_110 0x31c2
+ VF610_PAD_PTE6__GPIO_111 0x31c2
+ >;
+ };
+};
diff --git a/arch/arm/dts/vf610-zii-dev-rev-b.dts b/arch/arm/dts/vf610-zii-dev-rev-b.dts
new file mode 100644
index 0000000..bf0a010
--- /dev/null
+++ b/arch/arm/dts/vf610-zii-dev-rev-b.dts
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2015, 2016 Zodiac Inflight Innovations
+ *
+ * Based on an original 'vf610-twr.dts' which is Copyright 2015,
+ * Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file 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 file 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "vf610-zii-dev.dtsi"
+
+/*
+ * =============================================================
+ * The following code is shared with Linux kernel and should be
+ * removed once it trickles down from there eventually
+ * =============================================================
+ */
+
+/ {
+ model = "ZII VF610 Development Board, Rev B";
+ compatible = "zii,vf610dev-b", "zii,vf610dev", "fsl,vf610";
+
+ mdio-mux {
+ compatible = "mdio-mux-gpio";
+ pinctrl-0 = <&pinctrl_mdio_mux>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 8 GPIO_ACTIVE_HIGH
+ &gpio0 9 GPIO_ACTIVE_HIGH
+ &gpio0 24 GPIO_ACTIVE_HIGH
+ &gpio0 25 GPIO_ACTIVE_HIGH>;
+ mdio-parent-bus = <&mdio1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mdio_mux_1: mdio@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch0: switch0@0 {
+ compatible = "marvell,mv88e6085";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ dsa,member = <0 0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ label = "lan0";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan1";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan2";
+ };
+
+ switch0port5: port@5 {
+ reg = <5>;
+ label = "dsa";
+ phy-mode = "rgmii-txid";
+ link = <&switch1port6
+ &switch2port9>;
+ };
+
+ port@6 {
+ reg = <6>;
+ label = "cpu";
+ ethernet = <&fec1>;
+ fixed-link {
+ speed = <100>;
+ full-duplex;
+ };
+ };
+ };
+ };
+ };
+
+ mdio_mux_2: mdio@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch1: switch1@0 {
+ compatible = "marvell,mv88e6085";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ dsa,member = <0 1>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ label = "lan3";
+ phy-handle = <&switch1phy0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan4";
+ phy-handle = <&switch1phy1>;
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan5";
+ phy-handle = <&switch1phy2>;
+ };
+
+ switch1port5: port@5 {
+ reg = <5>;
+ label = "dsa";
+ link = <&switch2port9>;
+ phy-mode = "rgmii-txid";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ switch1port6: port@6 {
+ reg = <6>;
+ label = "dsa";
+ phy-mode = "rgmii-txid";
+ link = <&switch0port5>;
+ };
+ };
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ switch1phy0: switch1phy0@0 {
+ reg = <0>;
+ };
+ switch1phy1: switch1phy0@1 {
+ reg = <1>;
+ };
+ switch1phy2: switch1phy0@2 {
+ reg = <2>;
+ };
+ };
+ };
+ };
+
+ mdio_mux_4: mdio@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ switch2: switch2@0 {
+ compatible = "marvell,mv88e6085";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ dsa,member = <0 2>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ label = "lan6";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan7";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan8";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "optical3";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ link-gpios = <&gpio6 2
+ GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "optical4";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ link-gpios = <&gpio6 3
+ GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ switch2port9: port@9 {
+ reg = <9>;
+ label = "dsa";
+ phy-mode = "rgmii-txid";
+ link = <&switch1port5
+ &switch0port5>;
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+ };
+ };
+
+ mdio_mux_8: mdio@8 {
+ reg = <8>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ spi0 {
+ compatible = "spi-gpio";
+ pinctrl-0 = <&pinctrl_gpio_spi0>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ gpio-sck = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ gpio-mosi = <&gpio1 11 GPIO_ACTIVE_HIGH>;
+ gpio-miso = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ cs-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH
+ &gpio1 8 GPIO_ACTIVE_HIGH>;
+ num-chipselects = <2>;
+
+ m25p128@0 {
+ compatible = "m25p128", "jedec,spi-nor";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ };
+
+ at93c46d@1 {
+ compatible = "atmel,at93c46d";
+ pinctrl-0 = <&pinctrl_gpio_e6185_eeprom_sel>;
+ pinctrl-names = "default";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ reg = <1>;
+ spi-max-frequency = <500000>;
+ spi-cs-high;
+ data-size = <16>;
+ select-gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&i2c0 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ status = "okay";
+
+ gpio5: pca9554@20 {
+ compatible = "nxp,pca9554";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ };
+
+ gpio6: pca9554@22 {
+ compatible = "nxp,pca9554";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pca9554_22>;
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ tca9548@70 {
+ compatible = "nxp,pca9548";
+ pinctrl-0 = <&pinctrl_i2c_mux_reset>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+ reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ sfp1: at24c04@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ sfp2: at24c04@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ sfp3: at24c04@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ sfp4: at24c04@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+ };
+};
+
+
+&iomuxc {
+ pinctrl_gpio_e6185_eeprom_sel: pinctrl-gpio-e6185-eeprom-spi0 {
+ fsl,pins = <
+ VF610_PAD_PTE27__GPIO_132 0x33e2
+ >;
+ };
+
+ pinctrl_gpio_spi0: pinctrl-gpio-spi0 {
+ fsl,pins = <
+ VF610_PAD_PTB22__GPIO_44 0x33e2
+ VF610_PAD_PTB21__GPIO_43 0x33e2
+ VF610_PAD_PTB20__GPIO_42 0x33e1
+ VF610_PAD_PTB19__GPIO_41 0x33e2
+ VF610_PAD_PTB18__GPIO_40 0x33e2
+ >;
+ };
+
+ pinctrl_mdio_mux: pinctrl-mdio-mux {
+ fsl,pins = <
+ VF610_PAD_PTA18__GPIO_8 0x31c2
+ VF610_PAD_PTA19__GPIO_9 0x31c2
+ VF610_PAD_PTB2__GPIO_24 0x31c2
+ VF610_PAD_PTB3__GPIO_25 0x31c2
+ >;
+ };
+
+ pinctrl_pca9554_22: pinctrl-pca95540-22 {
+ fsl,pins = <
+ VF610_PAD_PTB28__GPIO_98 0x219d
+ >;
+ };
+};
+
+/*
+ * =============================================================
+ * End of shared part
+ * =============================================================
+*/
diff --git a/arch/arm/dts/vf610-zii-dev-rev-c.dts b/arch/arm/dts/vf610-zii-dev-rev-c.dts
new file mode 100644
index 0000000..5228942
--- /dev/null
+++ b/arch/arm/dts/vf610-zii-dev-rev-c.dts
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2015, 2016 Zodiac Inflight Innovations
+ *
+ * Based on an original 'vf610-twr.dts' which is Copyright 2015,
+ * Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file 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 file 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "vf610-zii-dev.dtsi"
+
+/*
+ * =============================================================
+ * The following code is shared with Linux kernel and should be
+ * removed once it trickles down from there eventually
+ * =============================================================
+ */
+
+/ {
+ model = "ZII VF610 Development Board, Rev C";
+ compatible = "zii,vf610dev-c", "zii,vf610dev", "fsl,vf610";
+
+ mdio-mux {
+ compatible = "mdio-mux-gpio";
+ pinctrl-0 = <&pinctrl_mdio_mux>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 8 GPIO_ACTIVE_HIGH
+ &gpio0 9 GPIO_ACTIVE_HIGH
+ &gpio0 25 GPIO_ACTIVE_HIGH>;
+ mdio-parent-bus = <&mdio1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mdio_mux_1: mdio@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch0: switch0@0 {
+ compatible = "marvell,mv88e6190";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ dsa,member = <0 0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "cpu";
+ ethernet = <&fec1>;
+ fixed-link {
+ speed = <100>;
+ full-duplex;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan1";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan2";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan3";
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "lan4";
+ };
+
+ switch0port10: port@10 {
+ reg = <10>;
+ label = "dsa";
+ phy-mode = "xgmii";
+ link = <&switch1port10>;
+ };
+ };
+ };
+ };
+
+ mdio_mux_2: mdio@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch1: switch1@0 {
+ compatible = "marvell,mv88e6190";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ dsa,member = <0 1>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+ label = "lan5";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan6";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan7";
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "lan8";
+ };
+
+
+ switch1port10: port@10 {
+ reg = <10>;
+ label = "dsa";
+ phy-mode = "xgmii";
+ link = <&switch0port10>;
+ };
+ };
+ };
+ };
+
+ mdio_mux_4: mdio@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+&dspi0 {
+ bus-num = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dspi0>;
+ status = "okay";
+ spi-num-chipselects = <2>;
+
+ m25p128@0 {
+ compatible = "m25p128", "jedec,spi-nor";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ };
+
+ atzb-rf-233@1 {
+ compatible = "atmel,at86rf233";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctr_atzb_rf_233>;
+
+ spi-max-frequency = <7500000>;
+ reg = <1>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gpio3>;
+ xtal-trim = /bits/ 8 <0x06>;
+
+ sleep-gpio = <&gpio0 24 GPIO_ACTIVE_HIGH>;
+ reset-gpio = <&gpio6 10 GPIO_ACTIVE_HIGH>;
+
+ fsl,spi-cs-sck-delay = <180>;
+ fsl,spi-sck-cs-delay = <250>;
+ };
+};
+
+&dspi2 {
+ bus-num = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dspi2>;
+ status = "okay";
+ spi-num-chipselects = <2>;
+};
+
+&i2c0 {
+ /*
+ * U712
+ *
+ * Exposed signals:
+ * P1 - WE2_CMD
+ * P2 - WE2_CLK
+ */
+ gpio5: pca9557@18 {
+ compatible = "nxp,pca9557";
+ reg = <0x18>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ /*
+ * U121
+ *
+ * Exposed signals:
+ * I/O0 - ENET_SWR_EN
+ * I/O1 - ESW1_RESETn
+ * I/O2 - ARINC_RESET
+ * I/O3 - DD1_IO_RESET
+ * I/O4 - ESW2_RESETn
+ * I/O5 - ESW3_RESETn
+ * I/O6 - ESW4_RESETn
+ * I/O8 - TP909
+ * I/O9 - FEM_SEL
+ * I/O10 - WIFI_RESETn
+ * I/O11 - PHY_RSTn
+ * I/O12 - OPT1_SD
+ * I/O13 - OPT2_SD
+ * I/O14 - OPT1_TX_DIS
+ * I/O15 - OPT2_TX_DIS
+ */
+ gpio6: sx1503@20 {
+ compatible = "semtech,sx1503q";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sx1503_20>;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
+ gpio-controller;
+ interrupt-controller;
+
+ enet_swr_en {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "enet-swr-en";
+ };
+ };
+
+ /*
+ * U715
+ *
+ * Exposed signals:
+ * IO0 - WE1_CLK
+ * IO1 - WE1_CMD
+ */
+ gpio7: pca9554@22 {
+ compatible = "nxp,pca9554";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ };
+};
+
+&i2c1 {
+ at24mac602@00 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ read-only;
+ };
+};
+
+&i2c2 {
+ tca9548@70 {
+ compatible = "nxp,pca9548";
+ pinctrl-0 = <&pinctrl_i2c_mux_reset>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+ reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ sfp2: at24c04@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ sfp3: at24c04@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&gpio0 {
+ eth0_intrp {
+ gpio-hog;
+ gpios = <23 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "sx1503-irq";
+ };
+};
+
+&gpio3 {
+ eth0_intrp {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "eth0-intrp";
+ };
+};
+
+&fec0 {
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec0_phy_int>;
+
+ interrupt-parent = <&gpio3>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ reg = <0>;
+ };
+ };
+};
+
+&iomuxc {
+ pinctr_atzb_rf_233: pinctrl-atzb-rf-233 {
+ fsl,pins = <
+ VF610_PAD_PTB2__GPIO_24 0x31c2
+ VF610_PAD_PTE27__GPIO_132 0x33e2
+ >;
+ };
+
+
+ pinctrl_sx1503_20: pinctrl-sx1503-20 {
+ fsl,pins = <
+ VF610_PAD_PTB1__GPIO_23 0x219d
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ VF610_PAD_PTA20__UART3_TX 0x21a2
+ VF610_PAD_PTA21__UART3_RX 0x21a1
+ >;
+ };
+
+ pinctrl_mdio_mux: pinctrl-mdio-mux {
+ fsl,pins = <
+ VF610_PAD_PTA18__GPIO_8 0x31c2
+ VF610_PAD_PTA19__GPIO_9 0x31c2
+ VF610_PAD_PTB3__GPIO_25 0x31c2
+ >;
+ };
+
+ pinctrl_fec0_phy_int: pinctrl-fec0-phy-int {
+ fsl,pins = <
+ VF610_PAD_PTB28__GPIO_98 0x219d
+ >;
+ };
+};
+
+/*
+ * =============================================================
+ * End of shared part
+ * =============================================================
+ */
+
+
+&dspi0 {
+ m25p128@0 {
+ partition@0 {
+ label = "bootloader";
+ reg = <0x0 0x100000>;
+ };
+ };
+};
diff --git a/arch/arm/dts/vf610-zii-dev.dtsi b/arch/arm/dts/vf610-zii-dev.dtsi
new file mode 100644
index 0000000..dae077c
--- /dev/null
+++ b/arch/arm/dts/vf610-zii-dev.dtsi
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2015, 2016 Zodiac Inflight Innovations
+ *
+ * Based on an original 'vf610-twr.dts' which is Copyright 2015,
+ * Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file 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 file 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+n * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * =============================================================
+ * The following code is shared with Linux kernel and should be
+ * removed once it trickles down from there eventually
+ * =============================================================
+ */
+
+#include <arm/vf610.dtsi>
+
+/ {
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0x80000000 0x20000000>;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pinctrl_leds_debug>;
+ pinctrl-names = "default";
+
+ debug {
+ label = "zii:green:debug1";
+ gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ reg_vcc_3v3_mcu: regulator-vcc-3v3-mcu {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_mcu";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ usb0_vbus: regulator-usb0-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-0 = <&pinctrl_usb_vbus>;
+ regulator-name = "usb_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 6 0>;
+ };
+};
+
+&adc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0_ad5>;
+ vref-supply = <&reg_vcc_3v3_mcu>;
+ status = "okay";
+};
+
+&edma0 {
+ status = "okay";
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&fec0 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec0>;
+ status = "okay";
+};
+
+&fec1 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ status = "okay";
+
+ fixed-link {
+ speed = <100>;
+ full-duplex;
+ };
+
+ mdio1: mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ };
+};
+
+&i2c0 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ pinctrl-1 = <&pinctrl_i2c0_gpio>;
+ scl-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ lm75@48 {
+ compatible = "national,lm75";
+ reg = <0x48>;
+ };
+
+ at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+
+ at24c04@52 {
+ compatible = "atmel,24c04";
+ reg = <0x52>;
+ };
+
+ ds1682@6b {
+ compatible = "dallas,ds1682";
+ reg = <0x6b>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbdev0 {
+ disable-over-current;
+ vbus-supply = <&usb0_vbus>;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbh1 {
+ disable-over-current;
+ status = "okay";
+};
+
+&usbmisc0 {
+ status = "okay";
+};
+
+&usbmisc1 {
+ status = "okay";
+};
+
+&usbphy0 {
+ status = "okay";
+};
+
+&usbphy1 {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_adc0_ad5: adc0ad5grp {
+ fsl,pins = <
+ VF610_PAD_PTC30__ADC0_SE5 0x00a1
+ >;
+ };
+
+ pinctrl_dspi0: dspi0grp {
+ fsl,pins = <
+ VF610_PAD_PTB18__DSPI0_CS1 0x1182
+ VF610_PAD_PTB19__DSPI0_CS0 0x1182
+ VF610_PAD_PTB20__DSPI0_SIN 0x1181
+ VF610_PAD_PTB21__DSPI0_SOUT 0x1182
+ VF610_PAD_PTB22__DSPI0_SCK 0x1182
+ >;
+ };
+
+ pinctrl_dspi2: dspi2grp {
+ fsl,pins = <
+ VF610_PAD_PTD31__DSPI2_CS1 0x1182
+ VF610_PAD_PTD30__DSPI2_CS0 0x1182
+ VF610_PAD_PTD29__DSPI2_SIN 0x1181
+ VF610_PAD_PTD28__DSPI2_SOUT 0x1182
+ VF610_PAD_PTD27__DSPI2_SCK 0x1182
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ VF610_PAD_PTA24__ESDHC1_CLK 0x31ef
+ VF610_PAD_PTA25__ESDHC1_CMD 0x31ef
+ VF610_PAD_PTA26__ESDHC1_DAT0 0x31ef
+ VF610_PAD_PTA27__ESDHC1_DAT1 0x31ef
+ VF610_PAD_PTA28__ESDHC1_DATA2 0x31ef
+ VF610_PAD_PTA29__ESDHC1_DAT3 0x31ef
+ VF610_PAD_PTA7__GPIO_134 0x219d
+ >;
+ };
+
+ pinctrl_fec0: fec0grp {
+ fsl,pins = <
+ VF610_PAD_PTC0__ENET_RMII0_MDC 0x30d2
+ VF610_PAD_PTC1__ENET_RMII0_MDIO 0x30d3
+ VF610_PAD_PTC2__ENET_RMII0_CRS 0x30d1
+ VF610_PAD_PTC3__ENET_RMII0_RXD1 0x30d1
+ VF610_PAD_PTC4__ENET_RMII0_RXD0 0x30d1
+ VF610_PAD_PTC5__ENET_RMII0_RXER 0x30d1
+ VF610_PAD_PTC6__ENET_RMII0_TXD1 0x30d2
+ VF610_PAD_PTC7__ENET_RMII0_TXD0 0x30d2
+ VF610_PAD_PTC8__ENET_RMII0_TXEN 0x30d2
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ VF610_PAD_PTA6__RMII_CLKIN 0x30d1
+ VF610_PAD_PTC9__ENET_RMII1_MDC 0x30d2
+ VF610_PAD_PTC10__ENET_RMII1_MDIO 0x30d3
+ VF610_PAD_PTC11__ENET_RMII1_CRS 0x30d1
+ VF610_PAD_PTC12__ENET_RMII1_RXD1 0x30d1
+ VF610_PAD_PTC13__ENET_RMII1_RXD0 0x30d1
+ VF610_PAD_PTC14__ENET_RMII1_RXER 0x30d1
+ VF610_PAD_PTC15__ENET_RMII1_TXD1 0x30d2
+ VF610_PAD_PTC16__ENET_RMII1_TXD0 0x30d2
+ VF610_PAD_PTC17__ENET_RMII1_TXEN 0x30d2
+ >;
+ };
+
+ pinctrl_gpio_spi0: pinctrl-gpio-spi0 {
+ fsl,pins = <
+ VF610_PAD_PTB22__GPIO_44 0x33e2
+ VF610_PAD_PTB21__GPIO_43 0x33e2
+ VF610_PAD_PTB20__GPIO_42 0x33e1
+ VF610_PAD_PTB19__GPIO_41 0x33e2
+ VF610_PAD_PTB18__GPIO_40 0x33e2
+ >;
+ };
+
+ pinctrl_i2c_mux_reset: pinctrl-i2c-mux-reset {
+ fsl,pins = <
+ VF610_PAD_PTE14__GPIO_119 0x31c2
+ >;
+ };
+
+ pinctrl_i2c0: i2c0grp {
+ fsl,pins = <
+ VF610_PAD_PTB14__I2C0_SCL 0x37ff
+ VF610_PAD_PTB15__I2C0_SDA 0x37ff
+ >;
+ };
+
+ pinctrl_i2c0_gpio: i2c0grp-gpio {
+ fsl,pins = <
+ VF610_PAD_PTB14__GPIO_36 0x31c2
+ VF610_PAD_PTB15__GPIO_37 0x31c2
+ >;
+ };
+
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ VF610_PAD_PTB16__I2C1_SCL 0x37ff
+ VF610_PAD_PTB17__I2C1_SDA 0x37ff
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ VF610_PAD_PTA22__I2C2_SCL 0x37ff
+ VF610_PAD_PTA23__I2C2_SDA 0x37ff
+ >;
+ };
+
+ pinctrl_leds_debug: pinctrl-leds-debug {
+ fsl,pins = <
+ VF610_PAD_PTD20__GPIO_74 0x31c2
+ >;
+ };
+
+ pinctrl_qspi0: qspi0grp {
+ fsl,pins = <
+ VF610_PAD_PTD7__QSPI0_B_QSCK 0x31c3
+ VF610_PAD_PTD8__QSPI0_B_CS0 0x31ff
+ VF610_PAD_PTD9__QSPI0_B_DATA3 0x31c3
+ VF610_PAD_PTD10__QSPI0_B_DATA2 0x31c3
+ VF610_PAD_PTD11__QSPI0_B_DATA1 0x31c3
+ VF610_PAD_PTD12__QSPI0_B_DATA0 0x31c3
+ >;
+ };
+
+ pinctrl_uart0: uart0grp {
+ fsl,pins = <
+ VF610_PAD_PTB10__UART0_TX 0x21a2
+ VF610_PAD_PTB11__UART0_RX 0x21a1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ VF610_PAD_PTB23__UART1_TX 0x21a2
+ VF610_PAD_PTB24__UART1_RX 0x21a1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ VF610_PAD_PTD0__UART2_TX 0x21a2
+ VF610_PAD_PTD1__UART2_RX 0x21a1
+ >;
+ };
+
+ pinctrl_usb_vbus: pinctrl-usb-vbus {
+ fsl,pins = <
+ VF610_PAD_PTA16__GPIO_6 0x31c2
+ >;
+ };
+
+ pinctrl_usb0_host: usb0-host-grp {
+ fsl,pins = <
+ VF610_PAD_PTD6__GPIO_85 0x0062
+ >;
+ };
+};
+
+/*
+ * =============================================================
+ * End of shared part
+ * =============================================================
+ */
+
+/ {
+ audio_ext: mclk_osc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ enet_ext: eth_osc {
+ compatible = "fixed-clock";
+ clock-output-names = "enet_ext";
+ #clock-cells = <0>;
+ clock-frequency = <50000000>;
+ };
+
+ anaclk1: anaclk1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+};
+
+&clks {
+ clocks = <&sxosc>, <&fxosc>, <&enet_ext>, <&audio_ext>, <&anaclk1>,
+ <&clks VF610_CLK_SYS_BUS>, <&clks VF610_CLK_PLATFORM_BUS>,
+ <&clks VF610_CLK_IPG_BUS>, <&clks VF610_CLK_DDRMC>;
+ clock-names = "sxosc", "fxosc", "enet_ext", "audio_ext", "anaclk1",
+ "cpu", "bus", "ipg", "ddr";
+
+ assigned-clocks = <&clks VF610_CLK_ENET_SEL>,
+ <&clks VF610_CLK_ENET_TS_SEL>;
+ assigned-clock-parents = <&clks VF610_CLK_ENET_EXT>,
+ <&clks VF610_CLK_ENET_EXT>;
+};
+
+&ocotp {
+ barebox,provide-mac-address = <&fec0 0x620>,
+ <&fec1 0x640>;
+};
diff --git a/arch/arm/dts/vf610-zii-scu4-aib-rev-c.dts b/arch/arm/dts/vf610-zii-scu4-aib-rev-c.dts
new file mode 100644
index 0000000..d10f460
--- /dev/null
+++ b/arch/arm/dts/vf610-zii-scu4-aib-rev-c.dts
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2015, 2016 Zodiac Inflight Innovations
+ *
+ * Based on an original 'vf610-twr.dts' which is Copyright 2015,
+ * Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file 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 file 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "vf610-zii-dev.dtsi"
+
+/ {
+ model = "ZII VF610 SCU4 AIB, Rev C";
+ compatible = "zii,vf610scu4-aib-c", "zii,vf610dev", "fsl,vf610";
+
+ chosen {
+ bootargs = "console=ttyLP0,115200n8";
+ };
+
+ gpio-leds {
+ debug {
+ gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ mdio-mux {
+ compatible = "mdio-mux-gpio";
+ pinctrl-0 = <&pinctrl_mdio_mux>;
+ pinctrl-names = "default";
+ gpios = <&gpio4 4 GPIO_ACTIVE_HIGH
+ &gpio4 5 GPIO_ACTIVE_HIGH
+ &gpio3 30 GPIO_ACTIVE_HIGH
+ &gpio3 31 GPIO_ACTIVE_HIGH>;
+ mdio-parent-bus = <&mdio1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mdio_mux_1: mdio@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mdio_mux_2: mdio@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mdio_mux_4: mdio@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mdio_mux_8: mdio@8 {
+ reg = <8>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ spi2 {
+ compatible = "spi-gpio";
+ pinctrl-0 = <&pinctrl_dspi2>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio-sck = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+ gpio-mosi = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+ gpio-miso = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+ cs-gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;
+ num-chipselects = <1>;
+
+ at93c46d@0 {
+ compatible = "atmel,at93c46d";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ reg = <0>;
+ spi-max-frequency = <500000>;
+ spi-cs-high;
+ data-size = <16>;
+ select-gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&dspi0 {
+ pinctrl-0 = <&pinctrl_dspi0>, <&pinctrl_dspi0_cs_4_5>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&dspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dspi1>;
+ status = "okay";
+
+ m25p128@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p128", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+
+ partition@0 {
+ label = "m25p128-0";
+ reg = <0x0 0x01000000>;
+ };
+ };
+
+ m25p128@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p128", "jedec,spi-nor";
+ reg = <1>;
+ spi-max-frequency = <50000000>;
+
+ partition@0 {
+ label = "m25p128-1";
+ reg = <0x0 0x01000000>;
+ };
+ };
+};
+
+&esdhc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc0>;
+ bus-width = <8>;
+ status = "okay";
+};
+
+&fec0 {
+ status = "disabled";
+};
+
+&i2c0 {
+ /* Reset Signals */
+ gpio5: pca9505@20 {
+ compatible = "nxp,pca9554";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ /* Board Revision */
+ gpio6: pca9505@22 {
+ compatible = "nxp,pca9554";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&i2c1 {
+ /* Wireless 2 */
+ gpio8: pca9554@18 {
+ compatible = "nxp,pca9557";
+ reg = <0x18>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ /* Wireless 1 */
+ gpio7: pca9554@24 {
+ compatible = "nxp,pca9554";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ /* AIB voltage monitor */
+ adt7411@4a {
+ compatible = "adi,adt7411";
+ reg = <0x4a>;
+ };
+};
+
+&i2c2 {
+ /* FIB voltage monitor */
+ adt7411@4a {
+ compatible = "adi,adt7411";
+ reg = <0x4a>;
+ };
+
+ lm75_swb {
+ compatible = "national,lm75";
+ reg = <0x4e>;
+ };
+
+ lm75_swa {
+ compatible = "national,lm75";
+ reg = <0x4f>;
+ };
+
+ /* FIB Nameplate */
+ at24c08@57 {
+ compatible = "atmel,24c08";
+ reg = <0x57>;
+ };
+
+ tca9548@70 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ sff0: at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ sff1: at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ sff2: at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ sff3: at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ sff4: at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+ };
+ };
+
+
+ tca9548@71 {
+ compatible = "nxp,pca9548";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ sff5: at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ sff6: at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ sff7: at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ sff8: at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ sff9: at24c04@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ };
+ };
+ };
+};
+
+&uart1 {
+ linux,rs485-enabled-at-boot-time;
+ pinctrl-0 = <&pinctrl_uart1>, <&pinctrl_uart1_rts>;
+};
+
+&uart2 {
+ linux,rs485-enabled-at-boot-time;
+ pinctrl-0 = <&pinctrl_uart2>, <&pinctrl_uart2_rts>;
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpo_public>;
+
+
+ pinctrl_gpo_public: gpopubgrp {
+ fsl,pins = <
+ VF610_PAD_PTE2__GPIO_107 0x2062
+ VF610_PAD_PTE3__GPIO_108 0x2062
+ VF610_PAD_PTE4__GPIO_109 0x2062
+ VF610_PAD_PTE5__GPIO_110 0x2062
+ VF610_PAD_PTE6__GPIO_111 0x2062
+ >;
+ };
+
+ pinctrl_dspi0_cs_4_5: dspi0grp-cs-4-5 {
+ fsl,pins = <
+ VF610_PAD_PTB13__DSPI0_CS4 0x1182
+ VF610_PAD_PTB12__DSPI0_CS5 0x1182
+ >;
+ };
+
+ pinctrl_dspi1: dspi1grp {
+ fsl,pins = <
+ VF610_PAD_PTD5__DSPI1_CS0 0x1182
+ VF610_PAD_PTD4__DSPI1_CS1 0x1182
+ VF610_PAD_PTC6__DSPI1_SIN 0x1181
+ VF610_PAD_PTC7__DSPI1_SOUT 0x1182
+ VF610_PAD_PTC8__DSPI1_SCK 0x1182
+ >;
+ };
+
+ pinctrl_esdhc0: esdhc0grp {
+ fsl,pins = <
+ VF610_PAD_PTC0__ESDHC0_CLK 0x31ef
+ VF610_PAD_PTC1__ESDHC0_CMD 0x31ef
+ VF610_PAD_PTC2__ESDHC0_DAT0 0x31ef
+ VF610_PAD_PTC3__ESDHC0_DAT1 0x31ef
+ VF610_PAD_PTC4__ESDHC0_DAT2 0x31ef
+ VF610_PAD_PTC5__ESDHC0_DAT3 0x31ef
+ VF610_PAD_PTD23__ESDHC0_DAT4 0x31ef
+ VF610_PAD_PTD22__ESDHC0_DAT5 0x31ef
+ VF610_PAD_PTD21__ESDHC0_DAT6 0x31ef
+ VF610_PAD_PTD20__ESDHC0_DAT7 0x31ef
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ VF610_PAD_PTA30__I2C3_SCL 0x37ff
+ VF610_PAD_PTA31__I2C3_SDA 0x37ff
+ >;
+ };
+
+ pinctrl_leds_debug: pinctrl-leds-debug {
+ fsl,pins = <
+ VF610_PAD_PTB26__GPIO_96 0x31c2
+ >;
+ };
+
+ pinctrl_uart1_rts: uart1grp-rts {
+ fsl,pins = <
+ VF610_PAD_PTB25__UART1_RTS 0x2062
+ >;
+ };
+
+ pinctrl_uart2_rts: uart2grp-rts {
+ fsl,pins = <
+ VF610_PAD_PTD2__UART2_RTS 0x2062
+ >;
+ };
+
+ pinctrl_mdio_mux: pinctrl-mdio-mux {
+ fsl,pins = <
+ VF610_PAD_PTE27__GPIO_132 0x31c2
+ VF610_PAD_PTE28__GPIO_133 0x31c2
+ VF610_PAD_PTE21__GPIO_126 0x31c2
+ VF610_PAD_PTE22__GPIO_127 0x31c2
+ >;
+ };
+};
diff --git a/arch/arm/dts/vf610-zii-spu3-rev-a.dts b/arch/arm/dts/vf610-zii-spu3-rev-a.dts
new file mode 100644
index 0000000..25ab26d
--- /dev/null
+++ b/arch/arm/dts/vf610-zii-spu3-rev-a.dts
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2015, 2016 Zodiac Inflight Innovations
+ *
+ * Based on an original 'vf610-twr.dts' which is Copyright 2015,
+ * Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file 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 file 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "vf610-zii-dev.dtsi"
+
+
+/ {
+ model = "ZII VF610 SPU3 Switch Management Board";
+ compatible = "zii,vf610spu3-a", "zii,vf610dev", "fsl,vf610";
+
+ aliases {
+ /delete-property/ serial2;
+ };
+
+ gpio-leds {
+ debug {
+ gpios = <&gpio2 18 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&dspi1 {
+ bus-num = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dspi1>;
+ status = "okay";
+
+ m25p128@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p128", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+
+ partition@0 {
+ label = "m25p128-0";
+ reg = <0x0 0x01000000>;
+ };
+ };
+};
+
+&esdhc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc0>;
+ bus-width = <8>;
+ status = "okay";
+};
+
+&fec0 {
+ status = "disabled";
+};
+
+&i2c0 {
+ /* Board Revision */
+ gpio6: pca9505@22 {
+ compatible = "nxp,pca9554";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+/delete-node/ &i2c1;
+/delete-node/ &i2c2;
+/delete-node/ &uart2;
+
+&iomuxc {
+ pinctrl_dspi1: dspi1grp {
+ fsl,pins = <
+ VF610_PAD_PTD5__DSPI1_CS0 0x1182
+ VF610_PAD_PTD4__DSPI1_CS1 0x1182
+ VF610_PAD_PTC6__DSPI1_SIN 0x1181
+ VF610_PAD_PTC7__DSPI1_SOUT 0x1182
+ VF610_PAD_PTC8__DSPI1_SCK 0x1182
+ >;
+ };
+
+ pinctrl_esdhc0: esdhc0grp {
+ fsl,pins = <
+ VF610_PAD_PTC0__ESDHC0_CLK 0x31ef
+ VF610_PAD_PTC1__ESDHC0_CMD 0x31ef
+ VF610_PAD_PTC2__ESDHC0_DAT0 0x31ef
+ VF610_PAD_PTC3__ESDHC0_DAT1 0x31ef
+ VF610_PAD_PTC4__ESDHC0_DAT2 0x31ef
+ VF610_PAD_PTC5__ESDHC0_DAT3 0x31ef
+ VF610_PAD_PTD23__ESDHC0_DAT4 0x31ef
+ VF610_PAD_PTD22__ESDHC0_DAT5 0x31ef
+ VF610_PAD_PTD21__ESDHC0_DAT6 0x31ef
+ VF610_PAD_PTD20__ESDHC0_DAT7 0x31ef
+ >;
+ };
+
+ pinctrl_leds_debug: pinctrl-leds-debug {
+ fsl,pins = <
+ VF610_PAD_PTD3__GPIO_82 0x31c2
+ >;
+ };
+};
diff --git a/arch/arm/include/asm/arm-smccc.h b/arch/arm/include/asm/arm-smccc.h
new file mode 100644
index 0000000..b5abfda
--- /dev/null
+++ b/arch/arm/include/asm/arm-smccc.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+#ifndef __LINUX_ARM_SMCCC_H
+#define __LINUX_ARM_SMCCC_H
+
+#include <linux/linkage.h>
+#include <linux/types.h>
+
+/*
+ * This file provides common defines for ARM SMC Calling Convention as
+ * specified in
+ * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+ */
+
+#define ARM_SMCCC_STD_CALL 0
+#define ARM_SMCCC_FAST_CALL 1
+#define ARM_SMCCC_TYPE_SHIFT 31
+
+#define ARM_SMCCC_SMC_32 0
+#define ARM_SMCCC_SMC_64 1
+#define ARM_SMCCC_CALL_CONV_SHIFT 30
+
+#define ARM_SMCCC_OWNER_MASK 0x3F
+#define ARM_SMCCC_OWNER_SHIFT 24
+
+#define ARM_SMCCC_FUNC_MASK 0xFFFF
+
+#define ARM_SMCCC_IS_FAST_CALL(smc_val) \
+ ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
+#define ARM_SMCCC_IS_64(smc_val) \
+ ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
+#define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK)
+#define ARM_SMCCC_OWNER_NUM(smc_val) \
+ (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
+
+#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
+ (((type) << ARM_SMCCC_TYPE_SHIFT) | \
+ ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
+ (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
+ ((func_num) & ARM_SMCCC_FUNC_MASK))
+
+#define ARM_SMCCC_OWNER_ARCH 0
+#define ARM_SMCCC_OWNER_CPU 1
+#define ARM_SMCCC_OWNER_SIP 2
+#define ARM_SMCCC_OWNER_OEM 3
+#define ARM_SMCCC_OWNER_STANDARD 4
+#define ARM_SMCCC_OWNER_TRUSTED_APP 48
+#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
+#define ARM_SMCCC_OWNER_TRUSTED_OS 50
+#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
+
+/**
+ * struct arm_smccc_res - Result from SMC/HVC call
+ * @a0-a3 result values from registers 0 to 3
+ */
+struct arm_smccc_res {
+ unsigned long a0;
+ unsigned long a1;
+ unsigned long a2;
+ unsigned long a3;
+};
+
+/**
+ * arm_smccc_smc() - make SMC calls
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ *
+ * This function is used to make SMC calls following SMC Calling Convention.
+ * The content of the supplied param are copied to registers 0 to 7 prior
+ * to the SMC instruction. The return values are updated with the content
+ * from register 0 to 3 on return from the SMC instruction.
+ */
+asmlinkage void arm_smccc_smc(unsigned long a0, unsigned long a1,
+ unsigned long a2, unsigned long a3, unsigned long a4,
+ unsigned long a5, unsigned long a6, unsigned long a7,
+ struct arm_smccc_res *res);
+
+/**
+ * arm_smccc_hvc() - make HVC calls
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ *
+ * This function is used to make HVC calls following SMC Calling
+ * Convention. The content of the supplied param are copied to registers 0
+ * to 7 prior to the HVC instruction. The return values are updated with
+ * the content from register 0 to 3 on return from the HVC instruction.
+ */
+asmlinkage void arm_smccc_hvc(unsigned long a0, unsigned long a1,
+ unsigned long a2, unsigned long a3, unsigned long a4,
+ unsigned long a5, unsigned long a6, unsigned long a7,
+ struct arm_smccc_res *res);
+
+#endif /*__LINUX_ARM_SMCCC_H*/
diff --git a/arch/arm/include/asm/armlinux.h b/arch/arm/include/asm/armlinux.h
index 07479fb..5c39200 100644
--- a/arch/arm/include/asm/armlinux.h
+++ b/arch/arm/include/asm/armlinux.h
@@ -3,6 +3,7 @@
#include <asm/memory.h>
#include <asm/setup.h>
+#include <asm/secure.h>
#if defined CONFIG_ARM_LINUX
void armlinux_set_bootparams(void *params);
@@ -38,6 +39,7 @@ static inline void armlinux_set_atag_appender(struct tag *(*func)(struct tag *))
struct image_data;
void start_linux(void *adr, int swap, unsigned long initrd_address,
- unsigned long initrd_size, void *oftree);
+ unsigned long initrd_size, void *oftree,
+ enum arm_security_state);
#endif /* __ARCH_ARMLINUX_H */
diff --git a/arch/arm/include/asm/gic.h b/arch/arm/include/asm/gic.h
new file mode 100644
index 0000000..bd3a80c
--- /dev/null
+++ b/arch/arm/include/asm/gic.h
@@ -0,0 +1,110 @@
+#ifndef __GIC_H__
+#define __GIC_H__
+
+/* Register offsets for the ARM generic interrupt controller (GIC) */
+
+#define GIC_DIST_OFFSET 0x1000
+#define GIC_CPU_OFFSET_A9 0x0100
+#define GIC_CPU_OFFSET_A15 0x2000
+
+/* Distributor Registers */
+#define GICD_CTLR 0x0000
+#define GICD_TYPER 0x0004
+#define GICD_IIDR 0x0008
+#define GICD_STATUSR 0x0010
+#define GICD_SETSPI_NSR 0x0040
+#define GICD_CLRSPI_NSR 0x0048
+#define GICD_SETSPI_SR 0x0050
+#define GICD_CLRSPI_SR 0x0058
+#define GICD_SEIR 0x0068
+#define GICD_IGROUPRn 0x0080
+#define GICD_ISENABLERn 0x0100
+#define GICD_ICENABLERn 0x0180
+#define GICD_ISPENDRn 0x0200
+#define GICD_ICPENDRn 0x0280
+#define GICD_ISACTIVERn 0x0300
+#define GICD_ICACTIVERn 0x0380
+#define GICD_IPRIORITYRn 0x0400
+#define GICD_ITARGETSRn 0x0800
+#define GICD_ICFGR 0x0c00
+#define GICD_IGROUPMODRn 0x0d00
+#define GICD_NSACRn 0x0e00
+#define GICD_SGIR 0x0f00
+#define GICD_CPENDSGIRn 0x0f10
+#define GICD_SPENDSGIRn 0x0f20
+#define GICD_IROUTERn 0x6000
+
+/* Cpu Interface Memory Mapped Registers */
+#define GICC_CTLR 0x0000
+#define GICC_PMR 0x0004
+#define GICC_BPR 0x0008
+#define GICC_IAR 0x000C
+#define GICC_EOIR 0x0010
+#define GICC_RPR 0x0014
+#define GICC_HPPIR 0x0018
+#define GICC_ABPR 0x001c
+#define GICC_AIAR 0x0020
+#define GICC_AEOIR 0x0024
+#define GICC_AHPPIR 0x0028
+#define GICC_APRn 0x00d0
+#define GICC_NSAPRn 0x00e0
+#define GICC_IIDR 0x00fc
+#define GICC_DIR 0x1000
+
+/* ReDistributor Registers for Control and Physical LPIs */
+#define GICR_CTLR 0x0000
+#define GICR_IIDR 0x0004
+#define GICR_TYPER 0x0008
+#define GICR_STATUSR 0x0010
+#define GICR_WAKER 0x0014
+#define GICR_SETLPIR 0x0040
+#define GICR_CLRLPIR 0x0048
+#define GICR_SEIR 0x0068
+#define GICR_PROPBASER 0x0070
+#define GICR_PENDBASER 0x0078
+#define GICR_INVLPIR 0x00a0
+#define GICR_INVALLR 0x00b0
+#define GICR_SYNCR 0x00c0
+#define GICR_MOVLPIR 0x0100
+#define GICR_MOVALLR 0x0110
+
+/* ReDistributor Registers for SGIs and PPIs */
+#define GICR_IGROUPRn 0x0080
+#define GICR_ISENABLERn 0x0100
+#define GICR_ICENABLERn 0x0180
+#define GICR_ISPENDRn 0x0200
+#define GICR_ICPENDRn 0x0280
+#define GICR_ISACTIVERn 0x0300
+#define GICR_ICACTIVERn 0x0380
+#define GICR_IPRIORITYRn 0x0400
+#define GICR_ICFGR0 0x0c00
+#define GICR_ICFGR1 0x0c04
+#define GICR_IGROUPMODRn 0x0d00
+#define GICR_NSACRn 0x0e00
+
+/* Cpu Interface System Registers */
+#define ICC_IAR0_EL1 S3_0_C12_C8_0
+#define ICC_IAR1_EL1 S3_0_C12_C12_0
+#define ICC_EOIR0_EL1 S3_0_C12_C8_1
+#define ICC_EOIR1_EL1 S3_0_C12_C12_1
+#define ICC_HPPIR0_EL1 S3_0_C12_C8_2
+#define ICC_HPPIR1_EL1 S3_0_C12_C12_2
+#define ICC_BPR0_EL1 S3_0_C12_C8_3
+#define ICC_BPR1_EL1 S3_0_C12_C12_3
+#define ICC_DIR_EL1 S3_0_C12_C11_1
+#define ICC_PMR_EL1 S3_0_C4_C6_0
+#define ICC_RPR_EL1 S3_0_C12_C11_3
+#define ICC_CTLR_EL1 S3_0_C12_C12_4
+#define ICC_CTLR_EL3 S3_6_C12_C12_4
+#define ICC_SRE_EL1 S3_0_C12_C12_5
+#define ICC_SRE_EL2 S3_4_C12_C9_5
+#define ICC_SRE_EL3 S3_6_C12_C12_5
+#define ICC_IGRPEN0_EL1 S3_0_C12_C12_6
+#define ICC_IGRPEN1_EL1 S3_0_C12_C12_7
+#define ICC_IGRPEN1_EL3 S3_6_C12_C12_7
+#define ICC_SEIEN_EL1 S3_0_C12_C13_0
+#define ICC_SGI0R_EL1 S3_0_C12_C11_7
+#define ICC_SGI1R_EL1 S3_0_C12_C11_5
+#define ICC_ASGI1R_EL1 S3_0_C12_C11_6
+
+#endif /* __GIC_H__ */
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
new file mode 100644
index 0000000..e0c4525
--- /dev/null
+++ b/arch/arm/include/asm/psci.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM_PSCI_H__
+#define __ARM_PSCI_H__
+
+#define ARM_PSCI_VER_1_0 (0x00010000)
+#define ARM_PSCI_VER_0_2 (0x00000002)
+
+/* PSCI 0.1 interface */
+#define ARM_PSCI_FN_BASE 0x95c1ba5e
+#define ARM_PSCI_FN(n) (ARM_PSCI_FN_BASE + (n))
+
+#define ARM_PSCI_FN_CPU_SUSPEND ARM_PSCI_FN(0)
+#define ARM_PSCI_FN_CPU_OFF ARM_PSCI_FN(1)
+#define ARM_PSCI_FN_CPU_ON ARM_PSCI_FN(2)
+#define ARM_PSCI_FN_MIGRATE ARM_PSCI_FN(3)
+
+#define ARM_PSCI_RET_SUCCESS 0
+#define ARM_PSCI_RET_NOT_SUPPORTED (-1)
+#define ARM_PSCI_RET_INVAL (-2)
+#define ARM_PSCI_RET_DENIED (-3)
+#define ARM_PSCI_RET_ALREADY_ON (-4)
+#define ARM_PSCI_RET_ON_PENDING (-5)
+#define ARM_PSCI_RET_INTERNAL_FAILURE (-6)
+#define ARM_PSCI_RET_NOT_PRESENT (-7)
+#define ARM_PSCI_RET_DISABLED (-8)
+#define ARM_PSCI_RET_INVALID_ADDRESS (-9)
+
+/* PSCI 0.2 interface */
+#define ARM_PSCI_0_2_FN_BASE 0x84000000
+#define ARM_PSCI_0_2_FN(n) (ARM_PSCI_0_2_FN_BASE + (n))
+
+#define ARM_PSCI_0_2_FN64_BASE 0xC4000000
+#define ARM_PSCI_0_2_FN64(n) (ARM_PSCI_0_2_FN64_BASE + (n))
+
+#define ARM_PSCI_0_2_FN_PSCI_VERSION ARM_PSCI_0_2_FN(0)
+#define ARM_PSCI_0_2_FN_CPU_SUSPEND ARM_PSCI_0_2_FN(1)
+#define ARM_PSCI_0_2_FN_CPU_OFF ARM_PSCI_0_2_FN(2)
+#define ARM_PSCI_0_2_FN_CPU_ON ARM_PSCI_0_2_FN(3)
+#define ARM_PSCI_0_2_FN_AFFINITY_INFO ARM_PSCI_0_2_FN(4)
+#define ARM_PSCI_0_2_FN_MIGRATE ARM_PSCI_0_2_FN(5)
+#define ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE ARM_PSCI_0_2_FN(6)
+#define ARM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU ARM_PSCI_0_2_FN(7)
+#define ARM_PSCI_0_2_FN_SYSTEM_OFF ARM_PSCI_0_2_FN(8)
+#define ARM_PSCI_0_2_FN_SYSTEM_RESET ARM_PSCI_0_2_FN(9)
+
+#define ARM_PSCI_0_2_FN64_CPU_SUSPEND ARM_PSCI_0_2_FN64(1)
+#define ARM_PSCI_0_2_FN64_CPU_ON ARM_PSCI_0_2_FN64(3)
+#define ARM_PSCI_0_2_FN64_AFFINITY_INFO ARM_PSCI_0_2_FN64(4)
+#define ARM_PSCI_0_2_FN64_MIGRATE ARM_PSCI_0_2_FN64(5)
+#define ARM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU ARM_PSCI_0_2_FN64(7)
+
+/* PSCI 1.0 interface */
+#define ARM_PSCI_1_0_FN_PSCI_FEATURES ARM_PSCI_0_2_FN(10)
+#define ARM_PSCI_1_0_FN_CPU_FREEZE ARM_PSCI_0_2_FN(11)
+#define ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND ARM_PSCI_0_2_FN(12)
+#define ARM_PSCI_1_0_FN_NODE_HW_STATE ARM_PSCI_0_2_FN(13)
+#define ARM_PSCI_1_0_FN_SYSTEM_SUSPEND ARM_PSCI_0_2_FN(14)
+#define ARM_PSCI_1_0_FN_SET_SUSPEND_MODE ARM_PSCI_0_2_FN(15)
+#define ARM_PSCI_1_0_FN_STAT_RESIDENCY ARM_PSCI_0_2_FN(16)
+#define ARM_PSCI_1_0_FN_STAT_COUNT ARM_PSCI_0_2_FN(17)
+
+#define ARM_PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND ARM_PSCI_0_2_FN64(12)
+#define ARM_PSCI_1_0_FN64_NODE_HW_STATE ARM_PSCI_0_2_FN64(13)
+#define ARM_PSCI_1_0_FN64_SYSTEM_SUSPEND ARM_PSCI_0_2_FN64(14)
+#define ARM_PSCI_1_0_FN64_STAT_RESIDENCY ARM_PSCI_0_2_FN64(16)
+#define ARM_PSCI_1_0_FN64_STAT_COUNT ARM_PSCI_0_2_FN64(17)
+
+/* PSCI affinity level state returned by AFFINITY_INFO */
+#define PSCI_AFFINITY_LEVEL_ON 0
+#define PSCI_AFFINITY_LEVEL_OFF 1
+#define PSCI_AFFINITY_LEVEL_ON_PENDING 2
+
+struct psci_ops {
+ int (*cpu_suspend)(u32 power_state, unsigned long entry, u32 context_id);
+ int (*cpu_off)(void);
+ int (*cpu_on)(u32 cpu_id);
+ int (*affinity_info)(u32 affinity, u32 lowest_affinity_level);
+ int (*migrate)(u32 cpu_id);
+ int (*migrate_info_type)(void);
+ int (*migrate_info_up_cpu)(void);
+ void (*system_off)(void);
+ void (*system_reset)(void);
+};
+
+#ifdef CONFIG_ARM_PSCI
+void psci_set_ops(struct psci_ops *ops);
+#else
+static inline void psci_set_ops(struct psci_ops *ops)
+{
+}
+#endif
+
+void psci_cpu_entry(void);
+
+#ifdef CONFIG_ARM_PSCI_DEBUG
+void psci_set_putc(void (*putcf)(void *ctx, int c), void *ctx);
+void psci_putc(char c);
+int psci_puts(const char *str);
+int psci_printf(const char *fmt, ...)
+ __attribute__ ((format(__printf__, 1, 2)));
+#else
+
+static inline void psci_set_putc(void (*putcf)(void *ctx, int c), void *ctx)
+{
+}
+
+static inline void psci_putc(char c)
+{
+}
+
+static inline int psci_puts(const char *str)
+{
+ return 0;
+}
+
+static inline int psci_printf(const char *fmt, ...)
+{
+ return 0;
+}
+#endif
+
+int psci_get_cpu_id(void);
+
+#endif /* __ARM_PSCI_H__ */
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 022d365..6520a0a 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -32,6 +32,7 @@
#define IRQ_MODE 0x00000012
#define SVC_MODE 0x00000013
#define ABT_MODE 0x00000017
+#define HYP_MODE 0x0000001a
#define UND_MODE 0x0000001b
#define SYSTEM_MODE 0x0000001f
#define MODE32_BIT 0x00000010
diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h
new file mode 100644
index 0000000..a4cb1f6
--- /dev/null
+++ b/arch/arm/include/asm/secure.h
@@ -0,0 +1,39 @@
+#ifndef __ASM_ARM_SECURE_H
+#define __ASM_ARM_SECURE_H
+
+#ifndef __ASSEMBLY__
+
+int armv7_secure_monitor_install(void);
+int __armv7_secure_monitor_install(void);
+void armv7_switch_to_hyp(void);
+
+extern unsigned char secure_monitor_init_vectors[];
+
+enum arm_security_state {
+ ARM_STATE_SECURE,
+ ARM_STATE_NONSECURE,
+ ARM_STATE_HYP,
+};
+
+#ifdef CONFIG_ARM_SECURE_MONITOR
+enum arm_security_state bootm_arm_security_state(void);
+const char *bootm_arm_security_state_name(enum arm_security_state state);
+#else
+static inline enum arm_security_state bootm_arm_security_state(void)
+{
+ return ARM_STATE_SECURE;
+}
+
+static inline const char *bootm_arm_security_state_name(
+ enum arm_security_state state)
+{
+ return "secure";
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#define ARM_SECURE_STACK_SHIFT 10
+#define ARM_SECURE_MAX_CPU 8
+
+#endif /* __ASM_ARM_SECURE_H */
diff --git a/arch/arm/include/asm/unwind.h b/arch/arm/include/asm/unwind.h
index 311ad3d..a6f3a91 100644
--- a/arch/arm/include/asm/unwind.h
+++ b/arch/arm/include/asm/unwind.h
@@ -48,4 +48,10 @@ extern void unwind_backtrace(struct pt_regs *regs);
#endif /* !__ASSEMBLY__ */
+#ifdef CONFIG_ARM_UNWIND
+#define UNWIND(code...) code
+#else
+#define UNWIND(code...)
+#endif
+
#endif /* __ASM_UNWIND_H */
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 9bd92f6..8068a53 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -18,6 +18,7 @@
#include <magicvar.h>
#include <binfmt.h>
#include <restart.h>
+#include <globalvar.h>
#include <asm/byteorder.h>
#include <asm/setup.h>
@@ -133,6 +134,7 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int
{
unsigned long kernel;
unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0;
+ enum arm_security_state state = bootm_arm_security_state();
int ret;
kernel = data->os_res->start + data->os_entry;
@@ -174,10 +176,20 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int
printf("...\n");
}
+ if (IS_ENABLED(CONFIG_ARM_SECURE_MONITOR)) {
+ if (file_detect_type((void *)data->os_res->start, 0x100) ==
+ filetype_arm_barebox)
+ state = ARM_STATE_SECURE;
+
+ printf("Starting kernel in %s mode\n",
+ bootm_arm_security_state_name(state));
+ }
+
if (data->dryrun)
return 0;
- start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree);
+ start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree,
+ state);
restart_machine();
diff --git a/arch/arm/lib/bootu.c b/arch/arm/lib/bootu.c
index 19009c8..d811da3 100644
--- a/arch/arm/lib/bootu.c
+++ b/arch/arm/lib/bootu.c
@@ -26,7 +26,7 @@ static int do_bootu(int argc, char *argv[])
oftree = of_get_fixed_tree(NULL);
#endif
- start_linux(kernel, 0, 0, 0, oftree);
+ start_linux(kernel, 0, 0, 0, oftree, ARM_STATE_SECURE);
return 1;
}
diff --git a/arch/arm/lib32/armlinux.c b/arch/arm/lib32/armlinux.c
index 6c7bd10..2520fe2 100644
--- a/arch/arm/lib32/armlinux.c
+++ b/arch/arm/lib32/armlinux.c
@@ -38,6 +38,7 @@
#include <asm/barebox-arm.h>
#include <asm/armlinux.h>
#include <asm/system.h>
+#include <asm/secure.h>
static struct tag *params;
static void *armlinux_bootparams = NULL;
@@ -258,11 +259,19 @@ static void setup_tags(unsigned long initrd_address,
}
void start_linux(void *adr, int swap, unsigned long initrd_address,
- unsigned long initrd_size, void *oftree)
+ unsigned long initrd_size, void *oftree,
+ enum arm_security_state state)
{
void (*kernel)(int zero, int arch, void *params) = adr;
void *params = NULL;
int architecture;
+ int ret;
+
+ if (IS_ENABLED(CONFIG_ARM_SECURE_MONITOR) && state > ARM_STATE_SECURE) {
+ ret = armv7_secure_monitor_install();
+ if (ret)
+ pr_err("Failed to install secure monitor\n");
+ }
if (oftree) {
pr_debug("booting kernel with devicetree\n");
@@ -274,6 +283,10 @@ void start_linux(void *adr, int swap, unsigned long initrd_address,
architecture = armlinux_get_architecture();
shutdown_barebox();
+
+ if (IS_ENABLED(CONFIG_ARM_SECURE_MONITOR) && state == ARM_STATE_HYP)
+ armv7_switch_to_hyp();
+
if (swap) {
u32 reg;
__asm__ __volatile__("mrc p15, 0, %0, c1, c0" : "=r" (reg));
diff --git a/arch/arm/lib32/barebox.lds.S b/arch/arm/lib32/barebox.lds.S
index 5fd39dc..b49c269 100644
--- a/arch/arm/lib32/barebox.lds.S
+++ b/arch/arm/lib32/barebox.lds.S
@@ -19,6 +19,7 @@
*/
#include <asm-generic/barebox.lds.h>
+#include <asm/secure.h>
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
@@ -123,6 +124,15 @@ SECTIONS
__bss_start = .;
.bss : { *(.bss*) }
__bss_stop = .;
+
+#ifdef CONFIG_ARM_SECURE_MONITOR
+ . = ALIGN(16);
+ __secure_stack_start = .;
+ . = . + (ARM_SECURE_MAX_CPU << ARM_SECURE_STACK_SHIFT);
+ __secure_stack_end = .;
+ __secure_end = .;
+#endif
+
_end = .;
_barebox_image_size = __bss_start - TEXT_BASE;
}
diff --git a/arch/arm/lib32/bootz.c b/arch/arm/lib32/bootz.c
index 5167c9d..c0ffd93 100644
--- a/arch/arm/lib32/bootz.c
+++ b/arch/arm/lib32/bootz.c
@@ -112,7 +112,7 @@ static int do_bootz(int argc, char *argv[])
oftree = of_get_fixed_tree(NULL);
#endif
- start_linux(zimage, swap, 0, 0, oftree);
+ start_linux(zimage, swap, 0, 0, oftree, ARM_STATE_SECURE);
return 0;
diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c
index 020e6d7..54ce6ca 100644
--- a/arch/arm/lib64/armlinux.c
+++ b/arch/arm/lib64/armlinux.c
@@ -40,7 +40,8 @@
#include <asm/system.h>
void start_linux(void *adr, int swap, unsigned long initrd_address,
- unsigned long initrd_size, void *oftree)
+ unsigned long initrd_size, void *oftree,
+ enum arm_security_state bootm_secure_state)
{
void (*kernel)(void *dtb) = adr;
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 9dbe31c..f83aedc 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -39,6 +39,7 @@ config ARCH_TEXT_BASE
default 0x4fc00000 if MACH_UDOO
default 0x4fc00000 if MACH_VARISCITE_MX6
default 0x4fc00000 if MACH_PHYTEC_SOM_IMX6
+ default 0x9fc00000 if MACH_WARP7
config ARCH_IMX_IMXIMAGE
bool
@@ -147,6 +148,10 @@ config ARCH_IMX6
select COMMON_CLK_OF_PROVIDER
select HW_HAS_PCI
+config ARCH_IMX6SL
+ bool
+ select ARCH_IMX6
+
config ARCH_IMX6SX
bool
select ARCH_IMX6
@@ -157,6 +162,12 @@ config ARCH_IMX6UL
bool
select ARCH_IMX6
+config ARCH_IMX7
+ bool
+ select CPU_V7
+ select OFTREE
+ select COMMON_CLK_OF_PROVIDER
+
config ARCH_VF610
bool
select ARCH_HAS_L2X0
@@ -166,6 +177,7 @@ config ARCH_VF610
select OFTREE
select COMMON_CLK
select COMMON_CLK_OF_PROVIDER
+ select IMX_OCOTP # Needed for clock adjustement
config IMX_MULTI_BOARDS
bool "Allow multiple boards to be selected"
@@ -346,10 +358,23 @@ config MACH_CM_FX6
bool "CM FX6"
select ARCH_IMX6
+config MACH_WARP7
+ bool "NXP i.MX7: element 14 WaRP7 Board"
+ select ARCH_IMX7
+
config MACH_VF610_TWR
bool "Freescale VF610 Tower Board"
select ARCH_VF610
+config MACH_ZII_RDU2
+ bool "ZII i.MX6Q(+) RDU2"
+ select ARCH_IMX6
+
+config MACH_ZII_VF610_DEV
+ bool "Zodiac VF610 Dev Family"
+ select ARCH_VF610
+ select CLKDEV_LOOKUP
+
endif
# ----------------------------------------------------------
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d0fe7ab..fc5305f 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
pbl-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o
lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
+obj-$(CONFIG_ARCH_IMX7) += imx7.o
obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o
obj-$(CONFIG_IMX_IIM) += iim.o
obj-$(CONFIG_IMX_OCOTP) += ocotp.o
diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c
index 4893060..72597f5 100644
--- a/arch/arm/mach-imx/boot.c
+++ b/arch/arm/mach-imx/boot.c
@@ -25,6 +25,7 @@
#include <mach/imx51-regs.h>
#include <mach/imx53-regs.h>
#include <mach/imx6-regs.h>
+#include <mach/imx7-regs.h>
/* [CTRL][TYPE] */
static const enum bootsource locations[4][4] = {
@@ -346,3 +347,72 @@ void imx6_boot_save_loc(void)
bootsource_set(src);
bootsource_set_instance(instance);
}
+
+#define IMX7_SRC_SBMR1 0x58
+#define IMX7_SRC_SBMR2 0x70
+
+void imx7_get_boot_source(enum bootsource *src, int *instance)
+{
+ void __iomem *src_base = IOMEM(MX7_SRC_BASE_ADDR);
+ uint32_t sbmr1 = readl(src_base + IMX7_SRC_SBMR1);
+ uint32_t sbmr2 = readl(src_base + IMX7_SRC_SBMR2);
+ int boot_mode;
+
+ /* BMOD[1:0] */
+ boot_mode = (sbmr2 >> 24) & 0x3;
+
+ switch (boot_mode) {
+ case 0: /* Fuses, fall through */
+ case 2: /* internal boot */
+ goto internal_boot;
+ case 1: /* Serial Downloader */
+ *src = BOOTSOURCE_SERIAL;
+ break;
+ case 3: /* reserved */
+ break;
+ };
+
+ return;
+
+internal_boot:
+
+ switch ((sbmr1 >> 12) & 0xf) {
+ case 1:
+ case 2:
+ *src = BOOTSOURCE_MMC;
+ *instance = (sbmr1 >> 10 & 0x3);
+ break;
+ case 3:
+ *src = BOOTSOURCE_NAND;
+ break;
+ case 4:
+ *src = BOOTSOURCE_SPI_NOR,
+ *instance = (sbmr1 >> 9 & 0x7);
+ break;
+ case 6:
+ *src = BOOTSOURCE_SPI; /* Really: qspi */
+ break;
+ case 5:
+ *src = BOOTSOURCE_NOR;
+ break;
+ default:
+ break;
+ }
+
+ /* BOOT_CFG1[7:0] */
+ if (sbmr1 & (1 << 7))
+ *src = BOOTSOURCE_NAND;
+
+ return;
+}
+
+void imx7_boot_save_loc(void)
+{
+ enum bootsource src = BOOTSOURCE_UNKNOWN;
+ int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
+
+ imx7_get_boot_source(&src, &instance);
+
+ bootsource_set(src);
+ bootsource_set_instance(instance);
+}
diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index 8d00bbb..8482abd 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -155,6 +155,9 @@ static __maybe_unused struct of_device_id imx_gpt_dt_ids[] = {
.compatible = "fsl,imx6ul-gpt",
.data = &regs_imx31,
}, {
+ .compatible = "fsl,imx7d-gpt",
+ .data = &regs_imx31,
+ }, {
/* sentinel */
}
};
diff --git a/arch/arm/mach-imx/cpu_init.c b/arch/arm/mach-imx/cpu_init.c
index 6971d89..2b388ca 100644
--- a/arch/arm/mach-imx/cpu_init.c
+++ b/arch/arm/mach-imx/cpu_init.c
@@ -34,6 +34,11 @@ void imx6_cpu_lowlevel_init(void)
enable_arm_errata_845369_war();
}
+void imx7_cpu_lowlevel_init(void)
+{
+ arm_cpu_lowlevel_init();
+}
+
void vf610_cpu_lowlevel_init(void)
{
arm_cpu_lowlevel_init();
diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index ffe708f..1eebc77 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -432,6 +432,9 @@ static struct platform_device_id imx_esdctl_ids[] = {
static __maybe_unused struct of_device_id imx_esdctl_dt_ids[] = {
{
+ .compatible = "fsl,imx6sl-mmdc",
+ .data = &imx6ul_data
+ }, {
.compatible = "fsl,imx6ul-mmdc",
.data = &imx6ul_data
}, {
diff --git a/arch/arm/mach-imx/imx.c b/arch/arm/mach-imx/imx.c
index 952db00..1990739 100644
--- a/arch/arm/mach-imx/imx.c
+++ b/arch/arm/mach-imx/imx.c
@@ -61,10 +61,16 @@ static int imx_soc_from_dt(void)
return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx6sx"))
return IMX_CPU_IMX6;
+ if (of_machine_is_compatible("fsl,imx6sl"))
+ return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx6qp"))
return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx6ul"))
return IMX_CPU_IMX6;
+ if (of_machine_is_compatible("fsl,imx7s"))
+ return IMX_CPU_IMX7;
+ if (of_machine_is_compatible("fsl,imx7d"))
+ return IMX_CPU_IMX7;
if (of_machine_is_compatible("fsl,vf610"))
return IMX_CPU_VF610;
@@ -103,6 +109,8 @@ static int imx_init(void)
ret = imx53_init();
else if (cpu_is_mx6())
ret = imx6_init();
+ else if (cpu_is_mx7())
+ ret = imx7_init();
else if (cpu_is_vf610())
ret = 0;
else
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index b2979b0..44a8dbe 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -151,6 +151,9 @@ int imx6_init(void)
case IMX6_CPUTYPE_IMX6S:
cputypestr = "i.MX6 Solo";
break;
+ case IMX6_CPUTYPE_IMX6SL:
+ cputypestr = "i.MX6 SoloLite";
+ break;
case IMX6_CPUTYPE_IMX6SX:
cputypestr = "i.MX6 SoloX";
break;
diff --git a/arch/arm/mach-imx/imx7.c b/arch/arm/mach-imx/imx7.c
new file mode 100644
index 0000000..4eef99c
--- /dev/null
+++ b/arch/arm/mach-imx/imx7.c
@@ -0,0 +1,202 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <init.h>
+#include <common.h>
+#include <io.h>
+#include <linux/sizes.h>
+#include <asm/psci.h>
+#include <mach/imx7.h>
+#include <mach/generic.h>
+#include <mach/revision.h>
+#include <mach/imx7-regs.h>
+
+void imx7_init_lowlevel(void)
+{
+ void __iomem *aips1 = IOMEM(MX7_AIPS1_CONFIG_BASE_ADDR);
+ void __iomem *aips2 = IOMEM(MX7_AIPS2_CONFIG_BASE_ADDR);
+
+ /*
+ * Set all MPROTx to be non-bufferable, trusted for R/W,
+ * not forced to user-mode.
+ */
+ writel(0x77777777, aips1);
+ writel(0x77777777, aips1 + 0x4);
+ writel(0, aips1 + 0x40);
+ writel(0, aips1 + 0x44);
+ writel(0, aips1 + 0x48);
+ writel(0, aips1 + 0x4c);
+ writel(0, aips1 + 0x50);
+
+ writel(0x77777777, aips2);
+ writel(0x77777777, aips2 + 0x4);
+ writel(0, aips2 + 0x40);
+ writel(0, aips2 + 0x44);
+ writel(0, aips2 + 0x48);
+ writel(0, aips2 + 0x4c);
+ writel(0, aips2 + 0x50);
+}
+
+#define SC_CNTCR 0x0
+#define SC_CNTSR 0x4
+#define SC_CNTCV1 0x8
+#define SC_CNTCV2 0xc
+#define SC_CNTFID0 0x20
+#define SC_CNTFID1 0x24
+#define SC_CNTFID2 0x28
+#define SC_counterid 0xfcc
+
+#define SC_CNTCR_ENABLE (1 << 0)
+#define SC_CNTCR_HDBG (1 << 1)
+#define SC_CNTCR_FREQ0 (1 << 8)
+#define SC_CNTCR_FREQ1 (1 << 9)
+
+static int imx7_timer_init(void)
+{
+ void __iomem *sctr = IOMEM(MX7_SYSCNT_CTRL_BASE_ADDR);
+ unsigned long val, freq;
+
+ freq = 8000000;
+ asm("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
+
+ writel(freq, sctr + SC_CNTFID0);
+
+ /* Enable system counter */
+ val = readl(sctr + SC_CNTCR);
+ val &= ~(SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1);
+ val |= SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG;
+ writel(val, sctr + SC_CNTCR);
+
+ return 0;
+}
+
+#define CSU_NUM_REGS 64
+#define CSU_INIT_SEC_LEVEL0 0x00FF00FF
+
+static void imx7_init_csu(void)
+{
+ void __iomem *csu = IOMEM(MX7_CSU_BASE_ADDR);
+ int i = 0;
+
+ for (i = 0; i < CSU_NUM_REGS; i++)
+ writel(CSU_INIT_SEC_LEVEL0, csu + i * 4);
+}
+
+#define GPC_CPU_PGC_SW_PDN_REQ 0xfc
+#define GPC_CPU_PGC_SW_PUP_REQ 0xf0
+#define GPC_PGC_C1 0x840
+#define GPC_PGC(n) (0x800 + (n) * 0x40)
+
+#define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2
+
+#define PGC_CTRL 0x0
+
+/* below is for i.MX7D */
+#define SRC_GPR1_MX7D 0x074
+#define SRC_A7RCR1 0x008
+
+static void imx_gpcv2_set_core_power(int core, bool pdn)
+{
+ void __iomem *gpc = IOMEM(MX7_GPC_BASE_ADDR);
+ void __iomem *pgc = gpc + GPC_PGC(core);
+
+ u32 reg = pdn ? GPC_CPU_PGC_SW_PUP_REQ : GPC_CPU_PGC_SW_PDN_REQ;
+ u32 val;
+
+ writel(1, pgc + PGC_CTRL);
+
+ val = readl(gpc + reg);
+ val |= 1 << core;
+ writel(val, gpc + reg);
+
+ while (readl(gpc + reg) & (1 << core));
+
+ writel(0, pgc + PGC_CTRL);
+}
+
+static int imx7_cpu_on(u32 cpu_id)
+{
+ void __iomem *src = IOMEM(MX7_SRC_BASE_ADDR);
+ u32 val;
+
+ writel(psci_cpu_entry, src + cpu_id * 8 + SRC_GPR1_MX7D);
+ imx_gpcv2_set_core_power(cpu_id, true);
+
+ val = readl(src + SRC_A7RCR1);
+ val |= 1 << cpu_id;
+ writel(val, src + SRC_A7RCR1);
+
+ return 0;
+}
+
+static int imx7_cpu_off(void)
+{
+ void __iomem *src = IOMEM(MX7_SRC_BASE_ADDR);
+ u32 val;
+ int cpu_id = psci_get_cpu_id();
+
+ val = readl(src + SRC_A7RCR1);
+ val &= ~(1 << cpu_id);
+ writel(val, src + SRC_A7RCR1);
+
+ /*
+ * FIXME: This reads nice and symmetrically to cpu_on above,
+ * but of course this will never be reached as we have just
+ * put the CPU we are currently running on into reset.
+ */
+
+ imx_gpcv2_set_core_power(cpu_id, false);
+
+ while (1);
+
+ return 0;
+}
+
+static struct psci_ops imx7_psci_ops = {
+ .cpu_on = imx7_cpu_on,
+ .cpu_off = imx7_cpu_off,
+};
+
+int imx7_init(void)
+{
+ const char *cputypestr;
+ u32 imx7_silicon_revision;
+
+ imx7_init_lowlevel();
+
+ imx7_init_csu();
+
+ imx7_timer_init();
+
+ imx7_boot_save_loc();
+
+ imx7_silicon_revision = imx7_cpu_revision();
+
+ psci_set_ops(&imx7_psci_ops);
+
+ switch (imx7_cpu_type()) {
+ case IMX7_CPUTYPE_IMX7D:
+ cputypestr = "i.MX7d";
+ break;
+ case IMX7_CPUTYPE_IMX7S:
+ cputypestr = "i.MX7s";
+ break;
+ default:
+ cputypestr = "unknown i.MX7";
+ break;
+ }
+
+ imx_set_silicon_revision(cputypestr, imx7_silicon_revision);
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index a132f3c..39d710f 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -14,6 +14,7 @@
#include <mach/imx51-regs.h>
#include <mach/imx53-regs.h>
#include <mach/imx6-regs.h>
+#include <mach/imx7-regs.h>
#include <mach/vf610-regs.h>
#include <serial/imx-uart.h>
@@ -44,6 +45,8 @@
#define IMX_DEBUG_SOC MX53
#elif defined CONFIG_DEBUG_IMX6Q_UART
#define IMX_DEBUG_SOC MX6
+#elif defined CONFIG_DEBUG_IMX7D_UART
+#define IMX_DEBUG_SOC MX7
#elif defined CONFIG_DEBUG_VF610_UART
#define IMX_DEBUG_SOC VF610
#else
diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index 3419450..73be9ce 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -14,12 +14,14 @@ void imx27_boot_save_loc(void);
void imx51_boot_save_loc(void);
void imx53_boot_save_loc(void);
void imx6_boot_save_loc(void);
+void imx7_boot_save_loc(void);
void imx25_get_boot_source(enum bootsource *src, int *instance);
void imx35_get_boot_source(enum bootsource *src, int *instance);
void imx51_get_boot_source(enum bootsource *src, int *instance);
void imx53_get_boot_source(enum bootsource *src, int *instance);
void imx6_get_boot_source(enum bootsource *src, int *instance);
+void imx7_get_boot_source(enum bootsource *src, int *instance);
int imx1_init(void);
int imx21_init(void);
@@ -31,6 +33,7 @@ int imx50_init(void);
int imx51_init(void);
int imx53_init(void);
int imx6_init(void);
+int imx7_init(void);
int imx1_devices_init(void);
int imx21_devices_init(void);
@@ -45,6 +48,7 @@ int imx6_devices_init(void);
void imx5_cpu_lowlevel_init(void);
void imx6_cpu_lowlevel_init(void);
+void imx7_cpu_lowlevel_init(void);
void vf610_cpu_lowlevel_init(void);
/* There's a off-by-one betweem the gpio bank number and the gpiochip */
@@ -174,6 +178,18 @@ extern unsigned int __imx_cpu_type;
# define cpu_is_mx6() (0)
#endif
+#ifdef CONFIG_ARCH_IMX7
+# ifdef imx_cpu_type
+# undef imx_cpu_type
+# define imx_cpu_type __imx_cpu_type
+# else
+# define imx_cpu_type IMX_CPU_IMX7
+# endif
+# define cpu_is_mx7() (imx_cpu_type == IMX_CPU_IMX7)
+#else
+# define cpu_is_mx7() (0)
+#endif
+
#ifdef CONFIG_ARCH_VF610
# ifdef imx_cpu_type
# undef imx_cpu_type
diff --git a/arch/arm/mach-imx/include/mach/imx6-fusemap.h b/arch/arm/mach-imx/include/mach/imx6-fusemap.h
index 5fdd904..e14044e 100644
--- a/arch/arm/mach-imx/include/mach/imx6-fusemap.h
+++ b/arch/arm/mach-imx/include/mach/imx6-fusemap.h
@@ -1,62 +1,22 @@
#ifndef __MACH_IMX_IMX6_OCOTP_H
#define __MACH_IMX_IMX6_OCOTP_H
-#include <mach/ocotp.h>
+#include <mach/ocotp-fusemap.h>
-#define IMX6_OCOTP_TESTER_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(0) | OCOTP_WIDTH(2))
-#define IMX6_OCOTP_BOOT_CFG_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(2) | OCOTP_WIDTH(2))
-#define IMX6_OCOTP_MEM_TRIM_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(4) | OCOTP_WIDTH(2))
-#define IMX6_OCOTP_SJC_RESP_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(6) | OCOTP_WIDTH(2))
-#define IMX6_OCOTP_MAC_ADDR_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(8) | OCOTP_WIDTH(2))
-#define IMX6_OCOTP_GP1_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(10) | OCOTP_WIDTH(2))
-#define IMX6_OCOTP_GP2_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(12) | OCOTP_WIDTH(2))
-#define IMX6_OCOTP_SRK_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(14) | OCOTP_WIDTH(1))
-#define IMX6_OCOTP_ANALOG_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(18) | OCOTP_WIDTH(2))
-#define IMX6_OCOTP_MISC_CONF_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(22) | OCOTP_WIDTH(1))
-
-/* 0 <= n <= 1 */
-#define IMX6_OCOTP_UNIQUE_ID(n) (OCOTP_WORD(0x410 + 0x10 * (n)) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define IMX6_OCOTP_SI_REV (OCOTP_WORD(0x430) | OCOTP_BIT(16) | OCOTP_WIDTH(4))
-#define IMX6_OCOTP_NUM_CORES (OCOTP_WORD(0x430) | OCOTP_BIT(20) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_SATA_RST_SRC (OCOTP_WORD(0x430) | OCOTP_BIT(24) | OCOTP_WIDTH(1))
-#define IMX6_OCOTP_MLB_DISABLE (OCOTP_WORD(0x430) | OCOTP_BIT(26) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_VPU_DISABLE (OCOTP_WORD(0x440) | OCOTP_BIT(15) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_SPEED_GRADING (OCOTP_WORD(0x440) | OCOTP_BIT(16) | OCOTP_WIDTH(2))
-#define IMX6_OCOTP_BOOT_CFG1 (OCOTP_WORD(0x450) | OCOTP_BIT(0) | OCOTP_WIDTH(8))
-#define IMX6_OCOTP_BOOT_CFG2 (OCOTP_WORD(0x450) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
-#define IMX6_OCOTP_BOOT_CFG3 (OCOTP_WORD(0x450) | OCOTP_BIT(16) | OCOTP_WIDTH(8))
-#define IMX6_OCOTP_BOOT_CFG4 (OCOTP_WORD(0x450) | OCOTP_BIT(24) | OCOTP_WIDTH(8))
-#define IMX6_OCOTP_SEC_CONFIG (OCOTP_WORD(0x460) | OCOTP_BIT(1) | OCOTP_WIDTH(1))
-#define IMX6_OCOTP_DIR_BT_DIS (OCOTP_WORD(0x460) | OCOTP_BIT(3) | OCOTP_WIDTH(1))
-#define IMX6_OCOTP_BT_FUSE_SEL (OCOTP_WORD(0x460) | OCOTP_BIT(4) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_DDR3_CONFIG (OCOTP_WORD(0x460) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
#define IMX6_OCOTP_HDCP (OCOTP_WORD(0x460) | OCOTP_BIT(16) | OCOTP_WIDTH(1))
-#define IMX6_OCOTP_SJC_DISABLE (OCOTP_WORD(0x460) | OCOTP_BIT(20) | OCOTP_WIDTH(1))
-#define IMX6_OCOTP_WDOG_ENABLE (OCOTP_WORD(0x460) | OCOTP_BIT(21) | OCOTP_WIDTH(1))
-#define IMX6_OCOTP_JTAG_SMODE (OCOTP_WORD(0x460) | OCOTP_BIT(22) | OCOTP_WIDTH(2))
-#define IMX6_OCOTP_KTE (OCOTP_WORD(0x460) | OCOTP_BIT(26) | OCOTP_WIDTH(1))
-#define IMX6_OCOTP_JTAG_HEO (OCOTP_WORD(0x460) | OCOTP_BIT(27) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_TZASC_ENABLE (OCOTP_WORD(0x460) | OCOTP_BIT(28) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_SDMMC_HYS_EN (OCOTP_WORD(0x460) | OCOTP_BIT(29) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_eMMC_RESET_EN (OCOTP_WORD(0x460) | OCOTP_BIT(30) | OCOTP_WIDTH(1))
-#define IMX6_OCOTP_NAND_READ_CMD_CODE1 (OCOTP_WORD(0x470) | OCOTP_BIT(0) | OCOTP_WIDTH(8))
-#define IMX6_OCOTP_NAND_READ_CMD_CODE2 (OCOTP_WORD(0x470) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
#define IMX6_OCOTP_BT_LPB_POLARITY (OCOTP_WORD(0x470) | OCOTP_BIT(20) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_LPB_BOOT (OCOTP_WORD(0x470) | OCOTP_BIT(21) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_MMC_DLL_DLY (OCOTP_WORD(0x470) | OCOTP_BIT(24) | OCOTP_WIDTH(7))
#define IMX6_OCOTP_TEMPERATURE_GRADE (OCOTP_WORD(0x480) | OCOTP_BIT(6) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_POWER_GATE_CORES (OCOTP_WORD(0x4d0) | OCOTP_BIT(31) | OCOTP_WIDTH(1))
-#define IMX6_OCOTP_USB_VID (OCOTP_WORD(0x4f0) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
-#define IMX6_OCOTP_USB_PID (OCOTP_WORD(0x4f0) | OCOTP_BIT(16) | OCOTP_WIDTH(16))
-/* 0 <= n <= 7 */
-#define IMX6_OCOTP_SRK_HASH(n) (OCOTP_WORD(0x580 + 0x10 * (n)) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
-#define IMX6_OCOTP_SJC_RESP_31_0 (OCOTP_WORD(0x600) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
-#define IMX6_OCOTP_SJC_RESP_55_32 (OCOTP_WORD(0x610) | OCOTP_BIT(0) | OCOTP_WIDTH(24))
-#define IMX6_OCOTP_MAC_ADDR_31_0 (OCOTP_WORD(0x620) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
-#define IMX6_OCOTP_MAC_ADDR_47_32 (OCOTP_WORD(0x630) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
-#define IMX6_OCOTP_GP1 (OCOTP_WORD(0x660) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
-#define IMX6_OCOTP_GP2 (OCOTP_WORD(0x670) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
-#define IMX6_OCOTP_PAD_SETTINGS (OCOTP_WORD(0x6d0) | OCOTP_BIT(0) | OCOTP_WIDTH(6))
#define IMX6DQ_OCOTP_TEST_PORT_DISABLE (OCOTP_WORD(0x6e0) | OCOTP_BIT(1) | OCOTP_WIDTH(1))
#define IMX6SDL_OCOTP_FIELD_RETURN (OCOTP_WORD(0x6e0) | OCOTP_BIT(0) | OCOTP_WIDTH(1))
diff --git a/arch/arm/mach-imx/include/mach/imx6.h b/arch/arm/mach-imx/include/mach/imx6.h
index 8c169f1..327676b 100644
--- a/arch/arm/mach-imx/include/mach/imx6.h
+++ b/arch/arm/mach-imx/include/mach/imx6.h
@@ -9,7 +9,9 @@
void imx6_init_lowlevel(void);
#define IMX6_ANATOP_SI_REV 0x260
+#define IMX6SL_ANATOP_SI_REV 0x280
+#define IMX6_CPUTYPE_IMX6SL 0x160
#define IMX6_CPUTYPE_IMX6S 0x161
#define IMX6_CPUTYPE_IMX6DL 0x261
#define IMX6_CPUTYPE_IMX6SX 0x462
@@ -36,6 +38,16 @@ static inline int __imx6_cpu_type(void)
val = readl(MX6_ANATOP_BASE_ADDR + IMX6_ANATOP_SI_REV);
val = (val >> 16) & 0xff;
+ /* non-MX6-standard SI_REV reg offset for MX6SL */
+ if (IS_ENABLED(CONFIG_ARCH_IMX6SL) &&
+ val < (IMX6_CPUTYPE_IMX6S & 0xff)) {
+ uint32_t tmp;
+ tmp = readl(MX6_ANATOP_BASE_ADDR + IMX6SL_ANATOP_SI_REV);
+ tmp = (tmp >> 16) & 0xff;
+ if ((IMX6_CPUTYPE_IMX6SL & 0xff) == tmp)
+ /* intentionally skip scu_get_core_count() for MX6SL */
+ return IMX6_CPUTYPE_IMX6SL;
+ }
val |= scu_get_core_count() << 8;
@@ -50,12 +62,37 @@ static inline int imx6_cpu_type(void)
return __imx6_cpu_type();
}
+#define DEFINE_MX6_CPU_TYPE(str, type) \
+ static inline int cpu_mx6_is_##str(void) \
+ { \
+ return __imx6_cpu_type() == type; \
+ } \
+ \
+ static inline int cpu_is_##str(void) \
+ { \
+ if (!cpu_is_mx6()) \
+ return 0; \
+ return cpu_mx6_is_##str(); \
+ }
+
+DEFINE_MX6_CPU_TYPE(mx6s, IMX6_CPUTYPE_IMX6S);
+DEFINE_MX6_CPU_TYPE(mx6dl, IMX6_CPUTYPE_IMX6DL);
+DEFINE_MX6_CPU_TYPE(mx6q, IMX6_CPUTYPE_IMX6Q);
+DEFINE_MX6_CPU_TYPE(mx6d, IMX6_CPUTYPE_IMX6D);
+DEFINE_MX6_CPU_TYPE(mx6sx, IMX6_CPUTYPE_IMX6SX);
+DEFINE_MX6_CPU_TYPE(mx6sl, IMX6_CPUTYPE_IMX6SL);
+DEFINE_MX6_CPU_TYPE(mx6ul, IMX6_CPUTYPE_IMX6UL);
+
static inline int __imx6_cpu_revision(void)
{
uint32_t rev;
+ uint32_t si_rev_offset = IMX6_ANATOP_SI_REV;
- rev = readl(MX6_ANATOP_BASE_ADDR + IMX6_ANATOP_SI_REV);
+ if (IS_ENABLED(CONFIG_ARCH_IMX6SL) && cpu_mx6_is_mx6sl())
+ si_rev_offset = IMX6SL_ANATOP_SI_REV;
+
+ rev = readl(MX6_ANATOP_BASE_ADDR + si_rev_offset);
switch (rev & 0xfff) {
case 0x00:
@@ -85,24 +122,4 @@ static inline int imx6_cpu_revision(void)
return __imx6_cpu_revision();
}
-#define DEFINE_MX6_CPU_TYPE(str, type) \
- static inline int cpu_mx6_is_##str(void) \
- { \
- return __imx6_cpu_type() == type; \
- } \
- \
- static inline int cpu_is_##str(void) \
- { \
- if (!cpu_is_mx6()) \
- return 0; \
- return cpu_mx6_is_##str(); \
- }
-
-DEFINE_MX6_CPU_TYPE(mx6s, IMX6_CPUTYPE_IMX6S);
-DEFINE_MX6_CPU_TYPE(mx6dl, IMX6_CPUTYPE_IMX6DL);
-DEFINE_MX6_CPU_TYPE(mx6q, IMX6_CPUTYPE_IMX6Q);
-DEFINE_MX6_CPU_TYPE(mx6d, IMX6_CPUTYPE_IMX6D);
-DEFINE_MX6_CPU_TYPE(mx6sx, IMX6_CPUTYPE_IMX6SX);
-DEFINE_MX6_CPU_TYPE(mx6ul, IMX6_CPUTYPE_IMX6UL);
-
#endif /* __MACH_IMX6_H */
diff --git a/arch/arm/mach-imx/include/mach/imx7-regs.h b/arch/arm/mach-imx/include/mach/imx7-regs.h
new file mode 100644
index 0000000..8774c32
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/imx7-regs.h
@@ -0,0 +1,119 @@
+#ifndef __MACH_IMX7_REGS_H
+#define __MACH_IMX7_REGS_H
+
+/* Defines for Blocks connected via AIPS */
+#define MX7_AIPS1_BASE_ADDR 0x30000000
+#define MX7_AIPS2_BASE_ADDR 0x30400000
+#define MX7_AIPS3_BASE_ADDR 0x30800000
+
+/* ATZ#1- On Platform */
+#define MX7_DAP_BASE_ADDR (MX7_AIPS1_BASE_ADDR)
+#define MX7_AIPS1_CONFIG_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x1F0000)
+
+/* ATZ#1- Off Platform */
+#define MX7_GPIO1_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x200000)
+#define MX7_GPIO2_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x210000)
+#define MX7_GPIO3_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x220000)
+#define MX7_GPIO4_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x230000)
+#define MX7_GPIO5_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x240000)
+#define MX7_GPIO6_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x250000)
+#define MX7_GPIO7_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x260000)
+#define MX7_IOMUXC_LPSR_GPR_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x270000)
+#define MX7_WDOG1_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x280000)
+#define MX7_WDOG2_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x290000)
+#define MX7_WDOG3_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2A0000)
+#define MX7_WDOG4_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2B0000)
+#define MX7_IOMUXC_LPSR_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2C0000)
+#define MX7_GPT1_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2D0000)
+#define MX7_GPT2_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2E0000)
+#define MX7_GPT3_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2F0000)
+#define MX7_GPT4_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x300000)
+#define MX7_ROMCP_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x310000)
+#define MX7_KPP_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x320000)
+#define MX7_IOMUXC_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x330000)
+#define MX7_IOMUXC_GPR_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x340000)
+#define MX7_OCOTP_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x350000)
+#define MX7_ANATOP_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x360000)
+#define MX7_SNVS_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x370000)
+#define MX7_CCM_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x380000)
+#define MX7_SRC_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x390000)
+#define MX7_GPC_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x3A0000)
+#define MX7_SEMAPHORE1_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x3B0000)
+#define MX7_SEMAPHORE2_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x3C0000)
+#define MX7_RDC_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x3D0000)
+#define MX7_CSU_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x3E0000)
+
+/* ATZ#2- On Platform */
+#define MX7_AIPS2_CONFIG_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x1F0000)
+
+/* ATZ#2- Off Platform */
+#define MX7_ADC1_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x230000)
+#define MX7_ADC2_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x230000)
+#define MX7_ECSPI4_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x230000)
+#define MX7_FTM1_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x240000)
+#define MX7_FTM2_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x250000)
+#define MX7_PWM1_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x260000)
+#define MX7_PWM2_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x270000)
+#define MX7_PWM3_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x280000)
+#define MX7_PWM4_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x290000)
+#define MX7_SYSCNT_RD_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x2A0000)
+#define MX7_SYSCNT_CMP_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x2B0000)
+#define MX7_SYSCNT_CTRL_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x2C0000)
+#define MX7_PCIE_PHY_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x2D0000)
+#define MX7_EPDC_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x2F0000)
+#define MX7_PXP_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x300000)
+#define MX7_CSI_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x310000)
+#define MX7_LCDIF_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x330000)
+#define MX7_MIPI_CSI_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x350000)
+#define MX7_MIPI_DSI_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x360000)
+#define MX7_TZASC_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x380000)
+#define MX7_DDRPHY_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x390000)
+#define MX7_DDRC_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x3A0000)
+#define MX7_IP2APB_PERFMON1_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x3C0000)
+#define MX7_IP2APB_PERFMON2_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x3D0000)
+#define MX7_AXI_DEBUG_MON_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x3E0000)
+
+/* ATZ#3- On Platform */
+#define MX7_ECSPI1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x20000)
+#define MX7_ECSPI2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x30000)
+#define MX7_ECSPI3_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x40000)
+#define MX7_UART1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x60000)
+#define MX7_UART2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x70000)
+#define MX7_UART3_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x80000)
+#define MX7_SAI1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0xA0000)
+#define MX7_SAI2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0xB0000)
+#define MX7_SAI3_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0xC0000)
+#define MX7_SPBA_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x90000)
+#define MX7_CAAM_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x100000)
+#define MX7_AIPS3_CONFIG_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x1F0000)
+
+/* ATZ#3- Off Platform */
+#define MX7_CAN1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x200000)
+#define MX7_CAN2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x210000)
+#define MX7_I2C1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x220000)
+#define MX7_I2C2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x230000)
+#define MX7_I2C3_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x240000)
+#define MX7_I2C4_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x250000)
+#define MX7_UART4_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x260000)
+#define MX7_UART5_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x270000)
+#define MX7_UART6_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x280000)
+#define MX7_UART7_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x290000)
+#define MX7_MU_A_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x2A0000)
+#define MX7_MU_B_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x2B0000)
+#define MX7_SEM_HS_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x2C0000)
+#define MX7_USBOH2_PL301_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x2D0000)
+#define MX7_OTG1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x310000)
+#define MX7_OTG2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x320000)
+#define MX7_USBOH3_USB_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x330000)
+#define MX7_USDHC1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x340000)
+#define MX7_USDHC2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x350000)
+#define MX7_USDHC3_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x360000)
+#define MX7_SIM1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x390000)
+#define MX7_SIM2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3A0000)
+#define MX7_QSPI_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3B0000)
+#define MX7_WEIM_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3C0000)
+#define MX7_SDMA_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3D0000)
+#define MX7_ENET1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3E0000)
+#define MX7_ENET2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3F0000)
+
+#endif /* __MACH_IMX7_REGS_H */
diff --git a/arch/arm/mach-imx/include/mach/imx7.h b/arch/arm/mach-imx/include/mach/imx7.h
new file mode 100644
index 0000000..8518935
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/imx7.h
@@ -0,0 +1,59 @@
+#ifndef __MACH_IMX7_H
+#define __MACH_IMX7_H
+
+#include <io.h>
+#include <mach/generic.h>
+#include <mach/imx7-regs.h>
+#include <mach/revision.h>
+
+void imx7_init_lowlevel(void);
+
+#define ANADIG_DIGPROG_IMX7 0x800
+
+#define IMX7_CPUTYPE_IMX7S 0x71
+#define IMX7_CPUTYPE_IMX7D 0x72
+
+static inline int __imx7_cpu_type(void)
+{
+ void __iomem *ocotp = IOMEM(MX7_OCOTP_BASE_ADDR);
+
+ if (readl(ocotp + 0x450) & 1)
+ return IMX7_CPUTYPE_IMX7S;
+ else
+ return IMX7_CPUTYPE_IMX7D;
+}
+
+static inline int imx7_cpu_type(void)
+{
+ if (!cpu_is_mx7())
+ return 0;
+
+ return __imx7_cpu_type();
+}
+
+static inline int imx7_cpu_revision(void)
+{
+ if (!cpu_is_mx7())
+ return IMX_CHIP_REV_UNKNOWN;
+
+ /* register value has the format of the IMX_CHIP_REV_* macros */
+ return readl(MX7_ANATOP_BASE_ADDR + ANADIG_DIGPROG_IMX7) & 0xff;
+}
+
+#define DEFINE_MX7_CPU_TYPE(str, type) \
+ static inline int cpu_mx7_is_##str(void) \
+ { \
+ return __imx7_cpu_type() == type; \
+ } \
+ \
+ static inline int cpu_is_##str(void) \
+ { \
+ if (!cpu_is_mx7()) \
+ return 0; \
+ return cpu_mx7_is_##str(); \
+ }
+
+DEFINE_MX7_CPU_TYPE(mx7s, IMX7_CPUTYPE_IMX7S);
+DEFINE_MX7_CPU_TYPE(mx7d, IMX7_CPUTYPE_IMX7D);
+
+#endif /* __MACH_IMX7_H */ \ No newline at end of file
diff --git a/arch/arm/mach-imx/include/mach/imx_cpu_types.h b/arch/arm/mach-imx/include/mach/imx_cpu_types.h
index 50be0b6..f95ef6f 100644
--- a/arch/arm/mach-imx/include/mach/imx_cpu_types.h
+++ b/arch/arm/mach-imx/include/mach/imx_cpu_types.h
@@ -11,6 +11,7 @@
#define IMX_CPU_IMX51 51
#define IMX_CPU_IMX53 53
#define IMX_CPU_IMX6 6
+#define IMX_CPU_IMX7 7
#define IMX_CPU_VF610 610
#endif /* __MACH_IMX_CPU_TYPES_H */
diff --git a/arch/arm/mach-imx/include/mach/iomux-v3.h b/arch/arm/mach-imx/include/mach/iomux-v3.h
index b8cc9af..271fe94 100644
--- a/arch/arm/mach-imx/include/mach/iomux-v3.h
+++ b/arch/arm/mach-imx/include/mach/iomux-v3.h
@@ -16,6 +16,8 @@
#ifndef __MACH_IOMUX_V3_H__
#define __MACH_IOMUX_V3_H__
+#include <io.h>
+
/*
* build IOMUX_PAD structure
*
@@ -76,6 +78,14 @@ typedef u64 iomux_v3_cfg_t;
((iomux_v3_cfg_t)(_sel_input_ofs) << MUX_SEL_INPUT_OFS_SHIFT) | \
((iomux_v3_cfg_t)(_sel_input) << MUX_SEL_INPUT_SHIFT))
+#define IOMUX_PAD_FIELD(name, pad) (((pad) & name##_MASK) >> name##_SHIFT)
+#define IOMUX_CTRL_OFS(pad) IOMUX_PAD_FIELD(MUX_CTRL_OFS, pad)
+#define IOMUX_MODE(pad) IOMUX_PAD_FIELD(MUX_MODE, pad)
+#define IOMUX_SEL_INPUT_OFS(pad) IOMUX_PAD_FIELD(MUX_SEL_INPUT_OFS, pad)
+#define IOMUX_SEL_INPUT(pad) IOMUX_PAD_FIELD(MUX_SEL_INPUT, pad)
+#define IOMUX_PAD_CTRL_OFS(pad) IOMUX_PAD_FIELD(MUX_PAD_CTRL_OFS, pad)
+#define IOMUX_PAD_CTRL(pad) IOMUX_PAD_FIELD(MUX_PAD_CTRL, pad)
+
#define NEW_PAD_CTRL(cfg, pad) (((cfg) & ~MUX_PAD_CTRL_MASK) | MUX_PAD_CTRL(pad))
/*
* Use to set PAD control
@@ -104,6 +114,57 @@ typedef u64 iomux_v3_cfg_t;
#define IOMUX_CONFIG_SION (0x1 << 4)
+#define SHARE_MUX_CONF_REG 0x1
+#define ZERO_OFFSET_VALID 0x2
+#define IMX7_PINMUX_LPSR 0x4
+
+static inline void iomux_v3_setup_pad(void __iomem *iomux, unsigned int flags,
+ u32 mux_reg, u32 conf_reg, u32 input_reg,
+ u32 mux_val, u32 conf_val, u32 input_val)
+{
+ const bool mux_ok = !!mux_reg || (flags & ZERO_OFFSET_VALID);
+ const bool conf_ok = !!conf_reg;
+ const bool input_ok = !!input_reg;
+
+ /*
+ * The sel_input registers for the LPSR controller pins are in the regular pinmux
+ * controller, so bend the register offset over to the other controller.
+ */
+ if (flags & IMX7_PINMUX_LPSR)
+ input_reg += 0x70000;
+
+ if (flags & SHARE_MUX_CONF_REG) {
+ mux_val |= conf_val;
+ } else {
+ if (conf_ok)
+ writel(conf_val, iomux + conf_reg);
+ }
+
+ if (mux_ok)
+ writel(mux_val, iomux + mux_reg);
+
+ if (input_ok)
+ writel(input_val, iomux + input_reg);
+}
+
+static inline void imx_setup_pad(void __iomem *iomux, iomux_v3_cfg_t pad)
+{
+ uint32_t pad_ctrl;
+
+ pad_ctrl = IOMUX_PAD_CTRL(pad);
+ pad_ctrl = (pad_ctrl & NO_PAD_CTRL) ? 0 : pad_ctrl,
+
+ iomux_v3_setup_pad(iomux, 0,
+ IOMUX_CTRL_OFS(pad),
+ IOMUX_PAD_CTRL_OFS(pad),
+ IOMUX_SEL_INPUT_OFS(pad),
+ IOMUX_MODE(pad),
+ pad_ctrl,
+ IOMUX_SEL_INPUT(pad));
+}
+
+
+
/*
* setups a single pad in the iomuxer
*/
diff --git a/arch/arm/mach-imx/include/mach/iomux-vf610.h b/arch/arm/mach-imx/include/mach/iomux-vf610.h
index 1535628..b9e509b 100644
--- a/arch/arm/mach-imx/include/mach/iomux-vf610.h
+++ b/arch/arm/mach-imx/include/mach/iomux-vf610.h
@@ -163,9 +163,13 @@ enum {
VF610_PAD_PTD22__NF_IO6 = IOMUX_PAD(0x0120, 0x0120, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD21__NF_IO5 = IOMUX_PAD(0x0124, 0x0124, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD20__NF_IO4 = IOMUX_PAD(0x0128, 0x0128, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+ VF610_PAD_PTD19__GPIO_75 = IOMUX_PAD(0x012C, 0x012C, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD19__NF_IO3 = IOMUX_PAD(0x012c, 0x012c, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+ VF610_PAD_PTD18__GPIO_76 = IOMUX_PAD(0x0120, 0x0130, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD18__NF_IO2 = IOMUX_PAD(0x0130, 0x0130, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+ VF610_PAD_PTD17__GPIO_77 = IOMUX_PAD(0x0134, 0x0134, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD17__NF_IO1 = IOMUX_PAD(0x0134, 0x0134, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+ VF610_PAD_PTD16__GPIO_78 = IOMUX_PAD(0x0138, 0x0138, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD16__NF_IO0 = IOMUX_PAD(0x0138, 0x0138, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTB24__NF_WE_B = IOMUX_PAD(0x0178, 0x0178, 5, __NA_, 0, VF610_NFC_CN_PAD_CTRL),
VF610_PAD_PTB25__NF_CE0_B = IOMUX_PAD(0x017c, 0x017c, 5, __NA_, 0, VF610_NFC_CN_PAD_CTRL),
@@ -223,4 +227,19 @@ enum {
VF610_PAD_DDR_ODT0__DDR_ODT_1 = IOMUX_PAD(0x02d8, 0x02d8, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
};
+#define PINCTRL_VF610_MUX_SHIFT 20
+
+
+static inline void vf610_setup_pad(void __iomem *iomux, iomux_v3_cfg_t pad)
+{
+ iomux_v3_setup_pad(iomux, SHARE_MUX_CONF_REG | ZERO_OFFSET_VALID,
+ IOMUX_CTRL_OFS(pad),
+ IOMUX_PAD_CTRL_OFS(pad),
+ IOMUX_SEL_INPUT_OFS(pad),
+ IOMUX_MODE(pad) << PINCTRL_VF610_MUX_SHIFT,
+ IOMUX_PAD_CTRL(pad),
+ IOMUX_SEL_INPUT(pad));
+}
+
+
#endif /* __IOMUX_VF610_H__ */
diff --git a/arch/arm/mach-imx/include/mach/ocotp-fusemap.h b/arch/arm/mach-imx/include/mach/ocotp-fusemap.h
new file mode 100644
index 0000000..44b58ca
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/ocotp-fusemap.h
@@ -0,0 +1,49 @@
+#ifndef __MACH_IMX_OCOTP_FUSEMAP_H
+#define __MACH_IMX_OCOTP_FUSEMAP_H
+
+#include <mach/ocotp.h>
+
+#define OCOTP_TESTER_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(0) | OCOTP_WIDTH(2))
+#define OCOTP_BOOT_CFG_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(2) | OCOTP_WIDTH(2))
+#define OCOTP_MEM_TRIM_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(4) | OCOTP_WIDTH(2))
+#define OCOTP_SJC_RESP_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(6) | OCOTP_WIDTH(1))
+#define OCOTP_MAC_ADDR_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(8) | OCOTP_WIDTH(2))
+#define OCOTP_GP1_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(10) | OCOTP_WIDTH(2))
+#define OCOTP_GP2_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(12) | OCOTP_WIDTH(2))
+#define OCOTP_SRK_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(14) | OCOTP_WIDTH(1))
+#define OCOTP_ANALOG_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(18) | OCOTP_WIDTH(2))
+#define OCOTP_MISC_CONF_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(22) | OCOTP_WIDTH(1))
+
+/* 0 <= n <= 1 */
+#define OCOTP_UNIQUE_ID(n) (OCOTP_WORD(0x410 + 0x10 * (n)) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define OCOTP_NUM_CORES (OCOTP_WORD(0x430) | OCOTP_BIT(20) | OCOTP_WIDTH(2))
+#define OCOTP_MLB_DISABLE (OCOTP_WORD(0x430) | OCOTP_BIT(26) | OCOTP_WIDTH(1))
+
+#define OCOTP_BOOT_CFG1 (OCOTP_WORD(0x450) | OCOTP_BIT(0) | OCOTP_WIDTH(8))
+#define OCOTP_BOOT_CFG2 (OCOTP_WORD(0x450) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
+#define OCOTP_BOOT_CFG3 (OCOTP_WORD(0x450) | OCOTP_BIT(16) | OCOTP_WIDTH(8))
+#define OCOTP_BOOT_CFG4 (OCOTP_WORD(0x450) | OCOTP_BIT(24) | OCOTP_WIDTH(8))
+#define OCOTP_SEC_CONFIG_1 (OCOTP_WORD(0x460) | OCOTP_BIT(1) | OCOTP_WIDTH(1))
+#define OCOTP_DIR_BT_DIS (OCOTP_WORD(0x460) | OCOTP_BIT(3) | OCOTP_WIDTH(1))
+#define OCOTP_BT_FUSE_SEL (OCOTP_WORD(0x460) | OCOTP_BIT(4) | OCOTP_WIDTH(1))
+#define OCOTP_SJC_DISABLE (OCOTP_WORD(0x460) | OCOTP_BIT(20) | OCOTP_WIDTH(1))
+#define OCOTP_WDOG_ENABLE (OCOTP_WORD(0x460) | OCOTP_BIT(21) | OCOTP_WIDTH(1))
+#define OCOTP_JTAG_SMODE (OCOTP_WORD(0x460) | OCOTP_BIT(22) | OCOTP_WIDTH(2))
+#define OCOTP_KTE (OCOTP_WORD(0x460) | OCOTP_BIT(26) | OCOTP_WIDTH(1))
+#define OCOTP_JTAG_HEO (OCOTP_WORD(0x460) | OCOTP_BIT(27) | OCOTP_WIDTH(1))
+#define OCOTP_NAND_READ_CMD_CODE1 (OCOTP_WORD(0x470) | OCOTP_BIT(0) | OCOTP_WIDTH(8))
+#define OCOTP_NAND_READ_CMD_CODE2 (OCOTP_WORD(0x470) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
+#define OCOTP_TEMP_SENSE (OCOTP_WORD(0x4e0) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define OCOTP_USB_VID (OCOTP_WORD(0x4f0) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
+#define OCOTP_USB_PID (OCOTP_WORD(0x4f0) | OCOTP_BIT(16) | OCOTP_WIDTH(16))
+/* 0 <= n <= 7 */
+#define OCOTP_SRK_HASH(n) (OCOTP_WORD(0x580 + 0x10 * (n)) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define OCOTP_SJC_RESP_31_0 (OCOTP_WORD(0x600) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define OCOTP_SJC_RESP_55_32 (OCOTP_WORD(0x610) | OCOTP_BIT(0) | OCOTP_WIDTH(24))
+#define OCOTP_MAC_ADDR_31_0 (OCOTP_WORD(0x620) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define OCOTP_MAC_ADDR_47_32 (OCOTP_WORD(0x630) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
+#define OCOTP_GP1 (OCOTP_WORD(0x660) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define OCOTP_GP2 (OCOTP_WORD(0x670) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define OCOTP_PAD_SETTINGS (OCOTP_WORD(0x6d0) | OCOTP_BIT(0) | OCOTP_WIDTH(6))
+
+#endif /* __MACH_IMX_OCOTP_FUSEMAP_H */
diff --git a/arch/arm/mach-imx/include/mach/ocotp.h b/arch/arm/mach-imx/include/mach/ocotp.h
index 430bc75..5474c27 100644
--- a/arch/arm/mach-imx/include/mach/ocotp.h
+++ b/arch/arm/mach-imx/include/mach/ocotp.h
@@ -16,5 +16,6 @@
int imx_ocotp_read_field(uint32_t field, unsigned *value);
int imx_ocotp_write_field(uint32_t field, unsigned value);
int imx_ocotp_permanent_write(int enable);
+bool imx_ocotp_sense_enable(bool enable);
#endif /* __MACH_IMX_OCOTP_H */
diff --git a/arch/arm/mach-imx/include/mach/vf610-fusemap.h b/arch/arm/mach-imx/include/mach/vf610-fusemap.h
new file mode 100644
index 0000000..a56faf1
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/vf610-fusemap.h
@@ -0,0 +1,15 @@
+#ifndef __MACH_VF610_OCOTP_H
+#define __MACH_VF610_OCOTP_H
+
+#include <mach/ocotp-fusemap.h>
+
+#define VF610_OCOTP_CPU_BUS_FRQ OCOTP_WORD(0x430) | OCOTP_BIT(22) | OCOTP_WIDTH(1)
+#define VF610_OCOTP_OVG_DISABLE OCOTP_WORD(0x430) | OCOTP_BIT(30) | OCOTP_WIDTH(1)
+#define VF610_OCOTP_SEC_CONFIG_0 OCOTP_WORD(0x440) | OCOTP_BIT(1) | OCOTP_WIDTH(1)
+#define VF610_OCOTP_SPEED_GRADING OCOTP_WORD(0x440) | OCOTP_BIT(18) | OCOTP_WIDTH(4)
+#define VF610_OCOTP_MAC_ADDR0_31_0 OCOTP_MAC_ADDR_31_0
+#define VF610_OCOTP_MAC_ADDR0_47_32 OCOTP_MAC_ADDR_47_32
+#define VF610_OCOTP_MAC_ADDR1_31_0 (OCOTP_WORD(0x640) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define VF610_OCOTP_MAC_ADDR1_47_32 (OCOTP_WORD(0x650) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
+
+#endif
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 68ff0ce..99b365a 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -69,12 +69,22 @@
/* Other definitions */
#define IMX6_OTP_DATA_ERROR_VAL 0xBADABADA
#define DEF_RELAX 20
-#define MAC_OFFSET (0x22 * 4)
+#define MAC_OFFSET_0 (0x22 * 4)
+#define MAC_OFFSET_1 (0x24 * 4)
+#define MAX_MAC_OFFSETS 2
#define MAC_BYTES 8
struct imx_ocotp_data {
int num_regs;
u32 (*addr_to_offset)(u32 addr);
+ u8 mac_offsets[MAX_MAC_OFFSETS];
+ u8 mac_offsets_num;
+};
+
+struct ocotp_priv_ethaddr {
+ char value[MAC_BYTES];
+ struct regmap *map;
+ u8 offset;
};
struct ocotp_priv {
@@ -84,9 +94,10 @@ struct ocotp_priv {
struct device_d dev;
int permanent_write_enable;
int sense_enable;
- char ethaddr[6];
+ struct ocotp_priv_ethaddr ethaddr[MAX_MAC_OFFSETS];
struct regmap_config map_config;
const struct imx_ocotp_data *data;
+ int mac_offset_idx;
};
static struct ocotp_priv *imx_ocotp;
@@ -348,6 +359,13 @@ int imx_ocotp_permanent_write(int enable)
return 0;
}
+bool imx_ocotp_sense_enable(bool enable)
+{
+ const bool old_value = imx_ocotp->sense_enable;
+ imx_ocotp->sense_enable = enable;
+ return old_value;
+}
+
static uint32_t inc_offset(uint32_t offset)
{
if ((offset & 0x3) == 0x3)
@@ -397,37 +415,39 @@ static void imx_ocotp_init_dt(struct device_d *dev, void __iomem *base)
}
}
+static void memreverse(void *dest, const void *src, size_t n)
+{
+ char *destp = dest;
+ const char *srcp = src + n - 1;
+
+ while(n--)
+ *destp++ = *srcp--;
+}
+
static int imx_ocotp_get_mac(struct param_d *param, void *priv)
{
- struct ocotp_priv *ocotp_priv = priv;
- char buf[8];
- int i, ret;
+ char buf[MAC_BYTES];
+ int ret;
+ struct ocotp_priv_ethaddr *ethaddr = priv;
- ret = regmap_bulk_read(ocotp_priv->map, MAC_OFFSET, buf, MAC_BYTES);
+ ret = regmap_bulk_read(ethaddr->map, ethaddr->offset,
+ buf, MAC_BYTES);
if (ret < 0)
return ret;
- for (i = 0; i < 6; i++)
- ocotp_priv->ethaddr[i] = buf[5 - i];
-
+ memreverse(ethaddr->value, buf, 6);
return 0;
}
static int imx_ocotp_set_mac(struct param_d *param, void *priv)
{
- struct ocotp_priv *ocotp_priv = priv;
- char buf[8];
- int i, ret;
-
- for (i = 0; i < 6; i++)
- buf[5 - i] = ocotp_priv->ethaddr[i];
- buf[6] = 0; buf[7] = 0;
+ char buf[MAC_BYTES];
+ struct ocotp_priv_ethaddr *ethaddr = priv;
- ret = regmap_bulk_write(ocotp_priv->map, MAC_OFFSET, buf, MAC_BYTES);
- if (ret < 0)
- return ret;
+ memreverse(buf, ethaddr->value, 6);
- return 0;
+ return regmap_bulk_write(ethaddr->map, ethaddr->offset,
+ buf, MAC_BYTES);
}
static struct regmap_bus imx_ocotp_regmap_bus = {
@@ -486,9 +506,28 @@ static int imx_ocotp_probe(struct device_d *dev)
NULL, NULL, &priv->permanent_write_enable, NULL);
}
- if (IS_ENABLED(CONFIG_NET))
- dev_add_param_mac(&(priv->dev), "mac_addr", imx_ocotp_set_mac,
- imx_ocotp_get_mac, priv->ethaddr, priv);
+ if (IS_ENABLED(CONFIG_NET)) {
+ int i;
+ struct ocotp_priv_ethaddr *ethaddr;
+
+ for (i = 0; i < priv->data->mac_offsets_num; i++) {
+ ethaddr = &priv->ethaddr[i];
+ ethaddr->map = priv->map;
+ ethaddr->offset = priv->data->mac_offsets[i];
+
+ dev_add_param_mac(&priv->dev, xasprintf("mac_addr%d", i),
+ imx_ocotp_set_mac, imx_ocotp_get_mac,
+ ethaddr->value, ethaddr);
+ }
+
+ /*
+ * Alias to mac_addr0 for backwards compatibility
+ */
+ ethaddr = &priv->ethaddr[0];
+ dev_add_param_mac(&priv->dev, "mac_addr",
+ imx_ocotp_set_mac, imx_ocotp_get_mac,
+ ethaddr->value, ethaddr);
+ }
dev_add_param_bool(&(priv->dev), "sense_enable", NULL, NULL, &priv->sense_enable, priv);
@@ -527,16 +566,22 @@ static u32 vf610_addr_to_offset(u32 addr)
static struct imx_ocotp_data imx6q_ocotp_data = {
.num_regs = 512,
.addr_to_offset = imx6q_addr_to_offset,
+ .mac_offsets_num = 1,
+ .mac_offsets = { MAC_OFFSET_0 },
};
static struct imx_ocotp_data imx6sl_ocotp_data = {
.num_regs = 256,
.addr_to_offset = imx6sl_addr_to_offset,
+ .mac_offsets_num = 1,
+ .mac_offsets = { MAC_OFFSET_0 },
};
static struct imx_ocotp_data vf610_ocotp_data = {
.num_regs = 512,
.addr_to_offset = vf610_addr_to_offset,
+ .mac_offsets_num = 2,
+ .mac_offsets = { MAC_OFFSET_0, MAC_OFFSET_1 },
};
static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
@@ -572,4 +617,4 @@ static int imx_ocotp_init(void)
return 0;
}
-coredevice_initcall(imx_ocotp_init);
+postcore_initcall(imx_ocotp_init);