Merge branch 'master' of git://www.denx.de/git/u-boot-imx
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index 8aeeaec..a34675c 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -21,6 +21,7 @@
 #include <asm/arch/crm_regs.h>
 #include <dm.h>
 #include <imx_thermal.h>
+#include <mmc.h>
 
 enum ldo_reg {
 	LDO_ARM,
@@ -355,7 +356,7 @@
 	return CONFIG_SYS_MMC_ENV_DEV;
 }
 
-int mmc_get_env_dev(void)
+static int mmc_get_boot_dev(void)
 {
 	struct src *src_regs = (struct src *)SRC_BASE_ADDR;
 	u32 soc_sbmr = readl(&src_regs->sbmr1);
@@ -370,16 +371,45 @@
 	 */
 	bootsel = (soc_sbmr & 0x000000FF) >> 6;
 
-	/* If not boot from sd/mmc, use default value */
+	/* No boot from sd/mmc */
 	if (bootsel != 1)
-		return CONFIG_SYS_MMC_ENV_DEV;
+		return -1;
 
 	/* BOOT_CFG2[3] and BOOT_CFG2[4] */
 	devno = (soc_sbmr & 0x00001800) >> 11;
 
+	return devno;
+}
+
+int mmc_get_env_dev(void)
+{
+	int devno = mmc_get_boot_dev();
+
+	/* If not boot from sd/mmc, use default value */
+	if (devno < 0)
+		return CONFIG_SYS_MMC_ENV_DEV;
+
 	return board_mmc_get_env_dev(devno);
 }
+
+#ifdef CONFIG_SYS_MMC_ENV_PART
+__weak int board_mmc_get_env_part(int devno)
+{
+	return CONFIG_SYS_MMC_ENV_PART;
+}
+
+uint mmc_get_env_part(struct mmc *mmc)
+{
+	int devno = mmc_get_boot_dev();
+
+	/* If not boot from sd/mmc, use default value */
+	if (devno < 0)
+		return CONFIG_SYS_MMC_ENV_PART;
+
+	return board_mmc_get_env_part(devno);
+}
 #endif
+#endif
 
 int board_postclk_init(void)
 {
@@ -537,3 +567,41 @@
 	writel(reg, &mxc_ccm->chsccdr);
 }
 #endif
+
+#ifdef CONFIG_IMX_BOOTAUX
+int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
+{
+	struct src *src_reg;
+	u32 stack, pc;
+
+	if (!boot_private_data)
+		return -EINVAL;
+
+	stack = *(u32 *)boot_private_data;
+	pc = *(u32 *)(boot_private_data + 4);
+
+	/* Set the stack and pc to M4 bootROM */
+	writel(stack, M4_BOOTROM_BASE_ADDR);
+	writel(pc, M4_BOOTROM_BASE_ADDR + 4);
+
+	/* Enable M4 */
+	src_reg = (struct src *)SRC_BASE_ADDR;
+	clrsetbits_le32(&src_reg->scr, SRC_SCR_M4C_NON_SCLR_RST_MASK,
+			SRC_SCR_M4_ENABLE_MASK);
+
+	return 0;
+}
+
+int arch_auxiliary_core_check_up(u32 core_id)
+{
+	struct src *src_reg = (struct src *)SRC_BASE_ADDR;
+	unsigned val;
+
+	val = readl(&src_reg->scr);
+
+	if (val & SRC_SCR_M4C_NON_SCLR_RST_MASK)
+		return 0;  /* assert in reset */
+
+	return 1;
+}
+#endif
diff --git a/arch/arm/cpu/armv7/mx7/clock.c b/arch/arm/cpu/armv7/mx7/clock.c
index 77db6e8..4d68ad2 100644
--- a/arch/arm/cpu/armv7/mx7/clock.c
+++ b/arch/arm/cpu/armv7/mx7/clock.c
@@ -1067,6 +1067,12 @@
 #ifdef CONFIG_NAND_MXS
 	clock_enable(CCGR_RAWNAND, 1);
 #endif
+
+	if (IS_ENABLED(CONFIG_IMX_RDC)) {
+		clock_enable(CCGR_RDC, 1);
+		clock_enable(CCGR_SEMA1, 1);
+		clock_enable(CCGR_SEMA2, 1);
+	}
 }
 
 #ifdef CONFIG_SECURE_BOOT
diff --git a/arch/arm/cpu/armv7/mx7/soc.c b/arch/arm/cpu/armv7/mx7/soc.c
index a6ab551..ba6cfb9 100644
--- a/arch/arm/cpu/armv7/mx7/soc.c
+++ b/arch/arm/cpu/armv7/mx7/soc.c
@@ -12,6 +12,8 @@
 #include <asm/imx-common/boot_mode.h>
 #include <asm/imx-common/dma.h>
 #include <asm/imx-common/hab.h>
+#include <asm/imx-common/rdc-sema.h>
+#include <asm/arch/imx-rdc.h>
 #include <asm/arch/crm_regs.h>
 #include <dm.h>
 #include <imx_thermal.h>
@@ -29,6 +31,65 @@
 };
 #endif
 
+#ifdef CONFIG_IMX_RDC
+/*
+ * In current design, if any peripheral was assigned to both A7 and M4,
+ * it will receive ipg_stop or ipg_wait when any of the 2 platforms enter
+ * low power mode. So M4 sleep will cause some peripherals fail to work
+ * at A7 core side. At default, all resources are in domain 0 - 3.
+ *
+ * There are 26 peripherals impacted by this IC issue:
+ * SIM2(sim2/emvsim2)
+ * SIM1(sim1/emvsim1)
+ * UART1/UART2/UART3/UART4/UART5/UART6/UART7
+ * SAI1/SAI2/SAI3
+ * WDOG1/WDOG2/WDOG3/WDOG4
+ * GPT1/GPT2/GPT3/GPT4
+ * PWM1/PWM2/PWM3/PWM4
+ * ENET1/ENET2
+ * Software Workaround:
+ * Here we setup some resources to domain 0 where M4 codes will move
+ * the M4 out of this domain. Then M4 is not able to access them any longer.
+ * This is a workaround for ic issue. So the peripherals are not shared
+ * by them. This way requires the uboot implemented the RDC driver and
+ * set the 26 IPs above to domain 0 only. M4 code will assign resource
+ * to its own domain, if it want to use the resource.
+ */
+static rdc_peri_cfg_t const resources[] = {
+	(RDC_PER_SIM1 | RDC_DOMAIN(0)),
+	(RDC_PER_SIM2 | RDC_DOMAIN(0)),
+	(RDC_PER_UART1 | RDC_DOMAIN(0)),
+	(RDC_PER_UART2 | RDC_DOMAIN(0)),
+	(RDC_PER_UART3 | RDC_DOMAIN(0)),
+	(RDC_PER_UART4 | RDC_DOMAIN(0)),
+	(RDC_PER_UART5 | RDC_DOMAIN(0)),
+	(RDC_PER_UART6 | RDC_DOMAIN(0)),
+	(RDC_PER_UART7 | RDC_DOMAIN(0)),
+	(RDC_PER_SAI1 | RDC_DOMAIN(0)),
+	(RDC_PER_SAI2 | RDC_DOMAIN(0)),
+	(RDC_PER_SAI3 | RDC_DOMAIN(0)),
+	(RDC_PER_WDOG1 | RDC_DOMAIN(0)),
+	(RDC_PER_WDOG2 | RDC_DOMAIN(0)),
+	(RDC_PER_WDOG3 | RDC_DOMAIN(0)),
+	(RDC_PER_WDOG4 | RDC_DOMAIN(0)),
+	(RDC_PER_GPT1 | RDC_DOMAIN(0)),
+	(RDC_PER_GPT2 | RDC_DOMAIN(0)),
+	(RDC_PER_GPT3 | RDC_DOMAIN(0)),
+	(RDC_PER_GPT4 | RDC_DOMAIN(0)),
+	(RDC_PER_PWM1 | RDC_DOMAIN(0)),
+	(RDC_PER_PWM2 | RDC_DOMAIN(0)),
+	(RDC_PER_PWM3 | RDC_DOMAIN(0)),
+	(RDC_PER_PWM4 | RDC_DOMAIN(0)),
+	(RDC_PER_ENET1 | RDC_DOMAIN(0)),
+	(RDC_PER_ENET2 | RDC_DOMAIN(0)),
+};
+
+static void isolate_resource(void)
+{
+	imx_rdc_setup_peripherals(resources, ARRAY_SIZE(resources));
+}
+#endif
+
 #if defined(CONFIG_SECURE_BOOT)
 struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
 	.bank = 1,
@@ -163,6 +224,9 @@
 	mxs_dma_init();
 #endif
 
+	if (IS_ENABLED(CONFIG_IMX_RDC))
+		isolate_resource();
+
 	return 0;
 }
 
@@ -211,6 +275,42 @@
 }
 #endif
 
