armv8: s32v234: Introduce basic support for s32v234evb

Add initial support for NXP's S32V234 SoC and S32V234EVB board.

The S32V230 family is designed to support computation-intensive applications
for image processing. The S32V234, as part of the S32V230 family, is a
high-performance automotive processor designed to support safe
computation-intensive applications in the area of vision and sensor fusion.

Code originally writen by:
Original-signed-off-by: Stoica Cosmin-Stefan <cosminstefan.stoica@freescale.com>
Original-signed-off-by: Mihaela Martinas <Mihaela.Martinas@freescale.com>
Original-signed-off-by: Eddy Petrișor <eddy.petrisor@gmail.com>

Signed-off-by: Eddy Petrișor <eddy.petrisor@nxp.com>
diff --git a/board/freescale/s32v234evb/Kconfig b/board/freescale/s32v234evb/Kconfig
new file mode 100644
index 0000000..e71dfc4
--- /dev/null
+++ b/board/freescale/s32v234evb/Kconfig
@@ -0,0 +1,23 @@
+if TARGET_S32V234EVB
+
+config SYS_CPU
+	string
+	default "armv8"
+
+config SYS_BOARD
+	string
+	default "s32v234evb"
+
+config SYS_VENDOR
+	string
+	default "freescale"
+
+config SYS_SOC
+	string
+	default "s32v234"
+
+config SYS_CONFIG_NAME
+	string
+	default "s32v234evb"
+
+endif
diff --git a/board/freescale/s32v234evb/MAINTAINERS b/board/freescale/s32v234evb/MAINTAINERS
new file mode 100644
index 0000000..62b2e1b
--- /dev/null
+++ b/board/freescale/s32v234evb/MAINTAINERS
@@ -0,0 +1,8 @@
+S32V234 Evaluation BOARD
+M:	Eddy Petrișor <eddy.petrisor@gmail.com>
+S:	Maintained
+F:	arch/arm/cpu/armv8/s32v234/
+F:	arch/arm/include/asm/arch-s32v234/
+F:	board/freescale/s32v234evb/
+F:	include/configs/s32v234evb.h
+F:	configs/s32v234evb_defconfig
diff --git a/board/freescale/s32v234evb/Makefile b/board/freescale/s32v234evb/Makefile
new file mode 100644
index 0000000..69e6d3e
--- /dev/null
+++ b/board/freescale/s32v234evb/Makefile
@@ -0,0 +1,11 @@
+#
+# (C) Copyright 2013-2015, Freescale Semiconductor, Inc.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y   := clock.o
+obj-y   += lpddr2.o
+obj-y   += s32v234evb.o
+
+#########################################################################
diff --git a/board/freescale/s32v234evb/clock.c b/board/freescale/s32v234evb/clock.c
new file mode 100644
index 0000000..d218c21
--- /dev/null
+++ b/board/freescale/s32v234evb/clock.c
@@ -0,0 +1,344 @@
+/*
+ * (C) Copyright 2015, Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/mc_cgm_regs.h>
+#include <asm/arch/mc_me_regs.h>
+#include <asm/arch/clock.h>
+
+/*
+ * Select the clock reference for required pll.
+ * pll - ARM_PLL, PERIPH_PLL, ENET_PLL, DDR_PLL, VIDEO_PLL.
+ * refclk_freq - input referece clock frequency (FXOSC - 40 MHZ, FIRC - 48 MHZ)
+ */
+static int select_pll_source_clk(enum pll_type pll, u32 refclk_freq)
+{
+	u32 clk_src;
+	u32 pll_idx;
+	volatile struct src *src = (struct src *)SRC_SOC_BASE_ADDR;
+
+	/* select the pll clock source */
+	switch (refclk_freq) {
+	case FIRC_CLK_FREQ:
+		clk_src = SRC_GPR1_FIRC_CLK_SOURCE;
+		break;
+	case XOSC_CLK_FREQ:
+		clk_src = SRC_GPR1_XOSC_CLK_SOURCE;
+		break;
+	default:
+		/* The clock frequency for the source clock is unknown */
+		return -1;
+	}
+	/*
+	 * The hardware definition is not uniform, it has to calculate again
+	 * the recurrence formula.
+	 */
+	switch (pll) {
+	case PERIPH_PLL:
+		pll_idx = 3;
+		break;
+	case ENET_PLL:
+		pll_idx = 1;
+		break;
+	case DDR_PLL:
+		pll_idx = 2;;
+		break;
+	default:
+		pll_idx = pll;
+	}
+
+	writel(readl(&src->gpr1) | SRC_GPR1_PLL_SOURCE(pll_idx, clk_src),
+	       &src->gpr1);
+
+	return 0;
+}
+
+static void entry_to_target_mode(u32 mode)
+{
+	writel(mode | MC_ME_MCTL_KEY, MC_ME_MCTL);
+	writel(mode | MC_ME_MCTL_INVERTEDKEY, MC_ME_MCTL);
+	while ((readl(MC_ME_GS) & MC_ME_GS_S_MTRANS) != 0x00000000) ;
+}
+
+/*
+ * Program the pll according to the input parameters.
+ * pll - ARM_PLL, PERIPH_PLL, ENET_PLL, DDR_PLL, VIDEO_PLL.
+ * refclk_freq - input reference clock frequency (FXOSC - 40 MHZ, FIRC - 48 MHZ)
+ * freq - expected output frequency for PHY0
+ * freq1 - expected output frequency for PHY1
+ * dfs_nr - number of DFS modules for current PLL
+ * dfs - array with the activation dfs field, mfn and mfi
+ * plldv_prediv - divider of clkfreq_ref
+ * plldv_mfd - loop multiplication factor divider
+ * pllfd_mfn - numerator loop multiplication factor divider
+ * Please consult the PLLDIG chapter of platform manual
+ * before to use this function.
+ *)
+ */
+static int program_pll(enum pll_type pll, u32 refclk_freq, u32 freq0, u32 freq1,
+		       u32 dfs_nr, u32 dfs[][DFS_PARAMS_Nr], u32 plldv_prediv,
+		       u32 plldv_mfd, u32 pllfd_mfn)
+{
+	u32 i, rfdphi1, rfdphi, dfs_on = 0, fvco;
+
+	/*
+	 * This formula is from platform reference manual (Rev. 1, 6/2015), PLLDIG chapter.
+	 */
+	fvco =
+	    (refclk_freq / plldv_prediv) * (plldv_mfd +
+					    pllfd_mfn / (float)20480);
+
+	/*
+	 * VCO should have value in [ PLL_MIN_FREQ, PLL_MAX_FREQ ]. Please consult
+	 * the platform DataSheet in order to determine the allowed values.
+	 */
+
+	if (fvco < PLL_MIN_FREQ || fvco > PLL_MAX_FREQ) {
+		return -1;
+	}
+
+	if (select_pll_source_clk(pll, refclk_freq) < 0) {
+		return -1;
+	}
+
+	rfdphi = fvco / freq0;
+
+	rfdphi1 = (freq1 == 0) ? 0 : fvco / freq1;
+
+	writel(PLLDIG_PLLDV_RFDPHI1_SET(rfdphi1) |
+	       PLLDIG_PLLDV_RFDPHI_SET(rfdphi) |
+	       PLLDIG_PLLDV_PREDIV_SET(plldv_prediv) |
+	       PLLDIG_PLLDV_MFD(plldv_mfd), PLLDIG_PLLDV(pll));
+
+	writel(readl(PLLDIG_PLLFD(pll)) | PLLDIG_PLLFD_MFN_SET(pllfd_mfn) |
+	       PLLDIG_PLLFD_SMDEN, PLLDIG_PLLFD(pll));
+
+	/* switch on the pll in current mode */
+	writel(readl(MC_ME_RUNn_MC(0)) | MC_ME_RUNMODE_MC_PLL(pll),
+	       MC_ME_RUNn_MC(0));
+
+	entry_to_target_mode(MC_ME_MCTL_RUN0);
+
+	/* Only ARM_PLL, ENET_PLL and DDR_PLL */
+	if ((pll == ARM_PLL) || (pll == ENET_PLL) || (pll == DDR_PLL)) {
+		/* DFS clk enable programming */
+		writel(DFS_CTRL_DLL_RESET, DFS_CTRL(pll));
+
+		writel(DFS_DLLPRG1_CPICTRL_SET(0x5) |
+		       DFS_DLLPRG1_VSETTLCTRL_SET(0x1) |
+		       DFS_DLLPRG1_CALBYPEN_SET(0x0) |
+		       DFS_DLLPRG1_DACIN_SET(0x1) | DFS_DLLPRG1_LCKWT_SET(0x0) |
+		       DFS_DLLPRG1_V2IGC_SET(0x5), DFS_DLLPRG1(pll));
+
+		for (i = 0; i < dfs_nr; i++) {
+			if (dfs[i][0]) {
+				writel(DFS_DVPORTn_MFI_SET(dfs[i][2]) |
+				       DFS_DVPORTn_MFN_SET(dfs[i][1]),
+				       DFS_DVPORTn(pll, i));
+				dfs_on |= (dfs[i][0] << i);
+			}
+		}
+
+		writel(readl(DFS_CTRL(pll)) & ~DFS_CTRL_DLL_RESET,
+		       DFS_CTRL(pll));
+		writel(readl(DFS_PORTRESET(pll)) &
+		       ~DFS_PORTRESET_PORTRESET_SET(dfs_on),
+		       DFS_PORTRESET(pll));
+		while ((readl(DFS_PORTSR(pll)) & dfs_on) != dfs_on) ;
+	}
+
+	entry_to_target_mode(MC_ME_MCTL_RUN0);
+
+	return 0;
+
+}
+
+static void aux_source_clk_config(uintptr_t cgm_addr, u8 ac, u32 source)
+{
+	/* select the clock source */
+	writel(MC_CGM_ACn_SEL_SET(source), CGM_ACn_SC(cgm_addr, ac));
+}
+
+static void aux_div_clk_config(uintptr_t cgm_addr, u8 ac, u8 dc, u32 divider)
+{
+	/* set the divider */
+	writel(MC_CGM_ACn_DCm_DE | MC_CGM_ACn_DCm_PREDIV(divider),
+	       CGM_ACn_DCm(cgm_addr, ac, dc));
+}
+
+static void setup_sys_clocks(void)
+{
+
+	/* set ARM PLL DFS 1 as SYSCLK */
+	writel((readl(MC_ME_RUNn_MC(0)) & ~MC_ME_RUNMODE_MC_SYSCLK_MASK) |
+	       MC_ME_RUNMODE_MC_SYSCLK(0x2), MC_ME_RUNn_MC(0));
+
+	entry_to_target_mode(MC_ME_MCTL_RUN0);
+
+	/* select sysclks  ARMPLL, ARMPLLDFS2, ARMPLLDFS3 */
+	writel(MC_ME_RUNMODE_SEC_CC_I_SYSCLK
+	       (0x2,
+		MC_ME_RUNMODE_SEC_CC_I_SYSCLK1_OFFSET) |
+	       MC_ME_RUNMODE_SEC_CC_I_SYSCLK(0x2,
+					     MC_ME_RUNMODE_SEC_CC_I_SYSCLK2_OFFSET)
+	       | MC_ME_RUNMODE_SEC_CC_I_SYSCLK(0x2,
+					       MC_ME_RUNMODE_SEC_CC_I_SYSCLK3_OFFSET),
+	       MC_ME_RUNn_SEC_CC_I(0));
+
+	/* setup the sys clock divider for CORE_CLK (1000MHz) */
+	writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x0),
+	       CGM_SC_DCn(MC_CGM1_BASE_ADDR, 0));
+
+	/* setup the sys clock divider for CORE2_CLK (500MHz) */
+	writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x1),
+	       CGM_SC_DCn(MC_CGM1_BASE_ADDR, 1));
+	/* setup the sys clock divider for SYS3_CLK (266 MHz) */
+	writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x0),
+	       CGM_SC_DCn(MC_CGM0_BASE_ADDR, 0));
+
+	/* setup the sys clock divider for SYS6_CLK (133 Mhz) */
+	writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x1),
+	       CGM_SC_DCn(MC_CGM0_BASE_ADDR, 1));
+
+	entry_to_target_mode(MC_ME_MCTL_RUN0);
+
+}
+
+static void setup_aux_clocks(void)
+{
+	/*
+	 * setup the aux clock divider for PERI_CLK
+	 * (source: PERIPH_PLL_PHI_0/5, PERI_CLK - 80 MHz)
+	 */
+	aux_source_clk_config(MC_CGM0_BASE_ADDR, 5, MC_CGM_ACn_SEL_PERPLLDIVX);
+	aux_div_clk_config(MC_CGM0_BASE_ADDR, 5, 0, 4);
+
+	/* setup the aux clock divider for LIN_CLK (40MHz) */
+	aux_source_clk_config(MC_CGM0_BASE_ADDR, 3, MC_CGM_ACn_SEL_PERPLLDIVX);
+	aux_div_clk_config(MC_CGM0_BASE_ADDR, 3, 0, 1);
+
+	/* setup the aux clock divider for ENET_TIME_CLK (50MHz) */
+	aux_source_clk_config(MC_CGM0_BASE_ADDR, 7, MC_CGM_ACn_SEL_ENETPLL);
+	aux_div_clk_config(MC_CGM0_BASE_ADDR, 7, 1, 9);
+
+	/* setup the aux clock divider for ENET_CLK (50MHz) */
+	aux_source_clk_config(MC_CGM2_BASE_ADDR, 2, MC_CGM_ACn_SEL_ENETPLL);
+	aux_div_clk_config(MC_CGM2_BASE_ADDR, 2, 0, 9);
+
+	/* setup the aux clock divider for SDHC_CLK (50 MHz). */
+	aux_source_clk_config(MC_CGM0_BASE_ADDR, 15, MC_CGM_ACn_SEL_ENETPLL);
+	aux_div_clk_config(MC_CGM0_BASE_ADDR, 15, 0, 9);
+
+	/* setup the aux clock divider for DDR_CLK (533MHz) and APEX_SYS_CLK (266MHz) */
+	aux_source_clk_config(MC_CGM0_BASE_ADDR, 8, MC_CGM_ACn_SEL_DDRPLL);
+	aux_div_clk_config(MC_CGM0_BASE_ADDR, 8, 0, 0);
+	/* setup the aux clock divider for DDR4_CLK (133,25MHz) */
+	aux_div_clk_config(MC_CGM0_BASE_ADDR, 8, 1, 3);
+
+	entry_to_target_mode(MC_ME_MCTL_RUN0);
+
+}
+
+static void enable_modules_clock(void)
+{
+	/* PIT0 */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL58);
+	/* PIT1 */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL170);
+	/* LINFLEX0 */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL83);
+	/* LINFLEX1 */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL188);
+	/* ENET */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL50);
+	/* SDHC */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL93);
+	/* IIC0 */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL81);
+	/* IIC1 */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL184);
+	/* IIC2 */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL186);
+	/* MMDC0 */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL54);
+	/* MMDC1 */
+	writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL162);
+
+	entry_to_target_mode(MC_ME_MCTL_RUN0);
+}
+
+void clock_init(void)
+{
+	unsigned int arm_dfs[ARM_PLL_PHI1_DFS_Nr][DFS_PARAMS_Nr] = {
+		{ARM_PLL_PHI1_DFS1_EN, ARM_PLL_PHI1_DFS1_MFN,
+		 ARM_PLL_PHI1_DFS1_MFI},
+		{ARM_PLL_PHI1_DFS2_EN, ARM_PLL_PHI1_DFS2_MFN,
+		 ARM_PLL_PHI1_DFS2_MFI},
+		{ARM_PLL_PHI1_DFS3_EN, ARM_PLL_PHI1_DFS3_MFN,
+		 ARM_PLL_PHI1_DFS3_MFI}
+	};
+
+	unsigned int enet_dfs[ENET_PLL_PHI1_DFS_Nr][DFS_PARAMS_Nr] = {
+		{ENET_PLL_PHI1_DFS1_EN, ENET_PLL_PHI1_DFS1_MFN,
+		 ENET_PLL_PHI1_DFS1_MFI},
+		{ENET_PLL_PHI1_DFS2_EN, ENET_PLL_PHI1_DFS2_MFN,
+		 ENET_PLL_PHI1_DFS2_MFI},
+		{ENET_PLL_PHI1_DFS3_EN, ENET_PLL_PHI1_DFS3_MFN,
+		 ENET_PLL_PHI1_DFS3_MFI},
+		{ENET_PLL_PHI1_DFS4_EN, ENET_PLL_PHI1_DFS4_MFN,
+		 ENET_PLL_PHI1_DFS4_MFI}
+	};
+
+	unsigned int ddr_dfs[DDR_PLL_PHI1_DFS_Nr][DFS_PARAMS_Nr] = {
+		{DDR_PLL_PHI1_DFS1_EN, DDR_PLL_PHI1_DFS1_MFN,
+		 DDR_PLL_PHI1_DFS1_MFI},
+		{DDR_PLL_PHI1_DFS2_EN, DDR_PLL_PHI1_DFS2_MFN,
+		 DDR_PLL_PHI1_DFS2_MFI},
+		{DDR_PLL_PHI1_DFS3_EN, DDR_PLL_PHI1_DFS3_MFN,
+		 DDR_PLL_PHI1_DFS3_MFI}
+	};
+
+	writel(MC_ME_RUN_PCn_DRUN | MC_ME_RUN_PCn_RUN0 | MC_ME_RUN_PCn_RUN1 |
+	       MC_ME_RUN_PCn_RUN2 | MC_ME_RUN_PCn_RUN3, MC_ME_RUN_PCn(0));
+
+	/* turn on FXOSC */
+	writel(MC_ME_RUNMODE_MC_MVRON | MC_ME_RUNMODE_MC_XOSCON |
+	       MC_ME_RUNMODE_MC_FIRCON | MC_ME_RUNMODE_MC_SYSCLK(0x1),
+	       MC_ME_RUNn_MC(0));
+
+	entry_to_target_mode(MC_ME_MCTL_RUN0);
+
+	program_pll(ARM_PLL, XOSC_CLK_FREQ, ARM_PLL_PHI0_FREQ,
+		    ARM_PLL_PHI1_FREQ, ARM_PLL_PHI1_DFS_Nr, arm_dfs,
+		    ARM_PLL_PLLDV_PREDIV, ARM_PLL_PLLDV_MFD, ARM_PLL_PLLDV_MFN);
+
+	setup_sys_clocks();
+
+	program_pll(PERIPH_PLL, XOSC_CLK_FREQ, PERIPH_PLL_PHI0_FREQ,
+		    PERIPH_PLL_PHI1_FREQ, PERIPH_PLL_PHI1_DFS_Nr, NULL,
+		    PERIPH_PLL_PLLDV_PREDIV, PERIPH_PLL_PLLDV_MFD,
+		    PERIPH_PLL_PLLDV_MFN);
+
+	program_pll(ENET_PLL, XOSC_CLK_FREQ, ENET_PLL_PHI0_FREQ,
+		    ENET_PLL_PHI1_FREQ, ENET_PLL_PHI1_DFS_Nr, enet_dfs,
+		    ENET_PLL_PLLDV_PREDIV, ENET_PLL_PLLDV_MFD,
+		    ENET_PLL_PLLDV_MFN);
+
+	program_pll(DDR_PLL, XOSC_CLK_FREQ, DDR_PLL_PHI0_FREQ,
+		    DDR_PLL_PHI1_FREQ, DDR_PLL_PHI1_DFS_Nr, ddr_dfs,
+		    DDR_PLL_PLLDV_PREDIV, DDR_PLL_PLLDV_MFD, DDR_PLL_PLLDV_MFN);
+
+	program_pll(VIDEO_PLL, XOSC_CLK_FREQ, VIDEO_PLL_PHI0_FREQ,
+		    VIDEO_PLL_PHI1_FREQ, VIDEO_PLL_PHI1_DFS_Nr, NULL,
+		    VIDEO_PLL_PLLDV_PREDIV, VIDEO_PLL_PLLDV_MFD,
+		    VIDEO_PLL_PLLDV_MFN);
+
+	setup_aux_clocks();
+
+	enable_modules_clock();
+
+}
diff --git a/board/freescale/s32v234evb/lpddr2.c b/board/freescale/s32v234evb/lpddr2.c
new file mode 100644
index 0000000..ecc0842
--- /dev/null
+++ b/board/freescale/s32v234evb/lpddr2.c
@@ -0,0 +1,137 @@
+/*
+ * (C) Copyright 2015, Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/siul.h>
+#include <asm/arch/lpddr2.h>
+#include <asm/arch/mmdc.h>
+
+volatile int mscr_offset_ck0;
+
+void lpddr2_config_iomux(uint8_t module)
+{
+	int i;
+
+	switch (module) {
+	case DDR0:
+		mscr_offset_ck0 = SIUL2_MSCRn(_DDR0_CKE0);
+		writel(LPDDR2_CLK0_PAD, SIUL2_MSCRn(_DDR0_CLK0));
+
+		writel(LPDDR2_CKEn_PAD, SIUL2_MSCRn(_DDR0_CKE0));
+		writel(LPDDR2_CKEn_PAD, SIUL2_MSCRn(_DDR0_CKE1));
+
+		writel(LPDDR2_CS_Bn_PAD, SIUL2_MSCRn(_DDR0_CS_B0));
+		writel(LPDDR2_CS_Bn_PAD, SIUL2_MSCRn(_DDR0_CS_B1));
+
+		for (i = _DDR0_DM0; i <= _DDR0_DM3; i++)
+			writel(LPDDR2_DMn_PAD, SIUL2_MSCRn(i));
+
+		for (i = _DDR0_DQS0; i <= _DDR0_DQS3; i++)
+			writel(LPDDR2_DQSn_PAD, SIUL2_MSCRn(i));
+
+		for (i = _DDR0_A0; i <= _DDR0_A9; i++)
+			writel(LPDDR2_An_PAD, SIUL2_MSCRn(i));
+
+		for (i = _DDR0_D0; i <= _DDR0_D31; i++)
+			writel(LPDDR2_Dn_PAD, SIUL2_MSCRn(i));
+		break;
+	case DDR1:
+		writel(LPDDR2_CLK0_PAD, SIUL2_MSCRn(_DDR1_CLK0));
+
+		writel(LPDDR2_CKEn_PAD, SIUL2_MSCRn(_DDR1_CKE0));
+		writel(LPDDR2_CKEn_PAD, SIUL2_MSCRn(_DDR1_CKE1));
+
+		writel(LPDDR2_CS_Bn_PAD, SIUL2_MSCRn(_DDR1_CS_B0));
+		writel(LPDDR2_CS_Bn_PAD, SIUL2_MSCRn(_DDR1_CS_B1));
+
+		for (i = _DDR1_DM0; i <= _DDR1_DM3; i++)
+			writel(LPDDR2_DMn_PAD, SIUL2_MSCRn(i));
+
+		for (i = _DDR1_DQS0; i <= _DDR1_DQS3; i++)
+			writel(LPDDR2_DQSn_PAD, SIUL2_MSCRn(i));
+
+		for (i = _DDR1_A0; i <= _DDR1_A9; i++)
+			writel(LPDDR2_An_PAD, SIUL2_MSCRn(i));
+
+		for (i = _DDR1_D0; i <= _DDR1_D31; i++)
+			writel(LPDDR2_Dn_PAD, SIUL2_MSCRn(i));
+		break;
+	}
+}
+
+void config_mmdc(uint8_t module)
+{
+	unsigned long mmdc_addr = (module) ? MMDC1_BASE_ADDR : MMDC0_BASE_ADDR;
+
+	writel(MMDC_MDSCR_CFG_VALUE, mmdc_addr + MMDC_MDSCR);
+
+	writel(MMDC_MDCFG0_VALUE, mmdc_addr + MMDC_MDCFG0);
+	writel(MMDC_MDCFG1_VALUE, mmdc_addr + MMDC_MDCFG1);
+	writel(MMDC_MDCFG2_VALUE, mmdc_addr + MMDC_MDCFG2);
+	writel(MMDC_MDCFG3LP_VALUE, mmdc_addr + MMDC_MDCFG3LP);
+	writel(MMDC_MDOTC_VALUE, mmdc_addr + MMDC_MDOTC);
+	writel(MMDC_MDMISC_VALUE, mmdc_addr + MMDC_MDMISC);
+	writel(MMDC_MDOR_VALUE, mmdc_addr + MMDC_MDOR);
+	writel(_MDCTL, mmdc_addr + MMDC_MDCTL);
+
+	writel(MMDC_MPMUR0_VALUE, mmdc_addr + MMDC_MPMUR0);
+
+	while (readl(mmdc_addr + MMDC_MPMUR0) & MMDC_MPMUR0_FRC_MSR) {
+	}
+
+	writel(MMDC_MDSCR_RST_VALUE, mmdc_addr + MMDC_MDSCR);
+
+	/* Perform ZQ calibration */
+	writel(MMDC_MPZQLP2CTL_VALUE, mmdc_addr + MMDC_MPZQLP2CTL);
+	writel(MMDC_MPZQHWCTRL_VALUE, mmdc_addr + MMDC_MPZQHWCTRL);
+	while (readl(mmdc_addr + MMDC_MPZQHWCTRL) & MMDC_MPZQHWCTRL_ZQ_HW_FOR) {
+	}
+
+	/* Enable MMDC with CS0 */
+	writel(_MDCTL + 0x80000000, mmdc_addr + MMDC_MDCTL);
+
+	/* Complete the initialization sequence as defined by JEDEC */
+	writel(MMDC_MDSCR_MR1_VALUE, mmdc_addr + MMDC_MDSCR);
+	writel(MMDC_MDSCR_MR2_VALUE, mmdc_addr + MMDC_MDSCR);
+	writel(MMDC_MDSCR_MR3_VALUE, mmdc_addr + MMDC_MDSCR);
+	writel(MMDC_MDSCR_MR10_VALUE, mmdc_addr + MMDC_MDSCR);
+
+	/* Set the amount of DRAM */
+	/* Set DQS settings based on board type */
+
+	switch (module) {
+	case MMDC0:
+		writel(MMDC_MDASP_MODULE0_VALUE, mmdc_addr + MMDC_MDASP);
+		writel(MMDC_MPRDDLCTL_MODULE0_VALUE,
+		       mmdc_addr + MMDC_MPRDDLCTL);
+		writel(MMDC_MPWRDLCTL_MODULE0_VALUE,
+		       mmdc_addr + MMDC_MPWRDLCTL);
+		writel(MMDC_MPDGCTRL0_MODULE0_VALUE,
+		       mmdc_addr + MMDC_MPDGCTRL0);
+		writel(MMDC_MPDGCTRL1_MODULE0_VALUE,
+		       mmdc_addr + MMDC_MPDGCTRL1);
+		break;
+	case MMDC1:
+		writel(MMDC_MDASP_MODULE1_VALUE, mmdc_addr + MMDC_MDASP);
+		writel(MMDC_MPRDDLCTL_MODULE1_VALUE,
+		       mmdc_addr + MMDC_MPRDDLCTL);
+		writel(MMDC_MPWRDLCTL_MODULE1_VALUE,
+		       mmdc_addr + MMDC_MPWRDLCTL);
+		writel(MMDC_MPDGCTRL0_MODULE1_VALUE,
+		       mmdc_addr + MMDC_MPDGCTRL0);
+		writel(MMDC_MPDGCTRL1_MODULE1_VALUE,
+		       mmdc_addr + MMDC_MPDGCTRL1);
+		break;
+	}
+
+	writel(MMDC_MDRWD_VALUE, mmdc_addr + MMDC_MDRWD);
+	writel(MMDC_MDPDC_VALUE, mmdc_addr + MMDC_MDPDC);
+	writel(MMDC_MDREF_VALUE, mmdc_addr + MMDC_MDREF);
+	writel(MMDC_MPODTCTRL_VALUE, mmdc_addr + MMDC_MPODTCTRL);
+	writel(MMDC_MDSCR_DEASSERT_VALUE, mmdc_addr + MMDC_MDSCR);
+
+}
diff --git a/board/freescale/s32v234evb/s32v234evb.c b/board/freescale/s32v234evb/s32v234evb.c
new file mode 100644
index 0000000..3100f09
--- /dev/null
+++ b/board/freescale/s32v234evb/s32v234evb.c
@@ -0,0 +1,183 @@
+/*
+ * (C) Copyright 2013-2015, Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/siul.h>
+#include <asm/arch/lpddr2.h>
+#include <asm/arch/clock.h>
+#include <mmc.h>
+#include <fsl_esdhc.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <i2c.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void setup_iomux_ddr(void)
+{
+	lpddr2_config_iomux(DDR0);
+	lpddr2_config_iomux(DDR1);
+
+}
+
+void ddr_phy_init(void)
+{
+}
+
+void ddr_ctrl_init(void)
+{
+	config_mmdc(0);
+	config_mmdc(1);
+}
+
+int dram_init(void)
+{
+	setup_iomux_ddr();
+
+	ddr_ctrl_init();
+
+	gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
+
+	return 0;
+}
+
+static void setup_iomux_uart(void)
+{
+	/* Muxing for linflex */
+	/* Replace the magic values after bringup */
+
+	/* set TXD - MSCR[12] PA12 */
+	writel(SIUL2_UART_TXD, SIUL2_MSCRn(SIUL2_UART0_TXD_PAD));
+
+	/* set RXD - MSCR[11] - PA11 */
+	writel(SIUL2_UART_MSCR_RXD, SIUL2_MSCRn(SIUL2_UART0_MSCR_RXD_PAD));
+
+	/* set RXD - IMCR[200] - 200 */
+	writel(SIUL2_UART_IMCR_RXD, SIUL2_IMCRn(SIUL2_UART0_IMCR_RXD_PAD));
+}
+
+static void setup_iomux_enet(void)
+{
+}
+
+static void setup_iomux_i2c(void)
+{
+}
+
+#ifdef CONFIG_SYS_USE_NAND
+void setup_iomux_nfc(void)
+{
+}
+#endif
+
+#ifdef CONFIG_FSL_ESDHC
+struct fsl_esdhc_cfg esdhc_cfg[1] = {
+	{USDHC_BASE_ADDR},
+};
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+	/* eSDHC1 is always present */
+	return 1;
+}
+
+int board_mmc_init(bd_t * bis)
+{
+	esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_USDHC_CLK);
+
+	/* Set iomux PADS for USDHC */
+
+	/* PK6 pad: uSDHC clk */
+	writel(SIUL2_USDHC_PAD_CTRL_CLK, SIUL2_MSCRn(150));
+	writel(0x3, SIUL2_MSCRn(902));
+
+	/* PK7 pad: uSDHC CMD */
+	writel(SIUL2_USDHC_PAD_CTRL_CMD, SIUL2_MSCRn(151));
+	writel(0x3, SIUL2_MSCRn(901));
+
+	/* PK8 pad: uSDHC DAT0 */
+	writel(SIUL2_USDHC_PAD_CTRL_DAT0_3, SIUL2_MSCRn(152));
+	writel(0x3, SIUL2_MSCRn(903));
+
+	/* PK9 pad: uSDHC DAT1 */
+	writel(SIUL2_USDHC_PAD_CTRL_DAT0_3, SIUL2_MSCRn(153));
+	writel(0x3, SIUL2_MSCRn(904));
+
+	/* PK10 pad: uSDHC DAT2 */
+	writel(SIUL2_USDHC_PAD_CTRL_DAT0_3, SIUL2_MSCRn(154));
+	writel(0x3, SIUL2_MSCRn(905));
+
+	/* PK11 pad: uSDHC DAT3 */
+	writel(SIUL2_USDHC_PAD_CTRL_DAT0_3, SIUL2_MSCRn(155));
+	writel(0x3, SIUL2_MSCRn(906));
+
+	/* PK15 pad: uSDHC DAT4 */
+	writel(SIUL2_USDHC_PAD_CTRL_DAT4_7, SIUL2_MSCRn(159));
+	writel(0x3, SIUL2_MSCRn(907));
+
+	/* PL0 pad: uSDHC DAT5 */
+	writel(SIUL2_USDHC_PAD_CTRL_DAT4_7, SIUL2_MSCRn(160));
+	writel(0x3, SIUL2_MSCRn(908));
+
+	/* PL1 pad: uSDHC DAT6 */
+	writel(SIUL2_USDHC_PAD_CTRL_DAT4_7, SIUL2_MSCRn(161));
+	writel(0x3, SIUL2_MSCRn(909));
+
+	/* PL2 pad: uSDHC DAT7 */
+	writel(SIUL2_USDHC_PAD_CTRL_DAT4_7, SIUL2_MSCRn(162));
+	writel(0x3, SIUL2_MSCRn(910));
+
+	return fsl_esdhc_initialize(bis, &esdhc_cfg[0]);
+}
+#endif
+
+static void mscm_init(void)
+{
+	struct mscm_ir *mscmir = (struct mscm_ir *)MSCM_BASE_ADDR;
+	int i;
+
+	for (i = 0; i < MSCM_IRSPRC_NUM; i++)
+		writew(MSCM_IRSPRC_CPn_EN, &mscmir->irsprc[i]);
+}
+
+int board_phy_config(struct phy_device *phydev)
+{
+	if (phydev->drv->config)
+		phydev->drv->config(phydev);
+
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	clock_init();
+	mscm_init();
+
+	setup_iomux_uart();
+	setup_iomux_enet();
+	setup_iomux_i2c();
+#ifdef CONFIG_SYS_USE_NAND
+	setup_iomux_nfc();
+#endif
+	return 0;
+}
+
+int board_init(void)
+{
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	puts("Board: s32v234evb\n");
+
+	return 0;
+}
diff --git a/board/freescale/s32v234evb/s32v234evb.cfg b/board/freescale/s32v234evb/s32v234evb.cfg
new file mode 100644
index 0000000..6017a40
--- /dev/null
+++ b/board/freescale/s32v234evb/s32v234evb.cfg
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2013-2015, Freescale Semiconductor, Inc.
+ *
+ * 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
+ */
+#include <asm/imx-common/imximage.cfg>
+
+/* image version */
+IMAGE_VERSION	2
+BOOT_FROM sd
+
+
+/*
+ * Boot Device : one of qspi, sd:
+ * qspi:   flash_offset: 0x1000
+ * sd/mmc: flash_offset: 0x1000
+ */
+
+
+#ifdef CONFIG_SECURE_BOOT
+SECURE_BOOT
+#endif