+#ifdef CONFIG_IMX_BOOTAUX
+int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
+{
+	u32 stack, pc;
+	struct src *src_reg = (struct src *)SRC_BASE_ADDR;
+
+	if (!boot_private_data)
+		return 1;
+
+	stack = *(u32 *)boot_private_data;
+	pc = *(u32 *)(boot_private_data + 4);
+
+	/* Set the stack and pc to M4 bootROM */
+	writel(stack, M4_BOOTROM_BASE_ADDR);
+	writel(pc, M4_BOOTROM_BASE_ADDR + 4);
+
+	/* Enable M4 */
+	clrsetbits_le32(&src_reg->m4rcr, SRC_M4RCR_M4C_NON_SCLR_RST_MASK,
+			SRC_M4RCR_ENABLE_M4_MASK);
+
+	return 0;
+}
+
+int arch_auxiliary_core_check_up(u32 core_id)
+{
+	uint32_t val;
+	struct src *src_reg = (struct src *)SRC_BASE_ADDR;
+
+	val = readl(&src_reg->m4rcr);
+	if (val & 0x00000001)
+		return 0; /* assert in reset */
+
+	return 1;
+}
+#endif
+
 void set_wdog_reset(struct wdog_regs *wdog)
 {
 	u32 reg = readw(&wdog->wcr);
diff --git a/arch/arm/imx-common/Kconfig b/arch/arm/imx-common/Kconfig
index 229623922..1b7da5a 100644
--- a/arch/arm/imx-common/Kconfig
+++ b/arch/arm/imx-common/Kconfig
@@ -3,3 +3,17 @@
 
 config ROM_UNIFIED_SECTIONS
 	bool
+
+config IMX_RDC
+	bool "i.MX Resource domain controller driver"
+	depends on ARCH_MX6 || ARCH_MX7
+	help
+	  i.MX Resource domain controller is used to assign masters
+	  and peripherals to differet domains. This can be used to
+	  isolate resources.
+
+config IMX_BOOTAUX
+	bool "Support boot auxiliary core"
+	depends on ARCH_MX7 || ARCH_MX6
+	help
+	  bootaux [addr] to boot auxiliary core.
diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile
index e7190c3..30e66ba 100644
--- a/arch/arm/imx-common/Makefile
+++ b/arch/arm/imx-common/Makefile
@@ -27,6 +27,8 @@
 obj-y 	+= cache.o init.o
 obj-$(CONFIG_CMD_SATA) += sata.o
 obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o
+obj-$(CONFIG_IMX_RDC) += rdc-sema.o
+obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o
 obj-$(CONFIG_SECURE_BOOT)    += hab.o
 endif
 ifeq ($(SOC),$(filter $(SOC),vf610))
diff --git a/arch/arm/imx-common/imx_bootaux.c b/arch/arm/imx-common/imx_bootaux.c
new file mode 100644
index 0000000..69026df
--- /dev/null
+++ b/arch/arm/imx-common/imx_bootaux.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+
+/* Allow for arch specific config before we boot */
+static int __arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
+{
+	/* please define platform specific arch_auxiliary_core_up() */
+	return CMD_RET_FAILURE;
+}
+
+int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
+	__attribute__((weak, alias("__arch_auxiliary_core_up")));
+
+/* Allow for arch specific config before we boot */
+static int __arch_auxiliary_core_check_up(u32 core_id)
+{
+	/* please define platform specific arch_auxiliary_core_check_up() */
+	return 0;
+}
+
+int arch_auxiliary_core_check_up(u32 core_id)
+	__attribute__((weak, alias("__arch_auxiliary_core_check_up")));
+
+/*
+ * To i.MX6SX and i.MX7D, the image supported by bootaux needs
+ * the reset vector at the head for the image, with SP and PC
+ * as the first two words.
+ *
+ * Per the cortex-M reference manual, the reset vector of M4 needs
+ * to exist at 0x0 (TCMUL). The PC and SP are the first two addresses
+ * of that vector.  So to boot M4, the A core must build the M4's reset
+ * vector with getting the PC and SP from image and filling them to
+ * TCMUL. When M4 is kicked, it will load the PC and SP by itself.
+ * The TCMUL is mapped to (M4_BOOTROM_BASE_ADDR) at A core side for
+ * accessing the M4 TCMUL.
+ */
+int do_bootaux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	ulong addr;
+	int ret, up;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	up = arch_auxiliary_core_check_up(0);
+	if (up) {
+		printf("## Auxiliary core is already up\n");
+		return CMD_RET_SUCCESS;
+	}
+
+	addr = simple_strtoul(argv[1], NULL, 16);
+
+	printf("## Starting auxiliary core at 0x%08lX ...\n", addr);
+
+	ret = arch_auxiliary_core_up(0, addr);
+	if (ret)
+		return CMD_RET_FAILURE;
+
+	return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+	bootaux, CONFIG_SYS_MAXARGS, 1,	do_bootaux,
+	"Start auxiliary core",
+	""
+);
diff --git a/arch/arm/imx-common/rdc-sema.c b/arch/arm/imx-common/rdc-sema.c
new file mode 100644
index 0000000..dcb5c41
--- /dev/null
+++ b/arch/arm/imx-common/rdc-sema.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:  GPL-2.0+
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/imx-common/rdc-sema.h>
+#include <asm/arch/imx-rdc.h>
+#include <asm-generic/errno.h>
+
+/*
+ * Check if the RDC Semaphore is required for this peripheral.
+ */
+static inline int imx_rdc_check_sema_required(int per_id)
+{
+	struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR;
+	u32 reg;
+
+	reg = readl(&imx_rdc->pdap[per_id]);
+	/*
+	 * No semaphore:
+	 * Intial value or this peripheral is assigned to only one domain
+	 */
+	if (!(reg & RDC_PDAP_SREQ_MASK))
+		return -ENOENT;
+
+	return 0;
+}
+
+/*
+ * Check the peripheral read / write access permission on Domain [dom_id].
+ */
+int imx_rdc_check_permission(int per_id, int dom_id)
+{
+	struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR;
+	u32 reg;
+
+	reg = readl(&imx_rdc->pdap[per_id]);
+	if (!(reg & RDC_PDAP_DRW_MASK(dom_id)))
+		return -EACCES;  /*No access*/
+
+	return 0;
+}
+
+/*
+ * Lock up the RDC semaphore for this peripheral if semaphore is required.
+ */
+int imx_rdc_sema_lock(int per_id)
+{
+	struct rdc_sema_regs *imx_rdc_sema;
+	int ret;
+	u8 reg;
+
+	ret = imx_rdc_check_sema_required(per_id);
+	if (ret)
+		return ret;
+
+	if (per_id < SEMA_GATES_NUM)
+		imx_rdc_sema  = (struct rdc_sema_regs *)SEMAPHORE1_BASE_ADDR;
+	else
+		imx_rdc_sema  = (struct rdc_sema_regs *)SEMAPHORE2_BASE_ADDR;
+
+	do {
+		writeb(RDC_SEMA_PROC_ID,
+		       &imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]);
+		reg = readb(&imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]);
+		if ((reg & RDC_SEMA_GATE_GTFSM_MASK) == RDC_SEMA_PROC_ID)
+			break;  /* Get the Semaphore*/
+	} while (1);
+
+	return 0;
+}
+
+/*
+ * Unlock the RDC semaphore for this peripheral if main CPU is the
+ * semaphore owner.
+ */
+int imx_rdc_sema_unlock(int per_id)
+{
+	struct rdc_sema_regs *imx_rdc_sema;
+	int ret;
+	u8 reg;
+
+	ret = imx_rdc_check_sema_required(per_id);
+	if (ret)
+		return ret;
+
+	if (per_id < SEMA_GATES_NUM)
+		imx_rdc_sema  = (struct rdc_sema_regs *)SEMAPHORE1_BASE_ADDR;
+	else
+		imx_rdc_sema  = (struct rdc_sema_regs *)SEMAPHORE2_BASE_ADDR;
+
+	reg = readb(&imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]);
+	if ((reg & RDC_SEMA_GATE_GTFSM_MASK) != RDC_SEMA_PROC_ID)
+		return 1;	/*Not the semaphore owner */
+
+	writeb(0x0, &imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]);
+
+	return 0;
+}
+
+/*
+ * Setup RDC setting for one peripheral
+ */
+int imx_rdc_setup_peri(rdc_peri_cfg_t p)
+{
+	struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR;
+	u32 reg = 0;
+	u32 share_count = 0;
+	u32 peri_id = p & RDC_PERI_MASK;
+	u32 domain = (p & RDC_DOMAIN_MASK) >> RDC_DOMAIN_SHIFT_BASE;
+
+	/* No domain assigned */
+	if (domain == 0)
+		return -EINVAL;
+
+	reg |= domain;
+
+	share_count = (domain & 0x3)
+		+ ((domain >> 2) & 0x3)
+		+ ((domain >> 4) & 0x3)
+		+ ((domain >> 6) & 0x3);
+
+	if (share_count > 0x3)
+		reg |= RDC_PDAP_SREQ_MASK;
+
+	writel(reg, &imx_rdc->pdap[peri_id]);
+
+	return 0;
+}
+
+/*
+ * Setup RDC settings for multiple peripherals
+ */
+int imx_rdc_setup_peripherals(rdc_peri_cfg_t const *peripherals_list,
+				     unsigned count)
+{
+	rdc_peri_cfg_t const *p = peripherals_list;
+	int i, ret;
+
+	for (i = 0; i < count; i++) {
+		ret = imx_rdc_setup_peri(*p);
+		if (ret)
+			return ret;
+		p++;
+	}
+
+	return 0;
+}
+
+/*
+ * Setup RDC setting for one master
+ */
+int imx_rdc_setup_ma(rdc_ma_cfg_t p)
+{
+	struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR;
+	u32 master_id = (p & RDC_MASTER_MASK) >> RDC_MASTER_SHIFT;
+	u32 domain = (p & RDC_DOMAIN_MASK) >> RDC_DOMAIN_SHIFT_BASE;
+
+	writel((domain & RDC_MDA_DID_MASK), &imx_rdc->mda[master_id]);
+
+	return 0;
+}
+
+/*
+ * Setup RDC settings for multiple masters
+ */
+int imx_rdc_setup_masters(rdc_ma_cfg_t const *masters_list, unsigned count)
+{
+	rdc_ma_cfg_t const *p = masters_list;
+	int i, ret;
+
+	for (i = 0; i < count; i++) {
+		ret = imx_rdc_setup_ma(*p);
+		if (ret)
+			return ret;
+		p++;
+	}
+
+	return 0;
+}
diff --git a/arch/arm/include/asm/arch-mx6/imx-rdc.h b/arch/arm/include/asm/arch-mx6/imx-rdc.h
new file mode 100644
index 0000000..c4d3bb4
--- /dev/null
+++ b/arch/arm/include/asm/arch-mx6/imx-rdc.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:  GPL-2.0+
+ */
+
+#ifndef __IMX_RDC_H__
+#define __IMX_RDC_H__
+
+#if defined(CONFIG_MX6SX)
+#include "mx6sx_rdc.h"
+#else
+#error "Please select cpu"
+#endif /* CONFIG_MX6SX */
+
+#endif	/* __IMX_RDC_H__*/
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index 5c45bf6..f3c26dc 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -356,6 +356,30 @@
 #define SRC_SCR_CORE_3_ENABLE_OFFSET    24
 #define SRC_SCR_CORE_3_ENABLE_MASK      (1<<SRC_SCR_CORE_3_ENABLE_OFFSET)
 
+struct rdc_regs {
+	u32	vir;		/* Version information */
+	u32	reserved1[8];
+	u32	stat;		/* Status */
+	u32	intctrl;	/* Interrupt and Control */
+	u32	intstat;	/* Interrupt Status */
+	u32	reserved2[116];
+	u32	mda[32];	/* Master Domain Assignment */
+	u32	reserved3[96];
+	u32	pdap[104];	/* Peripheral Domain Access Permissions */
+	u32	reserved4[88];
+	struct {
+		u32 mrsa;	/* Memory Region Start Address */
+		u32 mrea;	/* Memory Region End Address */
+		u32 mrc;	/* Memory Region Control */
+		u32 mrvs;	/* Memory Region Violation Status */
+	} mem_region[55];
+};
+
+struct rdc_sema_regs {
+	u8	gate[64];	/* Gate */
+	u16	rstgt;		/* Reset Gate */
+};
+
 /* WEIM registers */
 struct weim {
 	u32 cs0gcr1;
@@ -414,6 +438,11 @@
 	u32     gpr10;
 };
 
+#define SRC_SCR_M4_ENABLE_OFFSET                22
+#define SRC_SCR_M4_ENABLE_MASK                  (1 << 22)
+#define SRC_SCR_M4C_NON_SCLR_RST_OFFSET         4
+#define SRC_SCR_M4C_NON_SCLR_RST_MASK           (1 << 4)
+
 /* GPR1 bitfields */
 #define IOMUXC_GPR1_APP_CLK_REQ_N		BIT(30)
 #define IOMUXC_GPR1_PCIE_EXIT_L1		BIT(28)
diff --git a/arch/arm/include/asm/arch-mx6/mx6sx_rdc.h b/arch/arm/include/asm/arch-mx6/mx6sx_rdc.h
new file mode 100644
index 0000000..addfe01
--- /dev/null
+++ b/arch/arm/include/asm/arch-mx6/mx6sx_rdc.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:  GPL-2.0+
+ */
+
+#ifndef __MX6SX_RDC_H__
+#define __MX6SX_RDC_H__
+
+#define RDC_SEMA_PROC_ID 2  /* The processor ID for main CPU */
+
+enum {
+	RDC_PER_PWM1 = 0,
+	RDC_PER_PWM2,
+	RDC_PER_PWM3,
+	RDC_PER_PWM4,
+	RDC_PER_CAN1,
+	RDC_PER_CAN2,
+	RDC_PER_GPT,
+	RDC_PER_GPIO1,
+	RDC_PER_GPIO2,
+	RDC_PER_GPIO3,
+	RDC_PER_GPIO4,
+	RDC_PER_GPIO5,
+	RDC_PER_GPIO6,
+	RDC_PER_GPIO7,
+	RDC_PER_KPP,
+	RDC_PER_WDOG1,
+	RDC_PER_WODG2,
+	RDC_PER_CCM,
+	RDC_PER_ANATOPDIG,
+	RDC_PER_SNVSHP,
+	RDC_PER_EPIT1,
+	RDC_PER_EPIT2,
+	RDC_PER_SRC,
+	RDC_PER_GPC,
+	RDC_PER_IOMUXC,
+	RDC_PER_IOMUXCGPR,
+	RDC_PER_CANFD1,
+	RDC_PER_SDMA,
+	RDC_PER_CANFD2,
+	RDC_PER_SEMA1,
+	RDC_PER_SEMA2,
+	RDC_PER_RDC,
+	RDC_PER_AIPSTZ1_GE1,
+	RDC_PER_AIPSTZ2_GE2,
+	RDC_PER_USBO2H_PL301,
+	RDC_PER_USBO2H_USB,
+	RDC_PER_ENET1,
+	RDC_PER_MLB25,
+	RDC_PER_USDHC1,
+	RDC_PER_USDHC2,
+	RDC_PER_USDHC3,
+	RDC_PER_USDHC4,
+	RDC_PER_I2C1,
+	RDC_PER_I2C2,
+	RDC_PER_I2C3,
+	RDC_PER_ROMCP,
+	RDC_PER_MMDC,
+	RDC_PER_ENET2,
+	RDC_PER_EIM,
+	RDC_PER_OCOTP,
+	RDC_PER_CSU,
+	RDC_PER_PERFMON1,
+	RDC_PER_PERFMON2,
+	RDC_PER_AXIMON,
+	RDC_PER_TZASC1,
+	RDC_PER_SAI1,
+	RDC_PER_AUDMUX,
+	RDC_PER_SAI2,
+	RDC_PER_QSPI1,
+	RDC_PER_QSPI2,
+	RDC_PER_UART2,
+	RDC_PER_UART3,
+	RDC_PER_UART4,
+	RDC_PER_UART5,
+	RDC_PER_I2C4,
+	RDC_PER_QOSC,
+	RDC_PER_CAAM,
+	RDC_PER_DAP,
+	RDC_PER_ADC1,
+	RDC_PER_ADC2,
+	RDC_PER_WDOG3,
+	RDC_PER_ECSPI5,
+	RDC_PER_SEMA4,
+	RDC_PER_MUPORT1,
+	RDC_PER_CANFD_CPU,
+	RDC_PER_MUPORT2,
+	RDC_PER_UART6,
+	RDC_PER_PWM5,
+	RDC_PER_PWM6,
+	RDC_PER_PWM7,
+	RDC_PER_PWM8,
+	RDC_PER_AIPSTZ3_GE0,
+	RDC_PER_AIPSTZ3_GE1,
+	RDC_PER_RESERVED1,
+	RDC_PER_SPDIF,
+	RDC_PER_ECSPI1,
+	RDC_PER_ECSPI2,
+	RDC_PER_ECSPI3,
+	RDC_PER_ECSPI4,
+	RDC_PER_RESERVED2,
+	RDC_PER_RESERVED3,
+	RDC_PER_UART1,
+	RDC_PER_ESAI,
+	RDC_PER_SSI1,
+	RDC_PER_SSI2,
+	RDC_PER_SSI3,
+	RDC_PER_ASRC,
+	RDC_PER_RESERVED4,
+	RDC_PER_SPBA_MA,
+	RDC_PER_GIS,
+	RDC_PER_DCIC1,
+	RDC_PER_DCIC2,
+	RDC_PER_CSI1,
+	RDC_PER_PXP,
+	RDC_PER_CSI2,
+	RDC_PER_LCDIF1,
+	RDC_PER_LCDIF2,
+	RDC_PER_VADC,
+	RDC_PER_VDEC,
+	RDC_PER_SPBA_DISPLAYMIX,
+};
+
+enum {
+	RDC_MA_A9_L2CACHE = 0,
+	RDC_MA_M4,
+	RDC_MA_GPU,
+	RDC_MA_CSI1,
+	RDC_MA_CSI2,
+	RDC_MA_LCDIF1,
+	RDC_MA_LCDIF2,
+	RDC_MA_PXP,
+	RDC_MA_PCIE_CTRL,
+	RDC_MA_DAP,
+	RDC_MA_CAAM,
+	RDC_MA_SDMA_PERI,
+	RDC_MA_SDMA_BURST,
+	RDC_MA_APBHDMA,
+	RDC_MA_RAWNAND,
+	RDC_MA_USDHC1,
+	RDC_MA_USDHC2,
+	RDC_MA_USDHC3,
+	RDC_MA_USDHC4,
+	RDC_MA_USB,
+	RDC_MA_MLB,
+	RDC_MA_TEST,
+	RDC_MA_ENET1_TX,
+	RDC_MA_ENET1_RX,
+	RDC_MA_ENET2_TX,
+	RDC_MA_ENET2_RX,
+	RDC_MA_SDMA,
+};
+
+#endif	/* __MX6SX_RDC_H__*/
diff --git a/arch/arm/include/asm/arch-mx7/imx-rdc.h b/arch/arm/include/asm/arch-mx7/imx-rdc.h
new file mode 100644
index 0000000..dbeed56
--- /dev/null
+++ b/arch/arm/include/asm/arch-mx7/imx-rdc.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:  GPL-2.0+
+ */
+
+#ifndef __IMX_RDC_H__
+#define __IMX_RDC_H__
+
+#if defined(CONFIG_MX7D)
+#include "mx7d_rdc.h"
+#else
+#error "Please select cpu"
+#endif	/* CONFIG_MX7D */
+
+#endif	/* __IMX_RDC_H__*/
diff --git a/arch/arm/include/asm/arch-mx7/imx-regs.h b/arch/arm/include/asm/arch-mx7/imx-regs.h
index 58a25c7..a3106e7 100644
--- a/arch/arm/include/asm/arch-mx7/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx7/imx-regs.h
@@ -212,10 +212,16 @@
 #define DEBUG_MONITOR_BASE_ADDR IP2APB_AXIMON_IPS_BASE_ADDR
 
 #define USB_BASE_ADDR USBOTG1_IPS_BASE_ADDR
+#define SEMAPHORE1_BASE_ADDR SEMA41_IPS_BASE_ADDR
+#define SEMAPHORE2_BASE_ADDR SEMA42_IPS_BASE_ADDR
+#define RDC_BASE_ADDR RDC_IPS_BASE_ADDR
 
 #define FEC_QUIRK_ENET_MAC
 #define SNVS_LPGPR	0x68
 
+#define CONFIG_SYS_FSL_SEC_ADDR         (CAAM_IPS_BASE_ADDR)
+#define CONFIG_SYS_FSL_JR0_ADDR         (CONFIG_SYS_FSL_SEC_ADDR  + 0x1000)
+
 #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
 #include <asm/imx-common/regs-lcdif.h>
 #include <asm/types.h>
@@ -257,6 +263,11 @@
 	u32 ddrc_rcr;
 };
 
+#define SRC_M4RCR_M4C_NON_SCLR_RST_OFFSET	0
+#define SRC_M4RCR_M4C_NON_SCLR_RST_MASK		(1 << 0)
+#define SRC_M4RCR_ENABLE_M4_OFFSET		3
+#define SRC_M4RCR_ENABLE_M4_MASK		(1 << 3)
+
 /* GPR0 Bit Fields */
 #define IOMUXC_GPR_GPR0_DMAREQ_MUX_SEL0_MASK     0x1u
 #define IOMUXC_GPR_GPR0_DMAREQ_MUX_SEL0_SHIFT    0
diff --git a/arch/arm/include/asm/arch-mx7/mx7d_rdc.h b/arch/arm/include/asm/arch-mx7/mx7d_rdc.h
new file mode 100644
index 0000000..9073cbd
--- /dev/null
+++ b/arch/arm/include/asm/arch-mx7/mx7d_rdc.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:  GPL-2.0+
+ */
+
+#ifndef __MX7D_RDC_H__
+#define __MX7D_RDC_H__
+
+#define RDC_SEMA_PROC_ID 2  /* The processor ID for main CPU */
+
+enum {
+	RDC_PER_GPIO1 = 0,
+	RDC_PER_GPIO2,
+	RDC_PER_GPIO3,
+	RDC_PER_GPIO4,
+	RDC_PER_GPIO5,
+	RDC_PER_GPIO6,
+	RDC_PER_GPIO7,
+	RDC_PER_IOMUXC_LPSR_GPR,
+	RDC_PER_WDOG1,
+	RDC_PER_WDOG2,
+	RDC_PER_WDOG3,
+	RDC_PER_WDOG4,
+	RDC_PER_IOMUXC_LPSR,
+	RDC_PER_GPT1,
+	RDC_PER_GPT2,
+	RDC_PER_GPT3,
+	RDC_PER_GPT4,
+	RDC_PER_ROMCP,
+	RDC_PER_KPP,
+	RDC_PER_IOMUXC,
+	RDC_PER_IOMUXCGPR,
+	RDC_PER_OCOTP,
+	RDC_PER_ANATOP_DIG,
+	RDC_PER_SNVS_HP,
+	RDC_PER_CCM,
+	RDC_PER_SRC,
+	RDC_PER_GPC,
+	RDC_PER_SEMA1,
+	RDC_PER_SEMA2,
+	RDC_PER_RDC,
+	RDC_PER_CSU,
+	RDC_PER_RESERVED1,
+	RDC_PER_RESERVED2,
+	RDC_PER_ADC1,
+	RDC_PER_ADC2,
+	RDC_PER_ECSPI4,
+	RDC_PER_FLEX_TIMER1,
+	RDC_PER_FLEX_TIMER2,
+	RDC_PER_PWM1,
+	RDC_PER_PWM2,
+	RDC_PER_PWM3,
+	RDC_PER_PWM4,
+	RDC_PER_SYSTEM_COUNTER_READ,
+	RDC_PER_SYSTEM_COUNTER_COMPARE,
+	RDC_PER_SYSTEM_COUNTER_CONTROL,
+	RDC_PER_PCIE_PHY,
+	RDC_PER_RESERVED3,
+	RDC_PER_EPDC,
+	RDC_PER_PXP,
+	RDC_PER_CSI,
+	RDC_PER_RESERVED4,
+	RDC_PER_LCDIF,
+	RDC_PER_RESERVED5,
+	RDC_PER_MIPI_CSI,
+	RDC_PER_MIPI_DSI,
+	RDC_PER_RESERVED6,
+	RDC_PER_TZASC,
+	RDC_PER_DDR_PHY,
+	RDC_PER_DDRC,
+	RDC_PER_RESERVED7,
+	RDC_PER_PERFMON1,
+	RDC_PER_PERFMON2,
+	RDC_PER_AXI_DEBUG_MON,
+	RDC_PER_QOSC,
+	RDC_PER_FLEXCAN1,
+	RDC_PER_FLEXCAN2,
+	RDC_PER_I2C1,
+	RDC_PER_I2C2,
+	RDC_PER_I2C3,
+	RDC_PER_I2C4,
+	RDC_PER_UART4,
+	RDC_PER_UART5,
+	RDC_PER_UART6,
+	RDC_PER_UART7,
+	RDC_PER_MU_A,
+	RDC_PER_MU_B,
+	RDC_PER_SEMAPHORE_HS,
+	RDC_PER_USB_PL301,
+	RDC_PER_RESERVED8,
+	RDC_PER_RESERVED9,
+	RDC_PER_RESERVED10,
+	RDC_PER_USB1,
+	RDC_PER_USB2,
+	RDC_PER_USB3,
+	RDC_PER_USDHC1,
+	RDC_PER_USDHC2,
+	RDC_PER_USDHC3,
+	RDC_PER_RESERVED11,
+	RDC_PER_RESERVED12,
+	RDC_PER_SIM1,
+	RDC_PER_SIM2,
+	RDC_PER_QSPI,
+	RDC_PER_WEIM,
+	RDC_PER_SDMA,
+	RDC_PER_ENET1,
+	RDC_PER_ENET2,
+	RDC_PER_RESERVED13,
+	RDC_PER_RESERVED14,
+	RDC_PER_ECSPI1,
+	RDC_PER_ECSPI2,
+	RDC_PER_ECSPI3,
+	RDC_PER_RESERVED15,
+	RDC_PER_UART1,
+	RDC_PER_UART2,
+	RDC_PER_UART3,
+	RDC_PER_RESERVED16,
+	RDC_PER_SAI1,
+	RDC_PER_SAI2,
+	RDC_PER_SAI3,
+	RDC_PER_RESERVED17,
+	RDC_PER_RESERVED18,
+	RDC_PER_SPBA,
+	RDC_PER_DAP,
+	RDC_PER_RESERVED19,
+	RDC_PER_RESERVED20,
+	RDC_PER_RESERVED21,
+	RDC_PER_CAAM,
+	RDC_PER_RESERVED22,
+};
+
+enum {
+	RDC_MA_A7 = 0,
+	RDC_MA_M4,
+	RDC_MA_PCIE,
+	RDC_MA_CSI,
+	RDC_MA_EPDC,
+	RDC_MA_LCDIF,
+	RDC_MA_DISPLAY_PORT,
+	RDC_MA_PXP,
+	RDC_MA_CORESIGHT,
+	RDC_MA_DAP,
+	RDC_MA_CAAM,
+	RDC_MA_SDMA_PERI,
+	RDC_MA_SDMA_BURST,
+	RDC_MA_APBHDMA,
+	RDC_MA_RAWNAND,
+	RDC_MA_USDHC1,
+	RDC_MA_USDHC2,
+	RDC_MA_USDHC3,
+	RDC_MA_NC1,
+	RDC_MA_USB,
+	RDC_MA_NC2,
+	RDC_MA_TEST,
+	RDC_MA_ENET1_TX,
+	RDC_MA_ENET1_RX,
+	RDC_MA_ENET2_TX,
+	RDC_MA_ENET2_RX,
+	RDC_MA_SDMA,
+};
+
+#endif	/* __MX7D_RDC_H__*/
diff --git a/arch/arm/include/asm/imx-common/rdc-sema.h b/arch/arm/include/asm/imx-common/rdc-sema.h
new file mode 100644
index 0000000..2c61e56
--- /dev/null
+++ b/arch/arm/include/asm/imx-common/rdc-sema.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:  GPL-2.0+
+ */
+
+#ifndef __RDC_SEMA_H__
+#define __RDC_SEMA_H__
+
+/*
+ * rdc_peri_cfg_t and rdc_ma_cft_t use the same layout.
+ *
+ *   [ 23 22 | 21 20 | 19 18 | 17 16 ] | [ 15 - 8 ] | [ 7 - 0 ]
+ *      d3      d2      d1       d0    | master id  |  peri id
+ *   d[x] means domain[x], x can be [3 - 0].
+ */
+typedef u32 rdc_peri_cfg_t;
+typedef u32 rdc_ma_cfg_t;
+
+#define RDC_PERI_SHIFT		0
+#define RDC_PERI_MASK		0xFF
+
+#define RDC_DOMAIN_SHIFT_BASE	16
+#define RDC_DOMAIN_MASK		0xFF0000
+#define RDC_DOMAIN_SHIFT(x)	(RDC_DOMAIN_SHIFT_BASE + ((x << 1)))
+#define RDC_DOMAIN(x)		((rdc_peri_cfg_t)(0x3 << RDC_DOMAIN_SHIFT(x)))
+
+#define RDC_MASTER_SHIFT	8
+#define RDC_MASTER_MASK		0xFF00
+#define RDC_MASTER_CFG(master_id, domain_id) (rdc_ma_cfg_t)((master_id << 8) | \
+					(domain_id << RDC_DOMAIN_SHIFT_BASE))
+
+/* The Following macro definitions are common to i.MX6SX and i.MX7D */
+#define SEMA_GATES_NUM		64
+
+#define RDC_MDA_DID_SHIFT	0
+#define RDC_MDA_DID_MASK	(0x3 << RDC_MDA_DID_SHIFT)
+#define RDC_MDA_LCK_SHIFT	31
+#define RDC_MDA_LCK_MASK	(0x1 << RDC_MDA_LCK_SHIFT)
+
+#define RDC_PDAP_DW_SHIFT(domain)	((domain) << 1)
+#define RDC_PDAP_DR_SHIFT(domain)	(1 + RDC_PDAP_DW_SHIFT(domain))
+#define RDC_PDAP_DW_MASK(domain)	(1 << RDC_PDAP_DW_SHIFT(domain))
+#define RDC_PDAP_DR_MASK(domain)	(1 << RDC_PDAP_DR_SHIFT(domain))
+#define RDC_PDAP_DRW_MASK(domain)	(RDC_PDAP_DW_MASK(domain) | \
+					 RDC_PDAP_DR_MASK(domain))
+
+#define RDC_PDAP_SREQ_SHIFT	30
+#define RDC_PDAP_SREQ_MASK	(0x1 << RDC_PDAP_SREQ_SHIFT)
+#define RDC_PDAP_LCK_SHIFT	31
+#define RDC_PDAP_LCK_MASK	(0x1 << RDC_PDAP_LCK_SHIFT)
+
+#define RDC_MRSA_SADR_SHIFT	7
+#define RDC_MRSA_SADR_MASK	(0x1ffffff << RDC_MRSA_SADR_SHIFT)
+
+#define RDC_MREA_EADR_SHIFT	7
+#define RDC_MREA_EADR_MASK	(0x1ffffff << RDC_MREA_EADR_SHIFT)
+
+#define RDC_MRC_DW_SHIFT(domain)	(domain)
+#define RDC_MRC_DR_SHIFT(domain)	(1 + RDC_MRC_DW_SHIFT(domain))
+#define RDC_MRC_DW_MASK(domain)		(1 << RDC_MRC_DW_SHIFT(domain))
+#define RDC_MRC_DR_MASK(domain)		(1 << RDC_MRC_DR_SHIFT(domain))
+#define RDC_MRC_DRW_MASK(domain)	(RDC_MRC_DW_MASK(domain) | \
+					 RDC_MRC_DR_MASK(domain))
+#define RDC_MRC_ENA_SHIFT	30
+#define RDC_MRC_ENA_MASK	(0x1 << RDC_MRC_ENA_SHIFT)
+#define RDC_MRC_LCK_SHIFT	31
+#define RDC_MRC_LCK_MASK	(0x1 << RDC_MRC_LCK_SHIFT)
+
+#define RDC_MRVS_VDID_SHIFT	0
+#define RDC_MRVS_VDID_MASK	(0x3 << RDC_MRVS_VDID_SHIFT)
+#define RDC_MRVS_AD_SHIFT	4
+#define RDC_MRVS_AD_MASK	(0x1 << RDC_MRVS_AD_SHIFT)
+#define RDC_MRVS_VADDR_SHIFT	5
+#define RDC_MRVS_VADDR_MASK	(0x7ffffff << RDC_MRVS_VADDR_SHIFT)
+
+#define RDC_SEMA_GATE_GTFSM_SHIFT	0
+#define RDC_SEMA_GATE_GTFSM_MASK	(0xf << RDC_SEMA_GATE_GTFSM_SHIFT)
+#define RDC_SEMA_GATE_LDOM_SHIFT	5
+#define RDC_SEMA_GATE_LDOM_MASK		(0x3 << RDC_SEMA_GATE_LDOM_SHIFT)
+
+#define RDC_SEMA_RSTGT_RSTGDP_SHIFT	0
+#define RDC_SEMA_RSTGT_RSTGDP_MASK	(0xff << RDC_SEMA_RSTGT_RSTGDP_SHIFT)
+#define RDC_SEMA_RSTGT_RSTGSM_SHIFT	2
+#define RDC_SEMA_RSTGT_RSTGSM_MASK	(0x3 << RDC_SEMA_RSTGT_RSTGSM_SHIFT)
+#define RDC_SEMA_RSTGT_RSTGMS_SHIFT	4
+#define RDC_SEMA_RSTGT_RSTGMS_MASK	(0xf << RDC_SEMA_RSTGT_RSTGMS_SHIFT)
+#define RDC_SEMA_RSTGT_RSTGTN_SHIFT	8
+#define RDC_SEMA_RSTGT_RSTGTN_MASK	(0xff << RDC_SEMA_RSTGT_RSTGTN_SHIFT)
+
+int imx_rdc_check_permission(int per_id, int dom_id);
+int imx_rdc_sema_lock(int per_id);
+int imx_rdc_sema_unlock(int per_id);
+int imx_rdc_setup_peri(rdc_peri_cfg_t p);
+int imx_rdc_setup_peripherals(rdc_peri_cfg_t const *peripherals_list,
+			      unsigned count);
+int imx_rdc_setup_ma(rdc_ma_cfg_t p);
+int imx_rdc_setup_masters(rdc_ma_cfg_t const *masters_list, unsigned count);
+
+#endif	/* __RDC_SEMA_H__*/
diff --git a/board/freescale/mx7dsabresd/MAINTAINERS b/board/freescale/mx7dsabresd/MAINTAINERS
index 3910ee4..b96642a 100644
--- a/board/freescale/mx7dsabresd/MAINTAINERS
+++ b/board/freescale/mx7dsabresd/MAINTAINERS
@@ -1,5 +1,5 @@
 MX7DSABRESD BOARD
-M:	Adrian Alonso <aalonso@freescale.com>
+M:	Adrian Alonso <adrian.alonso@nxp.com>
 S:	Maintained
 F:	board/freescale/mx7dsabresd
 F:	include/configs/mx7dsabresd.h
diff --git a/board/freescale/mx7dsabresd/mx7dsabresd.c b/board/freescale/mx7dsabresd/mx7dsabresd.c
index fee24e2..4d0b195 100644
--- a/board/freescale/mx7dsabresd/mx7dsabresd.c
+++ b/board/freescale/mx7dsabresd/mx7dsabresd.c
@@ -23,6 +23,7 @@
 #include <i2c.h>
 #include <asm/imx-common/mxc_i2c.h>
 #include <asm/arch/crm_regs.h>
+#include <usb.h>
 #include <usb/ehci-fsl.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -111,6 +112,14 @@
 	MX7D_PAD_SD3_RESET_B__GPIO6_IO11 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 };
 
+static iomux_v3_cfg_t const usb_otg1_pads[] = {
+	MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const usb_otg2_pads[] = {
+	MX7D_PAD_UART3_CTS_B__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
 #define IOX_SDI IMX_GPIO_NR(1, 9)
 #define IOX_STCP IMX_GPIO_NR(1, 12)
 #define IOX_SHCP IMX_GPIO_NR(1, 13)
@@ -511,6 +520,10 @@
 	setup_iomux_uart();
 
 	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
+	imx_iomux_v3_setup_multiple_pads(usb_otg1_pads,
+					 ARRAY_SIZE(usb_otg1_pads));
+	imx_iomux_v3_setup_multiple_pads(usb_otg2_pads,
+					 ARRAY_SIZE(usb_otg2_pads));
 
 	return 0;
 }
@@ -602,29 +615,11 @@
 }
 
 #ifdef CONFIG_USB_EHCI_MX7
-static iomux_v3_cfg_t const usb_otg1_pads[] = {
-	MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
-};
-
-static iomux_v3_cfg_t const usb_otg2_pads[] = {
-	MX7D_PAD_UART3_CTS_B__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
-};
-
-int board_ehci_hcd_init(int port)
+int board_usb_phy_mode(int port)
 {
-	switch (port) {
-	case 0:
-		imx_iomux_v3_setup_multiple_pads(usb_otg1_pads,
-						 ARRAY_SIZE(usb_otg1_pads));
-		break;
-	case 1:
-		imx_iomux_v3_setup_multiple_pads(usb_otg2_pads,
-						 ARRAY_SIZE(usb_otg2_pads));
-		break;
-	default:
-		printf("MXC USB port %d not yet supported\n", port);
-		return -EINVAL;
-	}
-	return 0;
+	if (port == 0)
+		return USB_INIT_DEVICE;
+	else
+		return USB_INIT_HOST;
 }
 #endif
diff --git a/board/seco/mx6quq7/mx6quq7.c b/board/seco/mx6quq7/mx6quq7.c
index e7523f1..08566fc 100644
--- a/board/seco/mx6quq7/mx6quq7.c
+++ b/board/seco/mx6quq7/mx6quq7.c
@@ -91,11 +91,30 @@
 	return ret;
 }
 
+#define USDHC4_CD_GPIO		IMX_GPIO_NR(2, 6)
+
 static struct fsl_esdhc_cfg usdhc_cfg[2] = {
-	{USDHC3_BASE_ADDR},
-	{USDHC2_BASE_ADDR},
+	{USDHC3_BASE_ADDR, 0, 4},
+	{USDHC4_BASE_ADDR, 0, 4},
 };
 
+int board_mmc_getcd(struct mmc *mmc)
+{
+	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	int ret = 0;
+
+	switch (cfg->esdhc_base) {
+	case USDHC3_BASE_ADDR:
+		ret = 1; /* Assume eMMC is always present */
+		break;
+	case USDHC4_BASE_ADDR:
+		ret = !gpio_get_value(USDHC4_CD_GPIO);
+		break;
+	}
+
+	return ret;
+}
+
 int board_mmc_init(bd_t *bis)
 {
 	u32 index = 0;
@@ -112,12 +131,10 @@
 		case 0:
 			seco_mx6_setup_usdhc_iomux(3);
 			usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
-			usdhc_cfg[0].max_bus_width = 4;
 			break;
 		case 1:
 			seco_mx6_setup_usdhc_iomux(4);
 			usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
-			usdhc_cfg[1].max_bus_width = 4;
 			break;
 
 		default:
diff --git a/board/tbs/tbs2910/tbs2910.c b/board/tbs/tbs2910/tbs2910.c
index 7707cf5..f159af9 100644
--- a/board/tbs/tbs2910/tbs2910.c
+++ b/board/tbs/tbs2910/tbs2910.c
@@ -257,6 +257,17 @@
 	}
 	return 0;
 }
+
+/* set environment device to boot device when booting from SD */
+int board_mmc_get_env_dev(int devno)
+{
+	return devno - 1;
+}
+
+int board_mmc_get_env_part(int devno)
+{
+	return (devno == 3) ? 1 : 0; /* part 0 for SD2 / SD3, part 1 for eMMC */
+}
 #endif /* CONFIG_FSL_ESDHC */
 
 #ifdef CONFIG_VIDEO_IPUV3
diff --git a/configs/mx7dsabresd_defconfig b/configs/mx7dsabresd_defconfig
index 420d13e..1d262c1 100644
--- a/configs/mx7dsabresd_defconfig
+++ b/configs/mx7dsabresd_defconfig
@@ -1,6 +1,8 @@
 CONFIG_ARM=y
 CONFIG_ARCH_MX7=y
 CONFIG_TARGET_MX7DSABRESD=y
+CONFIG_IMX_RDC=y
+CONFIG_IMX_BOOTAUX=y
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx7dsabresd/imximage.cfg,MX7D"
 # CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_IMI is not set
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index 5695bef..fd0c4f7 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -14,7 +14,7 @@
 #include "jobdesc.h"
 #include "rsa_caam.h"
 
-#ifdef CONFIG_MX6
+#if defined(CONFIG_MX6) || defined(CONFIG_MX7)
 /*!
  * Secure memory run command
  *
@@ -25,10 +25,14 @@
 {
 	uint32_t temp_reg;
 
-	sec_out32(CAAM_SMCJR0, sec_mem_cmd);
+	ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+	uint32_t sm_vid = SM_VERSION(sec_in32(&sec->smvid));
+	uint32_t jr_id = 0;
+
+	sec_out32(CAAM_SMCJR(sm_vid, jr_id), sec_mem_cmd);
 
 	do {
-		temp_reg = sec_in32(CAAM_SMCSJR0);
+		temp_reg = sec_in32(CAAM_SMCSJR(sm_vid, jr_id));
 	} while (temp_reg & CMD_COMPLETE);
 
 	return temp_reg;
@@ -51,6 +55,10 @@
 {
 	uint32_t temp_reg;
 
+	ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+	uint32_t sm_vid = SM_VERSION(sec_in32(&sec->smvid));
+	uint32_t jr_id = 0;
+
 	/*
 	 * De-Allocate partition_num if already allocated to ARM core
 	 */
@@ -64,9 +72,9 @@
 	}
 
 	/* set the access rights to allow full access */
-	sec_out32(CAAM_SMAG1JR0(partition_num), 0xF);
-	sec_out32(CAAM_SMAG2JR0(partition_num), 0xF);
-	sec_out32(CAAM_SMAPJR0(partition_num), 0xFF);
+	sec_out32(CAAM_SMAG1JR(sm_vid, jr_id, partition_num), 0xF);
+	sec_out32(CAAM_SMAG2JR(sm_vid, jr_id, partition_num), 0xF);
+	sec_out32(CAAM_SMAPJR(sm_vid, jr_id, partition_num), 0xFF);
 
 	/* Now need to allocate partition_num of secure RAM. */
 	/* De-Allocate page_num by starting with a page inquiry command */
@@ -105,6 +113,10 @@
 int inline_cnstr_jobdesc_blob_dek(uint32_t *desc, const uint8_t *plain_txt,
 				       uint8_t *dek_blob, uint32_t in_sz)
 {
+	ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+	uint32_t sm_vid = SM_VERSION(sec_in32(&sec->smvid));
+	uint32_t jr_id = 0;
+
 	uint32_t ret = 0;
 	u32 aad_w1, aad_w2;
 	/* output blob will have 32 bytes key blob in beginning and
@@ -133,9 +145,9 @@
 	flush_dcache_range(start, end);
 
 	/* Now configure the access rights of the partition */
-	sec_out32(CAAM_SMAG1JR0(PARTITION_1), KS_G1); /* set group 1 */
-	sec_out32(CAAM_SMAG2JR0(PARTITION_1), 0);     /* clear group 2 */
-	sec_out32(CAAM_SMAPJR0(PARTITION_1), PERM);   /* set perm & locks */
+	sec_out32(CAAM_SMAG1JR(sm_vid, jr_id, PARTITION_1), KS_G1);
+	sec_out32(CAAM_SMAG2JR(sm_vid, jr_id, PARTITION_1), 0);
+	sec_out32(CAAM_SMAPJR(sm_vid, jr_id, PARTITION_1), PERM);
 
 	/* construct aad for AES */
 	aad_w1 = (in_sz << OP_ALG_ALGSEL_SHIFT) | KEY_AES_SRC | LD_CCM_MODE;
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 5dd2ddd..2a69bab 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -143,6 +143,7 @@
 
 endif
 
+source "drivers/pinctrl/nxp/Kconfig"
 source "drivers/pinctrl/uniphier/Kconfig"
 
 endmenu
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index b4f4650..d7b6180 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -5,6 +5,7 @@
 obj-y					+= pinctrl-uclass.o
 obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC)	+= pinctrl-generic.o
 
+obj-y					+= nxp/
 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
 obj-$(CONFIG_PINCTRL_SANDBOX)	+= pinctrl-sandbox.o
 
diff --git a/drivers/pinctrl/nxp/Kconfig b/drivers/pinctrl/nxp/Kconfig
new file mode 100644
index 0000000..35640f0
--- /dev/null
+++ b/drivers/pinctrl/nxp/Kconfig
@@ -0,0 +1,30 @@
+config PINCTRL_IMX
+	bool
+
+config PINCTRL_IMX6
+	bool "IMX6 pinctrl driver"
+	depends on ARCH_MX6 && PINCTRL_FULL
+	select DEVRES
+	select PINCTRL_IMX
+	help
+	  Say Y here to enable the imx6 pinctrl driver
+
+	  This provides a simple pinctrl driver for i.MX6 SoC familiy,
+	  i.MX6DQ/SL/SX/UL/DQP. This feature depends on device tree
+	  configuration. This driver is different from the linux one,
+	  this is a simple implementation, only parses the 'fsl,pins'
+	  property and configure related registers.
+
+config PINCTRL_IMX7
+	bool "IMX7 pinctrl driver"
+	depends on ARCH_MX7 && PINCTRL_FULL
+	select DEVRES
+	select PINCTRL_IMX
+	help
+	  Say Y here to enable the imx7 pinctrl driver
+
+	  This provides a simple pinctrl driver for i.MX7 SoC familiy,
+	  i.MX7D. This feature depends on device tree
+	  configuration. This driver is different from the linux one,
+	  this is a simple implementation, only parses the 'fsl,pins'
+	  property and configure related registers.
diff --git a/drivers/pinctrl/nxp/Makefile b/drivers/pinctrl/nxp/Makefile
new file mode 100644
index 0000000..0ee7f2f
--- /dev/null
+++ b/drivers/pinctrl/nxp/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_PINCTRL_IMX)		+= pinctrl-imx.o
+obj-$(CONFIG_PINCTRL_IMX6)		+= pinctrl-imx6.o
+obj-$(CONFIG_PINCTRL_IMX7)		+= pinctrl-imx7.o
diff --git a/drivers/pinctrl/nxp/pinctrl-imx.c b/drivers/pinctrl/nxp/pinctrl-imx.c
new file mode 100644
index 0000000..40b0616
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <mapmem.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <dm/device.h>
+#include <dm/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int imx_pinctrl_set_state(struct udevice *dev, struct udevice *config)
+{
+	struct imx_pinctrl_priv *priv = dev_get_priv(dev);
+	struct imx_pinctrl_soc_info *info = priv->info;
+	int node = config->of_offset;
+	const struct fdt_property *prop;
+	u32 *pin_data;
+	int npins, size, pin_size;
+	int mux_reg, conf_reg, input_reg, input_val, mux_mode, config_val;
+	int i, j = 0;
+
+	dev_dbg(dev, "%s: %s\n", __func__, config->name);
+
+	if (info->flags & SHARE_MUX_CONF_REG)
+		pin_size = SHARE_FSL_PIN_SIZE;
+	else
+		pin_size = FSL_PIN_SIZE;
+
+	prop = fdt_getprop(gd->fdt_blob, node, "fsl,pins", &size);
+	if (!prop) {
+		dev_err(dev, "No fsl,pins property in node %s\n", config->name);
+		return -EINVAL;
+	}
+
+	if (!size || size % pin_size) {
+		dev_err(dev, "Invalid fsl,pins property in node %s\n",
+			config->name);
+		return -EINVAL;
+	}
+
+	pin_data = devm_kzalloc(dev, size, 0);
+	if (!pin_data)
+		return -ENOMEM;
+
+	if (fdtdec_get_int_array(gd->fdt_blob, node, "fsl,pins",
+				 pin_data, size >> 2)) {
+		dev_err(dev, "Error reading pin data.\n");
+		return -EINVAL;
+	}
+
+	npins = size / pin_size;
+
+	/*
+	 * Refer to linux documentation for details:
+	 * Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
+	 */
+	for (i = 0; i < npins; i++) {
+		mux_reg = pin_data[j++];
+
+		if (!(info->flags & ZERO_OFFSET_VALID) && !mux_reg)
+			mux_reg = -1;
+
+		if (info->flags & SHARE_MUX_CONF_REG) {
+			conf_reg = mux_reg;
+		} else {
+			conf_reg = pin_data[j++];
+			if (!(info->flags & ZERO_OFFSET_VALID) && !conf_reg)
+				conf_reg = -1;
+		}
+
+		if ((mux_reg == -1) || (conf_reg == -1)) {
+			dev_err(dev, "Error mux_reg or conf_reg\n");
+			return -EINVAL;
+		}
+
+		input_reg = pin_data[j++];
+		mux_mode = pin_data[j++];
+		input_val = pin_data[j++];
+		config_val = pin_data[j++];
+
+		dev_dbg(dev, "mux_reg 0x%x, conf_reg 0x%x, input_reg 0x%x, "
+			"mux_mode 0x%x, input_val 0x%x, config_val 0x%x\n",
+			mux_reg, conf_reg, input_reg, mux_mode, input_val,
+			config_val);
+
+		if (config_val & IMX_PAD_SION)
+			mux_mode |= IOMUXC_CONFIG_SION;
+
+		config_val &= ~IMX_PAD_SION;
+
+		/* Set Mux */
+		if (info->flags & SHARE_MUX_CONF_REG) {
+			clrsetbits_le32(info->base + mux_reg, 0x7 << 20,
+					mux_mode << 20);
+		} else {
+			writel(mux_mode, info->base + mux_reg);
+		}
+
+		dev_dbg(dev, "write mux: offset 0x%x val 0x%x\n", mux_reg,
+			mux_mode);
+
+		/*
+		 * Set select input
+		 *
+		 * If the select input value begins with 0xff, it's a quirky
+		 * select input and the value should be interpreted as below.
+		 *     31     23      15      7        0
+		 *     | 0xff | shift | width | select |
+		 * It's used to work around the problem that the select
+		 * input for some pin is not implemented in the select
+		 * input register but in some general purpose register.
+		 * We encode the select input value, width and shift of
+		 * the bit field into input_val cell of pin function ID
+		 * in device tree, and then decode them here for setting
+		 * up the select input bits in general purpose register.
+		 */
+
+		if (input_val >> 24 == 0xff) {
+			u32 val = input_val;
+			u8 select = val & 0xff;
+			u8 width = (val >> 8) & 0xff;
+			u8 shift = (val >> 16) & 0xff;
+			u32 mask = ((1 << width) - 1) << shift;
+			/*
+			 * The input_reg[i] here is actually some IOMUXC general
+			 * purpose register, not regular select input register.
+			 */
+			val = readl(info->base + input_reg);
+			val &= ~mask;
+			val |= select << shift;
+			writel(val, info->base + input_reg);
+		} else if (input_reg) {
+			/*
+			 * Regular select input register can never be at offset
+			 * 0, and we only print register value for regular case.
+			 */
+			if (info->input_sel_base)
+				writel(input_val, info->input_sel_base +
+				       input_reg);
+			else
+				writel(input_val, info->base + input_reg);
+
+			dev_dbg(dev, "select_input: offset 0x%x val 0x%x\n",
+				input_reg, input_val);
+		}
+
+		/* Set config */
+		if (!(config_val & IMX_NO_PAD_CTL)) {
+			if (info->flags & SHARE_MUX_CONF_REG) {
+				clrsetbits_le32(info->base + conf_reg, 0xffff,
+						config_val);
+			} else {
+				writel(config_val, info->base + conf_reg);
+			}
+
+			dev_dbg(dev, "write config: offset 0x%x val 0x%x\n",
+				conf_reg, config_val);
+		}
+	}
+
+	return 0;
+}
+
+const struct pinctrl_ops imx_pinctrl_ops  = {
+	.set_state = imx_pinctrl_set_state,
+};
+
+int imx_pinctrl_probe(struct udevice *dev,
+		      struct imx_pinctrl_soc_info *info)
+{
+	struct imx_pinctrl_priv *priv = dev_get_priv(dev);
+	int node = dev->of_offset, ret;
+	struct fdtdec_phandle_args arg;
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	if (!info) {
+		dev_err(dev, "wrong pinctrl info\n");
+		return -EINVAL;
+	}
+
+	priv->dev = dev;
+	priv->info = info;
+
+	addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
+
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	info->base = map_sysmem(addr, size);
+	if (!info->base)
+		return -ENOMEM;
+	priv->info = info;
+
+	/*
+	 * Refer to linux documentation for details:
+	 * Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt
+	 */
+	if (fdtdec_get_bool(gd->fdt_blob, node, "fsl,input-sel")) {
+		ret = fdtdec_parse_phandle_with_args(gd->fdt_blob,
+						     node, "fsl,input-sel",
+						     NULL, 0, 0, &arg);
+		if (ret) {
+			dev_err(dev, "iomuxc fsl,input-sel property not found\n");
+			return -EINVAL;
+		}
+
+		addr = fdtdec_get_addr_size(gd->fdt_blob, arg.node, "reg",
+					    &size);
+		if (addr == FDT_ADDR_T_NONE)
+			return -EINVAL;
+
+		info->input_sel_base = map_sysmem(addr, size);
+		if (!info->input_sel_base)
+			return -ENOMEM;
+	}
+
+	dev_info(dev, "initialized IMX pinctrl driver\n");
+
+	return 0;
+}
+
+int imx_pinctrl_remove(struct udevice *dev)
+{
+	struct imx_pinctrl_priv *priv = dev_get_priv(dev);
+	struct imx_pinctrl_soc_info *info = priv->info;
+
+	if (info->input_sel_base)
+		unmap_sysmem(info->input_sel_base);
+	if (info->base)
+		unmap_sysmem(info->base);
+
+	return 0;
+}
diff --git a/drivers/pinctrl/nxp/pinctrl-imx.h b/drivers/pinctrl/nxp/pinctrl-imx.h
new file mode 100644
index 0000000..037c491
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DRIVERS_PINCTRL_IMX_H
+#define __DRIVERS_PINCTRL_IMX_H
+
+/**
+ * @base: the address to the controller in virtual memory
+ * @input_sel_base: the address of the select input in virtual memory.
+ * @flags: flags specific for each soc
+ */
+struct imx_pinctrl_soc_info {
+	void __iomem *base;
+	void __iomem *input_sel_base;
+	unsigned int flags;
+};
+
+/**
+ * @dev: a pointer back to containing device
+ * @info: the soc info
+ */
+struct imx_pinctrl_priv {
+	struct udevice *dev;
+	struct imx_pinctrl_soc_info *info;
+};
+
+extern const struct pinctrl_ops imx_pinctrl_ops;
+
+#define IMX_NO_PAD_CTL	0x80000000	/* no pin config need */
+#define IMX_PAD_SION	0x40000000	/* set SION */
+
+/*
+ * Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and
+ * 1 u32 CONFIG, so 24 types in total for each pin.
+ */
+#define FSL_PIN_SIZE		24
+#define SHARE_FSL_PIN_SIZE	20
+
+#define SHARE_MUX_CONF_REG	0x1
+#define ZERO_OFFSET_VALID	0x2
+
+#define IOMUXC_CONFIG_SION	(0x1 << 4)
+
+int imx_pinctrl_probe(struct udevice *dev, struct imx_pinctrl_soc_info *info);
+
+int imx_pinctrl_remove(struct udevice *dev);
+#endif /* __DRIVERS_PINCTRL_IMX_H */
diff --git a/drivers/pinctrl/nxp/pinctrl-imx6.c b/drivers/pinctrl/nxp/pinctrl-imx6.c
new file mode 100644
index 0000000..24f139e
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx6.c
@@ -0,0 +1,41 @@
+
+/*
+ * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dm/device.h>
+#include <dm/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+static struct imx_pinctrl_soc_info imx6_pinctrl_soc_info;
+
+static int imx6_pinctrl_probe(struct udevice *dev)
+{
+	struct imx_pinctrl_soc_info *info =
+		(struct imx_pinctrl_soc_info *)dev_get_driver_data(dev);
+
+	return imx_pinctrl_probe(dev, info);
+}
+
+static const struct udevice_id imx6_pinctrl_match[] = {
+	{ .compatible = "fsl,imx6q-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
+	{ .compatible = "fsl,imx6dl-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
+	{ .compatible = "fsl,imx6sl-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
+	{ .compatible = "fsl,imx6sx-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
+	{ .compatible = "fsl,imx6ul-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(imx6_pinctrl) = {
+	.name = "imx6-pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = of_match_ptr(imx6_pinctrl_match),
+	.probe = imx6_pinctrl_probe,
+	.remove = imx_pinctrl_remove,
+	.priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
+	.ops = &imx_pinctrl_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx7.c b/drivers/pinctrl/nxp/pinctrl-imx7.c
new file mode 100644
index 0000000..eeb7942
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx7.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dm/device.h>
+#include <dm/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info;
+
+static struct imx_pinctrl_soc_info imx7_lpsr_pinctrl_soc_info = {
+	.flags = ZERO_OFFSET_VALID,
+};
+
+static int imx7_pinctrl_probe(struct udevice *dev)
+{
+	struct imx_pinctrl_soc_info *info =
+		(struct imx_pinctrl_soc_info *)dev_get_driver_data(dev);
+
+	return imx_pinctrl_probe(dev, info);
+}
+
+static const struct udevice_id imx7_pinctrl_match[] = {
+	{ .compatible = "fsl,imx7d-iomuxc", .data = (ulong)&imx7_pinctrl_soc_info },
+	{ .compatible = "fsl,imx7d-iomuxc-lpsr", .data = (ulong)&imx7_lpsr_pinctrl_soc_info },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(imx7_pinctrl) = {
+	.name = "imx7-pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = of_match_ptr(imx7_pinctrl_match),
+	.probe = imx7_pinctrl_probe,
+	.remove = imx_pinctrl_remove,
+	.priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
+	.ops = &imx_pinctrl_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h
index 29e9c08..fdf2396 100644
--- a/include/configs/mx6sxsabresd.h
+++ b/include/configs/mx6sxsabresd.h
@@ -26,7 +26,31 @@
 #define CONFIG_MXC_UART
 #define CONFIG_MXC_UART_BASE		UART1_BASE
 
+#ifdef CONFIG_IMX_BOOTAUX
+/* Set to QSPI2 B flash at default */
+#define CONFIG_SYS_AUXCORE_BOOTDATA 0x78000000
+#define CONFIG_CMD_SETEXPR
+
+#define UPDATE_M4_ENV \
+	"m4image=m4_qspi.bin\0" \
+	"loadm4image=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4image}\0" \
+	"update_m4_from_sd=" \
+		"if sf probe 1:0; then " \
+			"if run loadm4image; then " \
+				"setexpr fw_sz ${filesize} + 0xffff; " \
+				"setexpr fw_sz ${fw_sz} / 0x10000; "	\
+				"setexpr fw_sz ${fw_sz} * 0x10000; "	\
+				"sf erase 0x0 ${fw_sz}; " \
+				"sf write ${loadaddr} 0x0 ${filesize}; " \
+			"fi; " \
+		"fi\0" \
+	"m4boot=sf probe 1:0; bootaux "__stringify(CONFIG_SYS_AUXCORE_BOOTDATA)"\0"
+#else
+#define UPDATE_M4_ENV ""
+#endif
+
 #define CONFIG_EXTRA_ENV_SETTINGS \
+	UPDATE_M4_ENV \
 	"script=boot.scr\0" \
 	"image=zImage\0" \
 	"console=ttymxc0\0" \
diff --git a/include/configs/mx6ul_14x14_evk.h b/include/configs/mx6ul_14x14_evk.h
index 4374c3a..c7e10f9 100644
--- a/include/configs/mx6ul_14x14_evk.h
+++ b/include/configs/mx6ul_14x14_evk.h
@@ -195,6 +195,7 @@
 #define CONFIG_CMD_CACHE
 #endif
 
+#define CONFIG_FSL_QSPI
 #ifdef CONFIG_FSL_QSPI
 #define CONFIG_CMD_SF
 #define CONFIG_SPI_FLASH
diff --git a/include/configs/mx7dsabresd.h b/include/configs/mx7dsabresd.h
index d23e4f3..2c981e0 100644
--- a/include/configs/mx7dsabresd.h
+++ b/include/configs/mx7dsabresd.h
@@ -57,6 +57,29 @@
 #define CONFIG_SUPPORT_EMMC_BOOT	/* eMMC specific */
 #define CONFIG_SYS_MMC_IMG_LOAD_PART	1
 
+#ifdef CONFIG_IMX_BOOTAUX
+/* Set to QSPI1 A flash at default */
+#define CONFIG_SYS_AUXCORE_BOOTDATA 0x60000000
+#define CONFIG_CMD_SETEXPR
+
+#define UPDATE_M4_ENV \
+	"m4image=m4_qspi.bin\0" \
+	"loadm4image=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4image}\0" \
+	"update_m4_from_sd=" \
+		"if sf probe 0:0; then " \
+			"if run loadm4image; then " \
+				"setexpr fw_sz ${filesize} + 0xffff; " \
+				"setexpr fw_sz ${fw_sz} / 0x10000; "	\
+				"setexpr fw_sz ${fw_sz} * 0x10000; "	\
+				"sf erase 0x0 ${fw_sz}; " \
+				"sf write ${loadaddr} 0x0 ${filesize}; " \
+			"fi; " \
+		"fi\0" \
+	"m4boot=sf probe 0:0; bootaux "__stringify(CONFIG_SYS_AUXCORE_BOOTDATA)"\0"
+#else
+#define UPDATE_M4_ENV ""
+#endif
+
 #define CONFIG_MFG_ENV_SETTINGS \
 	"mfgtool_args=setenv bootargs console=${console},${baudrate} " \
 		"rdinit=/linuxrc " \
@@ -76,6 +99,7 @@
 		"rootfs part 0 2\0" \
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
+	UPDATE_M4_ENV \
 	CONFIG_MFG_ENV_SETTINGS \
 	CONFIG_DFU_ENV_SETTINGS \
 	"script=boot.scr\0" \
diff --git a/include/configs/tbs2910.h b/include/configs/tbs2910.h
index 17b0213..0f23034 100644
--- a/include/configs/tbs2910.h
+++ b/include/configs/tbs2910.h
@@ -176,8 +176,8 @@
 
 /* Environment organization */
 #define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_SYS_MMC_ENV_DEV		2
-#define CONFIG_SYS_MMC_ENV_PART		1
+#define CONFIG_SYS_MMC_ENV_DEV		2 /* overwritten on SD boot */
+#define CONFIG_SYS_MMC_ENV_PART		1 /* overwritten on SD boot */
 #define CONFIG_ENV_SIZE			(8 * 1024)
 #define CONFIG_ENV_OFFSET		(384 * 1024)
 #define CONFIG_ENV_OVERWRITE
diff --git a/include/fsl_sec.h b/include/fsl_sec.h
index 2ddced3..a52110a 100644
--- a/include/fsl_sec.h
+++ b/include/fsl_sec.h
@@ -97,19 +97,20 @@
 	u32	drr;		/* DECO Reset Register */
 	u8	res5[0x4d8];
 	struct rng4tst rng;	/* RNG Registers */
-	u8	res11[0x8a0];
+	u8	res6[0x8a0];
 	u32	crnr_ms;	/* CHA Revision Number Register, MS */
 	u32	crnr_ls;	/* CHA Revision Number Register, LS */
 	u32	ctpr_ms;	/* Compile Time Parameters Register, MS */
 	u32	ctpr_ls;	/* Compile Time Parameters Register, LS */
-	u8	res6[0x10];
+	u8	res7[0x10];
 	u32	far_ms;		/* Fault Address Register, MS */
 	u32	far_ls;		/* Fault Address Register, LS */
 	u32	falr;		/* Fault Address LIODN Register */
 	u32	fadr;		/* Fault Address Detail Register */
-	u8	res7[0x4];
+	u8	res8[0x4];
 	u32	csta;		/* CAAM Status Register */
-	u8	res8[0x8];
+	u32	smpart;		/* Secure Memory Partition Parameters */
+	u32	smvid;		/* Secure Memory Version ID */
 	u32	rvid;		/* Run Time Integrity Checking Version ID Reg.*/
 	u32	ccbvid;		/* CHA Cluster Block Version ID Register */
 	u32	chavid_ms;	/* CHA Version ID Register, MS */
@@ -147,7 +148,8 @@
 #define CONFIG_JRSTARTR_JR0		0x00000001
 
 struct jr_regs {
-#if defined(CONFIG_SYS_FSL_SEC_LE) && !defined(CONFIG_MX6)
+#if defined(CONFIG_SYS_FSL_SEC_LE) && \
+	!(defined(CONFIG_MX6) || defined(CONFIG_MX7))
 	u32 irba_l;
 	u32 irba_h;
 #else
@@ -160,7 +162,8 @@
 	u32 irsa;
 	u32 rsvd3;
 	u32 irja;
-#if defined(CONFIG_SYS_FSL_SEC_LE) && !defined(CONFIG_MX6)
+#if defined(CONFIG_SYS_FSL_SEC_LE) && \
+	!(defined(CONFIG_MX6) || defined(CONFIG_MX7))
 	u32 orba_l;
 	u32 orba_h;
 #else
@@ -192,7 +195,8 @@
  * related information
  */
 struct sg_entry {
-#if defined(CONFIG_SYS_FSL_SEC_LE) && !defined(CONFIG_MX6)
+#if defined(CONFIG_SYS_FSL_SEC_LE) && \
+	!(defined(CONFIG_MX6) || defined(CONFIG_MX7))
 	uint32_t addr_lo;	/* Memory Address - lo */
 	uint32_t addr_hi;	/* Memory Address of start of buffer - hi */
 #else
@@ -211,26 +215,43 @@
 #define SG_ENTRY_OFFSET_SHIFT	0
 };
 
-#ifdef CONFIG_MX6
+#if defined(CONFIG_MX6) || defined(CONFIG_MX7)
+/* Job Ring Base Address */
+#define JR_BASE_ADDR(x) (CONFIG_SYS_FSL_SEC_ADDR + 0x1000 * (x + 1))
+/* Secure Memory Offset varies accross versions */
+#define SM_V1_OFFSET 0x0f4
+#define SM_V2_OFFSET 0xa00
+/*Secure Memory Versioning */
+#define SMVID_V2 0x20105
+#define SM_VERSION(x)  (x < SMVID_V2 ? 1 : 2)
+#define SM_OFFSET(x)  (x == 1 ? SM_V1_OFFSET : SM_V2_OFFSET)
 /* CAAM Job Ring 0 Registers */
 /* Secure Memory Partition Owner register */
 #define SMCSJR_PO		(3 << 6)
 /* JR Allocation Error */
 #define SMCSJR_AERR		(3 << 12)
 /* Secure memory partition 0 page 0 owner register */
-#define CAAM_SMPO_0		CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC
+#define CAAM_SMPO_0	    (CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC)
 /* Secure memory command register */
-#define CAAM_SMCJR0		CONFIG_SYS_FSL_SEC_ADDR + 0x10f4
+#define CAAM_SMCJR(v, jr)   (JR_BASE_ADDR(jr) + SM_OFFSET(v) + SM_CMD(v))
 /* Secure memory command status register */
-#define CAAM_SMCSJR0		CONFIG_SYS_FSL_SEC_ADDR + 0x10fc
+#define CAAM_SMCSJR(v, jr)  (JR_BASE_ADDR(jr) + SM_OFFSET(v) + SM_STATUS(v))
 /* Secure memory access permissions register */
-#define CAAM_SMAPJR0(y)	(CONFIG_SYS_FSL_SEC_ADDR + 0x1104 + y*16)
+#define CAAM_SMAPJR(v, jr, y) \
+	(JR_BASE_ADDR(jr) + SM_OFFSET(v) + SM_PERM(v) + y * 16)
 /* Secure memory access group 2 register */
-#define CAAM_SMAG2JR0(y)	(CONFIG_SYS_FSL_SEC_ADDR + 0x1108 + y*16)
+#define CAAM_SMAG2JR(v, jr, y) \
+	(JR_BASE_ADDR(jr) + SM_OFFSET(v) + SM_GROUP2(v) + y * 16)
 /* Secure memory access group 1 register */
-#define CAAM_SMAG1JR0(y)	(CONFIG_SYS_FSL_SEC_ADDR + 0x110C + y*16)
+#define CAAM_SMAG1JR(v, jr, y)  \
+	(JR_BASE_ADDR(jr) + SM_OFFSET(v) + SM_GROUP1(v) + y * 16)
 
 /* Commands and macros for secure memory */
+#define SM_CMD(v)		(v == 1 ? 0x0 : 0x1E4)
+#define SM_STATUS(v)		(v == 1 ? 0x8 : 0x1EC)
+#define SM_PERM(v)		(v == 1 ?  0x10 : 0x4)
+#define SM_GROUP2(v)		(v == 1 ? 0x14 : 0x8)
+#define SM_GROUP1(v)		(v == 1 ? 0x18 : 0xC)
 #define CMD_PAGE_ALLOC		0x1
 #define CMD_PAGE_DEALLOC	0x2
 #define CMD_PART_DEALLOC	0x3
diff --git a/tools/mxsboot.c b/tools/mxsboot.c
index 457f435..2e72009 100644
--- a/tools/mxsboot.c
+++ b/tools/mxsboot.c
@@ -7,7 +7,6 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-#include <endian.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/types.h>