Jelajahi Sumber

Merge git://git.denx.de/u-boot-fsl-qoriq

Tom Rini 7 tahun lalu
induk
melakukan
1612128018
44 mengubah file dengan 835 tambahan dan 47 penghapusan
  1. 287 0
      arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
  2. 39 0
      arch/arm/cpu/armv8/fsl-layerscape/soc.c
  3. 3 0
      arch/arm/cpu/armv8/fsl-layerscape/spl.c
  4. 1 1
      arch/arm/dts/fsl-ls1012a-frdm.dts
  5. 1 1
      arch/arm/dts/fsl-ls1012a-frdm.dtsi
  6. 1 1
      arch/arm/dts/fsl-ls1012a-qds.dts
  7. 1 1
      arch/arm/dts/fsl-ls1012a-qds.dtsi
  8. 1 1
      arch/arm/dts/fsl-ls1012a-rdb.dts
  9. 1 3
      arch/arm/dts/fsl-ls1012a-rdb.dtsi
  10. 1 1
      arch/arm/dts/fsl-ls1012a.dtsi
  11. 1 1
      arch/arm/dts/fsl-ls1043a-qds-duart.dts
  12. 1 1
      arch/arm/dts/fsl-ls1043a-qds-lpuart.dts
  13. 1 3
      arch/arm/dts/fsl-ls1043a-qds.dtsi
  14. 1 3
      arch/arm/dts/fsl-ls1043a-rdb.dts
  15. 1 3
      arch/arm/dts/fsl-ls1043a.dtsi
  16. 1 1
      arch/arm/dts/fsl-ls1046a-qds-duart.dts
  17. 1 1
      arch/arm/dts/fsl-ls1046a-qds-lpuart.dts
  18. 1 3
      arch/arm/dts/fsl-ls1046a-qds.dtsi
  19. 1 3
      arch/arm/dts/fsl-ls1046a-rdb.dts
  20. 1 3
      arch/arm/dts/fsl-ls1046a.dtsi
  21. 1 1
      arch/arm/dts/fsl-ls1088a-qds.dts
  22. 1 1
      arch/arm/dts/fsl-ls1088a-rdb.dts
  23. 1 1
      arch/arm/dts/fsl-ls1088a.dtsi
  24. 1 1
      arch/arm/dts/fsl-ls2080a-qds.dts
  25. 1 1
      arch/arm/dts/fsl-ls2080a-rdb.dts
  26. 1 1
      arch/arm/dts/fsl-ls2080a.dtsi
  27. 1 1
      arch/arm/dts/fsl-ls2081a-rdb.dts
  28. 1 1
      arch/arm/dts/fsl-ls2088a-rdb-qspi.dts
  29. 1 1
      arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
  30. 41 2
      arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
  31. 1 0
      arch/arm/include/asm/arch-fsl-layerscape/soc.h
  32. 16 0
      board/freescale/common/Kconfig
  33. 1 1
      board/freescale/common/Makefile
  34. 22 0
      board/freescale/common/qixis.c
  35. 146 1
      board/freescale/common/vid.c
  36. 21 0
      board/freescale/ls1088a/ddr.c
  37. 131 0
      board/freescale/ls1088a/ls1088a.c
  38. 10 0
      common/board_f.c
  39. 6 1
      common/hash.c
  40. 19 1
      drivers/crypto/fsl/fsl_hash.c
  41. 3 1
      drivers/ddr/fsl/fsl_ddr_gen4.c
  42. 3 0
      include/common.h
  43. 31 0
      include/configs/ls1088aqds.h
  44. 29 0
      include/configs/ls1088ardb.h

+ 287 - 0
arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c

@@ -158,6 +158,293 @@ void serdes_init(u32 sd, u32 sd_addr, u32 rcwsr, u32 sd_prctl_mask,
 	serdes_prtcl_map[NONE] = 1;
 }
 
+__weak int get_serdes_volt(void)
+{
+	return -1;
+}
+
+__weak int set_serdes_volt(int svdd)
+{
+	return -1;
+}
+
+#define LNAGCR0_RT_RSTB		0x00600000
+
+#define RSTCTL_RESET_MASK	0x000000E0
+
+#define RSTCTL_RSTREQ		0x80000000
+#define RSTCTL_RST_DONE		0x40000000
+#define RSTCTL_RSTERR		0x20000000
+
+#define RSTCTL_SDEN		0x00000020
+#define RSTCTL_SDRST_B		0x00000040
+#define RSTCTL_PLLRST_B		0x00000080
+
+#define TCALCR_CALRST_B		0x08000000
+
+struct serdes_prctl_info {
+	u32 id;
+	u32 mask;
+	u32 shift;
+};
+
+struct serdes_prctl_info srds_prctl_info[] = {
+#ifdef CONFIG_SYS_FSL_SRDS_1
+	{.id = 1,
+	 .mask = FSL_CHASSIS3_SRDS1_PRTCL_MASK,
+	 .shift = FSL_CHASSIS3_SRDS1_PRTCL_SHIFT
+	},
+
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+	{.id = 2,
+	 .mask = FSL_CHASSIS3_SRDS2_PRTCL_MASK,
+	 .shift = FSL_CHASSIS3_SRDS2_PRTCL_SHIFT
+	},
+#endif
+	{} /* NULL ENTRY */
+};
+
+static int get_serdes_prctl_info_idx(u32 serdes_id)
+{
+	int pos = 0;
+	struct serdes_prctl_info *srds_info;
+
+	/* loop until NULL ENTRY defined by .id=0 */
+	for (srds_info = srds_prctl_info; srds_info->id != 0;
+	     srds_info++, pos++) {
+		if (srds_info->id == serdes_id)
+			return pos;
+	}
+
+	return -1;
+}
+
+static void do_enabled_lanes_reset(u32 serdes_id, u32 cfg,
+				   struct ccsr_serdes __iomem *serdes_base,
+				   bool cmplt)
+{
+	int i, pos;
+	u32 cfg_tmp;
+
+	pos = get_serdes_prctl_info_idx(serdes_id);
+	if (pos == -1) {
+		printf("invalid serdes_id %d\n", serdes_id);
+		return;
+	}
+
+	cfg_tmp = cfg & srds_prctl_info[pos].mask;
+	cfg_tmp >>= srds_prctl_info[pos].shift;
+
+	for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
+		if (cmplt)
+			setbits_le32(&serdes_base->lane[i].gcr0,
+				     LNAGCR0_RT_RSTB);
+		else
+			clrbits_le32(&serdes_base->lane[i].gcr0,
+				     LNAGCR0_RT_RSTB);
+	}
+}
+
+static void do_pll_reset(u32 cfg,
+			 struct ccsr_serdes __iomem *serdes_base)
+{
+	int i;
+
+	for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
+		clrbits_le32(&serdes_base->bank[i].rstctl,
+			     RSTCTL_RESET_MASK);
+		udelay(1);
+
+		setbits_le32(&serdes_base->bank[i].rstctl,
+			     RSTCTL_RSTREQ);
+	}
+	udelay(1);
+}
+
+static void do_rx_tx_cal_reset(struct ccsr_serdes __iomem *serdes_base)
+{
+	clrbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
+	clrbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
+}
+
+static void do_rx_tx_cal_reset_comp(u32 cfg, int i,
+				    struct ccsr_serdes __iomem *serdes_base)
+{
+	if (!(cfg == 0x3 && i == 1)) {
+		udelay(1);
+		setbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
+		setbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
+	}
+	udelay(1);
+}
+
+static void do_pll_reset_done(u32 cfg,
+			      struct ccsr_serdes __iomem *serdes_base)
+{
+	int i;
+	u32 reg = 0;
+
+	for (i = 0; i < 2; i++) {
+		reg = in_le32(&serdes_base->bank[i].pllcr0);
+		if (!(cfg & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
+			setbits_le32(&serdes_base->bank[i].rstctl,
+				     RSTCTL_RST_DONE);
+		}
+	}
+}
+
+static void do_serdes_enable(u32 cfg,
+			     struct ccsr_serdes __iomem *serdes_base)
+{
+	int i;
+
+	for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
+		setbits_le32(&serdes_base->bank[i].rstctl, RSTCTL_SDEN);
+		udelay(1);
+
+		setbits_le32(&serdes_base->bank[i].rstctl, RSTCTL_PLLRST_B);
+		udelay(1);
+		/* Take the Rx/Tx calibration out of reset */
+		do_rx_tx_cal_reset_comp(cfg, i, serdes_base);
+	}
+}
+
+static void do_pll_lock(u32 cfg,
+			struct ccsr_serdes __iomem *serdes_base)
+{
+	int i;
+	u32 reg = 0;
+
+	for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
+		/* if the PLL is not locked, set RST_ERR */
+		reg = in_le32(&serdes_base->bank[i].pllcr0);
+		if (!((reg >> 23) & 0x1)) {
+			setbits_le32(&serdes_base->bank[i].rstctl,
+				     RSTCTL_RSTERR);
+		} else {
+			udelay(1);
+			setbits_le32(&serdes_base->bank[i].rstctl,
+				     RSTCTL_SDRST_B);
+			udelay(1);
+		}
+	}
+}
+
+int setup_serdes_volt(u32 svdd)
+{
+	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+	struct ccsr_serdes __iomem *serdes1_base =
+			(void *)CONFIG_SYS_FSL_LSCH3_SERDES_ADDR;
+	u32 cfg_rcwsrds1 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]);
+#ifdef CONFIG_SYS_FSL_SRDS_2
+	struct ccsr_serdes __iomem *serdes2_base =
+			(void *)(CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + 0x10000);
+	u32 cfg_rcwsrds2 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]);
+#endif
+	u32 cfg_tmp;
+	int svdd_cur, svdd_tar;
+	int ret = 1;
+
+	/* Only support switch SVDD to 900mV */
+	if (svdd != 900)
+		return -EINVAL;
+
+	/* Scale up to the LTC resolution is 1/4096V */
+	svdd = (svdd * 4096) / 1000;
+
+	svdd_tar = svdd;
+	svdd_cur = get_serdes_volt();
+	if (svdd_cur < 0)
+		return -EINVAL;
+
+	debug("%s: current SVDD: %x; target SVDD: %x\n",
+	      __func__, svdd_cur, svdd_tar);
+	if (svdd_cur == svdd_tar)
+		return 0;
+
+	/* Put the all enabled lanes in reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+	do_enabled_lanes_reset(1, cfg_rcwsrds1, serdes1_base, false);
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+	do_enabled_lanes_reset(2, cfg_rcwsrds2, serdes2_base, false);
+#endif
+
+	/* Put the all enabled PLL in reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+	cfg_tmp = cfg_rcwsrds1 & 0x3;
+	do_pll_reset(cfg_tmp, serdes1_base);
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+	cfg_tmp = cfg_rcwsrds1 & 0xC;
+	cfg_tmp >>= 2;
+	do_pll_reset(cfg_tmp, serdes2_base);
+#endif
+
+	/* Put the Rx/Tx calibration into reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+	do_rx_tx_cal_reset(serdes1_base);
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+	do_rx_tx_cal_reset(serdes2_base);
+#endif
+
+	ret = set_serdes_volt(svdd);
+	if (ret < 0) {
+		printf("could not change SVDD\n");
+		ret = -1;
+	}
+
+	/* For each PLL that’s not disabled via RCW enable the SERDES */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+	cfg_tmp = cfg_rcwsrds1 & 0x3;
+	do_serdes_enable(cfg_tmp, serdes1_base);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+	cfg_tmp = cfg_rcwsrds1 & 0xC;
+	cfg_tmp >>= 2;
+	do_serdes_enable(cfg_tmp, serdes2_base);
+#endif
+
+	/* Wait for at at least 625us, ensure the PLLs being reset are locked */
+	udelay(800);
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+	cfg_tmp = cfg_rcwsrds1 & 0x3;
+	do_pll_lock(cfg_tmp, serdes1_base);
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+	cfg_tmp = cfg_rcwsrds1 & 0xC;
+	cfg_tmp >>= 2;
+	do_pll_lock(cfg_tmp, serdes2_base);
+#endif
+	/* Take the all enabled lanes out of reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+	do_enabled_lanes_reset(1, cfg_rcwsrds1, serdes1_base, true);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+	do_enabled_lanes_reset(2, cfg_rcwsrds2, serdes2_base, true);
+#endif
+
+	/* For each PLL being reset, and achieved PLL lock set RST_DONE */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+	cfg_tmp = cfg_rcwsrds1 & 0x3;
+	do_pll_reset_done(cfg_tmp, serdes1_base);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+	cfg_tmp = cfg_rcwsrds1 & 0xC;
+	cfg_tmp >>= 2;
+	do_pll_reset_done(cfg_tmp, serdes2_base);
+#endif
+
+	return ret;
+}
+
 void fsl_serdes_init(void)
 {
 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)

+ 39 - 0
arch/arm/cpu/armv8/fsl-layerscape/soc.c

@@ -363,6 +363,45 @@ int sata_init(void)
 }
 #endif
 
+/* Get VDD in the unit mV from voltage ID */
+int get_core_volt_from_fuse(void)
+{
+	struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+	int vdd;
+	u32 fusesr;
+	u8 vid;
+
+	/* get the voltage ID from fuse status register */
+	fusesr = in_le32(&gur->dcfg_fusesr);
+	debug("%s: fusesr = 0x%x\n", __func__, fusesr);
+	vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) &
+		FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK;
+	if ((vid == 0) || (vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK)) {
+		vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) &
+			FSL_CHASSIS3_DCFG_FUSESR_VID_MASK;
+	}
+	debug("%s: VID = 0x%x\n", __func__, vid);
+	switch (vid) {
+	case 0x00: /* VID isn't supported */
+		vdd = -EINVAL;
+		debug("%s: The VID feature is not supported\n", __func__);
+		break;
+	case 0x08: /* 0.9V silicon */
+		vdd = 900;
+		break;
+	case 0x10: /* 1.0V silicon */
+		vdd = 1000;
+		break;
+	default:  /* Other core voltage */
+		vdd = -EINVAL;
+		debug("%s: The VID(%x) isn't supported\n", __func__, vid);
+		break;
+	}
+	debug("%s: The required minimum volt of CORE is %dmV\n", __func__, vdd);
+
+	return vdd;
+}
+
 #elif defined(CONFIG_FSL_LSCH2)
 #ifdef CONFIG_SCSI_AHCI_PLAT
 int sata_init(void)

+ 3 - 0
arch/arm/cpu/armv8/fsl-layerscape/spl.c

@@ -84,6 +84,9 @@ void board_init_f(ulong dummy)
 
 #ifdef CONFIG_SPL_I2C_SUPPORT
 	i2c_init_all();
+#endif
+#ifdef CONFIG_VID
+	init_func_vid();
 #endif
 	dram_init();
 #ifdef CONFIG_SPL_FSL_LS_PPA

+ 1 - 1
arch/arm/dts/fsl-ls1012a-frdm.dts

@@ -3,7 +3,7 @@
  *
  * Copyright 2016, Freescale Semiconductor
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 1
arch/arm/dts/fsl-ls1012a-frdm.dtsi

@@ -3,7 +3,7 @@
  *
  * Copyright 2016, Freescale Semiconductor
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /include/ "fsl-ls1012a.dtsi"

+ 1 - 1
arch/arm/dts/fsl-ls1012a-qds.dts

@@ -1,7 +1,7 @@
 /*
  * Copyright 2016 Freescale Semiconductor
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 1
arch/arm/dts/fsl-ls1012a-qds.dtsi

@@ -1,7 +1,7 @@
 /*
  * Copyright 2016 Freescale Semiconductor
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /include/ "fsl-ls1012a.dtsi"

+ 1 - 1
arch/arm/dts/fsl-ls1012a-rdb.dts

@@ -3,7 +3,7 @@
  *
  * Copyright 2016, Freescale Semiconductor
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 3
arch/arm/dts/fsl-ls1012a-rdb.dtsi

@@ -3,9 +3,7 @@
  *
  * Copyright 2016, Freescale Semiconductor
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * SPDX-License-Identifier:    GPL-2.0+	X11
  */
 
 /include/ "fsl-ls1012a.dtsi"

+ 1 - 1
arch/arm/dts/fsl-ls1012a.dtsi

@@ -1,7 +1,7 @@
 /*
  * Copyright 2016 Freescale Semiconductor
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /include/ "skeleton64.dtsi"

+ 1 - 1
arch/arm/dts/fsl-ls1043a-qds-duart.dts

@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2015, Freescale Semiconductor
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 1
arch/arm/dts/fsl-ls1043a-qds-lpuart.dts

@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2015, Freescale Semiconductor
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 3
arch/arm/dts/fsl-ls1043a-qds.dtsi

@@ -5,9 +5,7 @@
  *
  * Mingkai Hu <Mingkai.hu@freescale.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * SPDX-License-Identifier:    GPL-2.0+	X11
  */
 
 /include/ "fsl-ls1043a.dtsi"

+ 1 - 3
arch/arm/dts/fsl-ls1043a-rdb.dts

@@ -5,9 +5,7 @@
  *
  * Mingkai Hu <Mingkai.hu@freescale.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * SPDX-License-Identifier:    GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 3
arch/arm/dts/fsl-ls1043a.dtsi

@@ -5,9 +5,7 @@
  *
  * Mingkai Hu <Mingkai.hu@freescale.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * SPDX-License-Identifier:    GPL-2.0+	X11
  */
 
 /include/ "skeleton64.dtsi"

+ 1 - 1
arch/arm/dts/fsl-ls1046a-qds-duart.dts

@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2016, Freescale Semiconductor
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 1
arch/arm/dts/fsl-ls1046a-qds-lpuart.dts

@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2016, Freescale Semiconductor
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 3
arch/arm/dts/fsl-ls1046a-qds.dtsi

@@ -5,9 +5,7 @@
  *
  * Mingkai Hu <Mingkai.hu@nxp.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * SPDX-License-Identifier:    GPL-2.0+	X11
  */
 
 /include/ "fsl-ls1046a.dtsi"

+ 1 - 3
arch/arm/dts/fsl-ls1046a-rdb.dts

@@ -5,9 +5,7 @@
  *
  * Mingkai Hu <Mingkai.hu@freescale.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * SPDX-License-Identifier:    GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 3
arch/arm/dts/fsl-ls1046a.dtsi

@@ -5,9 +5,7 @@
  *
  * Mingkai Hu <mingkai.hu@nxp.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * SPDX-License-Identifier:    GPL-2.0+	X11
  */
 
 /include/ "skeleton64.dtsi"

+ 1 - 1
arch/arm/dts/fsl-ls1088a-qds.dts

@@ -3,7 +3,7 @@
  *
  * Copyright 2017 NXP
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 1
arch/arm/dts/fsl-ls1088a-rdb.dts

@@ -3,7 +3,7 @@
  *
  * Copyright 2017 NXP
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 1
arch/arm/dts/fsl-ls1088a.dtsi

@@ -3,7 +3,7 @@
  *
  * Copyright 2017 NXP
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 / {

+ 1 - 1
arch/arm/dts/fsl-ls2080a-qds.dts

@@ -3,7 +3,7 @@
  *
  * Copyright 2013-2015 Freescale Semiconductor, Inc.
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 1
arch/arm/dts/fsl-ls2080a-rdb.dts

@@ -3,7 +3,7 @@
  *
  * Copyright 2013-2015 Freescale Semiconductor, Inc.
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 1
arch/arm/dts/fsl-ls2080a.dtsi

@@ -3,7 +3,7 @@
  *
  * Copyright 2013-2015 Freescale Semiconductor, Inc.
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 / {

+ 1 - 1
arch/arm/dts/fsl-ls2081a-rdb.dts

@@ -5,7 +5,7 @@
  *
  * Copyright 2017 NXP
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 1
arch/arm/dts/fsl-ls2088a-rdb-qspi.dts

@@ -5,7 +5,7 @@
  *
  * Copyright 2017 NXP
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;

+ 1 - 1
arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h

@@ -164,6 +164,7 @@ void fsl_rgmii_init(void);
 #ifdef CONFIG_FSL_LSCH2
 const char *serdes_clock_to_string(u32 clock);
 int get_serdes_protocol(void);
+#endif
 #ifdef CONFIG_SYS_HAS_SERDES
 /* Get the volt of SVDD in unit mV */
 int get_serdes_volt(void);
@@ -172,6 +173,5 @@ int set_serdes_volt(int svdd);
 /* The target volt of SVDD in unit mV */
 int setup_serdes_volt(u32 svdd);
 #endif
-#endif
 
 #endif /* __FSL_SERDES_H__ */

+ 41 - 2
arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h

@@ -201,10 +201,15 @@ struct ccsr_gur {
 	u32	gpporcr3;
 	u32	gpporcr4;
 	u8	res_030[0x60-0x30];
-#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT	2
 #define FSL_CHASSIS3_DCFG_FUSESR_VID_MASK	0x1F
-#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT	7
 #define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK	0x1F
+#if defined(CONFIG_ARCH_LS1088A)
+#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT	25
+#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT	20
+#else
+#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT	2
+#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT	7
+#endif
 	u32	dcfg_fusesr;	/* Fuse status register */
 	u8	res_064[0x70-0x64];
 	u32	devdisr;	/* Device disable control 1 */
@@ -387,5 +392,39 @@ struct ccsr_reset {
 	u32 ip_rev2;			/* 0xbfc */
 };
 
+struct ccsr_serdes {
+	struct {
+		u32     rstctl; /* Reset Control Register */
+		u32     pllcr0; /* PLL Control Register 0 */
+		u32     pllcr1; /* PLL Control Register 1 */
+		u32     pllcr2; /* PLL Control Register 2 */
+		u32     pllcr3; /* PLL Control Register 3 */
+		u32     pllcr4; /* PLL Control Register 4 */
+		u32     pllcr5; /* PLL Control Register 5 */
+		u8      res[0x20 - 0x1c];
+	} bank[2];
+	u8      res1[0x90 - 0x40];
+	u32     srdstcalcr;     /* TX Calibration Control */
+	u32     srdstcalcr1;    /* TX Calibration Control1 */
+	u8      res2[0xa0 - 0x98];
+	u32     srdsrcalcr;     /* RX Calibration Control */
+	u32     srdsrcalcr1;    /* RX Calibration Control1 */
+	u8      res3[0xb0 - 0xa8];
+	u32     srdsgr0;        /* General Register 0 */
+	u8      res4[0x800 - 0xb4];
+	struct serdes_lane {
+		u32     gcr0;   /* General Control Register 0 */
+		u32     gcr1;   /* General Control Register 1 */
+		u32     gcr2;   /* General Control Register 2 */
+		u32     ssc0;   /* Speed Switch Control 0 */
+		u32     rec0;   /* Receive Equalization Control 0 */
+		u32     rec1;   /* Receive Equalization Control 1 */
+		u32     tec0;   /* Transmit Equalization Control 0 */
+		u32     ssc1;   /* Speed Switch Control 1 */
+		u8      res1[0x840 - 0x820];
+	} lane[8];
+	u8 res5[0x19fc - 0xa00];
+};
+
 #endif /*__ASSEMBLY__*/
 #endif /* __ARCH_FSL_LSCH3_IMMAP_H_ */

+ 1 - 0
arch/arm/include/asm/arch-fsl-layerscape/soc.h

@@ -121,6 +121,7 @@ struct ccsr_ahci {
 
 #ifdef CONFIG_FSL_LSCH3
 void fsl_lsch3_early_init_f(void);
+int get_core_volt_from_fuse(void);
 #elif defined(CONFIG_FSL_LSCH2)
 void fsl_lsch2_early_init_f(void);
 int setup_chip_volt(void);

+ 16 - 0
board/freescale/common/Kconfig

@@ -20,3 +20,19 @@ config CMD_ESBC_VALIDATE
 
 	    esbc_validate - validate signature using RSA verification
 	    esbc_halt - put the core in spin loop (Secure Boot Only)
+
+config VOL_MONITOR_LTC3882_READ
+	depends on VID
+	bool "Enable the LTC3882 voltage monitor read"
+	default n
+	help
+	 This option enables LTC3882 voltage monitor read
+	 functionality. It is used by common VID driver.
+
+config VOL_MONITOR_LTC3882_SET
+	depends on VID
+	bool "Enable the LTC3882 voltage monitor set"
+	default n
+	help
+	 This option enables LTC3882 voltage monitor set
+	 functionality. It is used by common VID driver.

+ 1 - 1
board/freescale/common/Makefile

@@ -23,8 +23,8 @@ obj-$(CONFIG_FMAN_ENET)	+= fman.o
 obj-$(CONFIG_FSL_PIXIS)	+= pixis.o
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_FSL_NGPIXIS)	+= ngpixis.o
-obj-$(CONFIG_VID)		+= vid.o
 endif
+obj-$(CONFIG_VID)		+= vid.o
 obj-$(CONFIG_FSL_QIXIS)	+= qixis.o
 obj-$(CONFIG_PQ_MDS_PIB)	+= pq-mds-pib.o
 ifndef CONFIG_SPL_BUILD

+ 22 - 0
board/freescale/common/qixis.c

@@ -234,6 +234,28 @@ static int qixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const ar
 		QIXIS_WRITE(rcfg_ctl, 0x21);
 #else
 		printf("Not implemented\n");
+#endif
+	} else if (strcmp(argv[1], "ifc") == 0) {
+#ifdef QIXIS_LBMAP_IFC
+		QIXIS_WRITE(rst_ctl, 0x30);
+		QIXIS_WRITE(rcfg_ctl, 0);
+		set_lbmap(QIXIS_LBMAP_IFC);
+		set_rcw_src(QIXIS_RCW_SRC_IFC);
+		QIXIS_WRITE(rcfg_ctl, 0x20);
+		QIXIS_WRITE(rcfg_ctl, 0x21);
+#else
+		printf("Not implemented\n");
+#endif
+	} else if (strcmp(argv[1], "emmc") == 0) {
+#ifdef QIXIS_LBMAP_EMMC
+		QIXIS_WRITE(rst_ctl, 0x30);
+		QIXIS_WRITE(rcfg_ctl, 0);
+		set_lbmap(QIXIS_LBMAP_EMMC);
+		set_rcw_src(QIXIS_RCW_SRC_EMMC);
+		QIXIS_WRITE(rcfg_ctl, 0x20);
+		QIXIS_WRITE(rcfg_ctl, 0x21);
+#else
+		printf("Not implemented\n");
 #endif
 	} else if (strcmp(argv[1], "sd_qspi") == 0) {
 #ifdef QIXIS_LBMAP_SD_QSPI

+ 146 - 1
board/freescale/common/vid.c

@@ -33,6 +33,16 @@ int __weak board_vdd_drop_compensation(void)
 	return 0;
 }
 
+/*
+ * Board specific settings for specific voltage value
+ */
+int __weak board_adjust_vdd(int vdd)
+{
+	return 0;
+}
+
+#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
+	defined(CONFIG_VOL_MONITOR_IR36021_READ)
 /*
  * Get the i2c address configuration for the IR regulator chip
  *
@@ -65,6 +75,7 @@ static int find_ir_chip_on_i2c(void)
 	}
 	return -1;
 }
+#endif
 
 /* Maximum loop count waiting for new voltage to take effect */
 #define MAX_LOOP_WAIT_NEW_VOL		100
@@ -163,6 +174,36 @@ static int read_voltage_from_IR(int i2caddress)
 }
 #endif
 
+#ifdef CONFIG_VOL_MONITOR_LTC3882_READ
+/* read the current value of the LTC Regulator Voltage */
+static int read_voltage_from_LTC(int i2caddress)
+{
+	int  ret, vcode = 0;
+	u8 chan = PWM_CHANNEL0;
+
+	/* select the PAGE 0 using PMBus commands PAGE for VDD*/
+	ret = i2c_write(I2C_VOL_MONITOR_ADDR,
+			PMBUS_CMD_PAGE, 1, &chan, 1);
+	if (ret) {
+		printf("VID: failed to select VDD Page 0\n");
+		return ret;
+	}
+
+	/*read the output voltage using PMBus command READ_VOUT*/
+	ret = i2c_read(I2C_VOL_MONITOR_ADDR,
+		       PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2);
+	if (ret) {
+		printf("VID: failed to read the volatge\n");
+		return ret;
+	}
+
+	/* Scale down to the real mV as LTC resolution is 1/4096V,rounding up */
+	vcode = DIV_ROUND_UP(vcode * 1000, 4096);
+
+	return vcode;
+}
+#endif
+
 static int read_voltage(int i2caddress)
 {
 	int voltage_read;
@@ -170,12 +211,15 @@ static int read_voltage(int i2caddress)
 	voltage_read = read_voltage_from_INA220(i2caddress);
 #elif defined CONFIG_VOL_MONITOR_IR36021_READ
 	voltage_read = read_voltage_from_IR(i2caddress);
+#elif defined CONFIG_VOL_MONITOR_LTC3882_READ
+	voltage_read = read_voltage_from_LTC(i2caddress);
 #else
 	return -1;
 #endif
 	return voltage_read;
 }
 
+#ifdef CONFIG_VOL_MONITOR_IR36021_SET
 /*
  * We need to calculate how long before the voltage stops to drop
  * or increase. It returns with the loop count. Each loop takes
@@ -235,7 +279,6 @@ static int wait_for_voltage_stable(int i2caddress)
 	return vdd_current;
 }
 
-#ifdef CONFIG_VOL_MONITOR_IR36021_SET
 /* Set the voltage to the IR chip */
 static int set_voltage_to_IR(int i2caddress, int vdd)
 {
@@ -270,6 +313,43 @@ static int set_voltage_to_IR(int i2caddress, int vdd)
 	debug("VID: Current voltage is %d mV\n", vdd_last);
 	return vdd_last;
 }
+
+#endif
+
+#ifdef CONFIG_VOL_MONITOR_LTC3882_SET
+/* this function sets the VDD and returns the value set */
+static int set_voltage_to_LTC(int i2caddress, int vdd)
+{
+	int ret, vdd_last, vdd_target = vdd;
+
+	/* Scale up to the LTC resolution is 1/4096V */
+	vdd = (vdd * 4096) / 1000;
+
+	/* 5-byte buffer which needs to be sent following the
+	 * PMBus command PAGE_PLUS_WRITE.
+	 */
+	u8 buff[5] = {0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND,
+			vdd & 0xFF, (vdd & 0xFF00) >> 8};
+
+	/* Write the desired voltage code to the regulator */
+	ret = i2c_write(I2C_VOL_MONITOR_ADDR,
+			PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5);
+	if (ret) {
+		printf("VID: I2C failed to write to the volatge regulator\n");
+		return -1;
+	}
+
+	/* Wait for the volatge to get to the desired value */
+	do {
+		vdd_last = read_voltage_from_LTC(i2caddress);
+		if (vdd_last < 0) {
+			printf("VID: Couldn't read sensor abort VID adjust\n");
+			return -1;
+		}
+	} while (vdd_last != vdd_target);
+
+	return vdd_last;
+}
 #endif
 
 static int set_voltage(int i2caddress, int vdd)
@@ -278,6 +358,8 @@ static int set_voltage(int i2caddress, int vdd)
 
 #ifdef CONFIG_VOL_MONITOR_IR36021_SET
 	vdd_last = set_voltage_to_IR(i2caddress, vdd);
+#elif defined CONFIG_VOL_MONITOR_LTC3882_SET
+	vdd_last = set_voltage_to_LTC(i2caddress, vdd);
 #else
 	#error Specific voltage monitor must be defined
 #endif
@@ -290,11 +372,53 @@ int adjust_vdd(ulong vdd_override)
 	int re_enable = disable_interrupts();
 	struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 	u32 fusesr;
+#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
+	defined(CONFIG_VOL_MONITOR_IR36021_READ)
 	u8 vid, buf;
+#else
+	u8 vid;
+#endif
 	int vdd_target, vdd_current, vdd_last;
 	int ret, i2caddress;
 	unsigned long vdd_string_override;
 	char *vdd_string;
+#ifdef CONFIG_ARCH_LS1088A
+	static const uint16_t vdd[32] = {
+		10250,
+		9875,
+		9750,
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		9000,
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		10000,  /* 1.0000V */
+		10125,
+		10250,
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+	};
+
+#else
 	static const uint16_t vdd[32] = {
 		10500,
 		0,      /* reserved */
@@ -329,6 +453,7 @@ int adjust_vdd(ulong vdd_override)
 		0,      /* reserved */
 		0,      /* reserved */
 	};
+#endif
 	struct vdd_drive {
 		u8 vid;
 		unsigned voltage;
@@ -340,6 +465,8 @@ int adjust_vdd(ulong vdd_override)
 		ret = -1;
 		goto exit;
 	}
+#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
+	defined(CONFIG_VOL_MONITOR_IR36021_READ)
 	ret = find_ir_chip_on_i2c();
 	if (ret < 0) {
 		printf("VID: Could not find voltage regulator on I2C.\n");
@@ -364,6 +491,7 @@ int adjust_vdd(ulong vdd_override)
 		ret = -1;
 		goto exit;
 	}
+#endif
 
 	/* get the voltage ID from fuse status register */
 	fusesr = in_le32(&gur->dcfg_fusesr);
@@ -415,6 +543,11 @@ int adjust_vdd(ulong vdd_override)
 	}
 	vdd_current = vdd_last;
 	debug("VID: Core voltage is currently at %d mV\n", vdd_last);
+
+#ifdef CONFIG_VOL_MONITOR_LTC3882_SET
+	/* Set the target voltage */
+	vdd_last = vdd_current = set_voltage(i2caddress, vdd_target);
+#else
 	/*
 	  * Adjust voltage to at or one step above target.
 	  * As measurements are less precise than setting the values
@@ -432,6 +565,12 @@ int adjust_vdd(ulong vdd_override)
 		vdd_last = set_voltage(i2caddress, vdd_current);
 	}
 
+#endif
+	if (board_adjust_vdd(vdd_target) < 0) {
+		ret = -1;
+		goto exit;
+	}
+
 	if (vdd_last > 0)
 		printf("VID: Core voltage after adjustment is at %d mV\n",
 		       vdd_last);
@@ -498,6 +637,8 @@ int adjust_vdd(ulong vdd_override)
 		ret = -1;
 		goto exit;
 	}
+#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
+	defined(CONFIG_VOL_MONITOR_IR36021_READ)
 	ret = find_ir_chip_on_i2c();
 	if (ret < 0) {
 		printf("VID: Could not find voltage regulator on I2C.\n");
@@ -522,6 +663,7 @@ int adjust_vdd(ulong vdd_override)
 		ret = -1;
 		goto exit;
 	}
+#endif
 
 	/* get the voltage ID from fuse status register */
 	fusesr = in_be32(&gur->dcfg_fusesr);
@@ -632,6 +774,8 @@ static int print_vdd(void)
 		debug("VID : I2c failed to switch channel\n");
 		return -1;
 	}
+#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
+	defined(CONFIG_VOL_MONITOR_IR36021_READ)
 	ret = find_ir_chip_on_i2c();
 	if (ret < 0) {
 		printf("VID: Could not find voltage regulator on I2C.\n");
@@ -640,6 +784,7 @@ static int print_vdd(void)
 		i2caddress = ret;
 		debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
 	}
+#endif
 
 	/*
 	 * Read voltage monitor to check real voltage.

+ 21 - 0
board/freescale/ls1088a/ddr.c

@@ -13,6 +13,23 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if defined(CONFIG_VID) && (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
+static void fsl_ddr_setup_0v9_volt(memctl_options_t *popts)
+{
+	int vdd;
+
+	vdd = get_core_volt_from_fuse();
+	/* Nothing to do for silicons doesn't support VID */
+	if (vdd < 0)
+		return;
+
+	if (vdd == 900) {
+		popts->ddr_cdr1 |= DDR_CDR1_V0PT9_EN;
+		debug("VID: configure DDR to support 900 mV\n");
+	}
+}
+#endif
+
 void fsl_ddr_board_options(memctl_options_t *popts,
 			   dimm_params_t *pdimm,
 			   unsigned int ctrl_num)
@@ -87,6 +104,10 @@ found:
 	popts->addr_hash = 1;
 
 	popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+#if defined(CONFIG_VID) && (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
+	fsl_ddr_setup_0v9_volt(popts);
+#endif
+
 	popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
 			  DDR_CDR2_VREF_TRAIN_EN | DDR_CDR2_VREF_RANGE_2;
 }

+ 131 - 0
board/freescale/ls1088a/ls1088a.c

@@ -19,9 +19,13 @@
 #include <asm/arch-fsl-layerscape/soc.h>
 #include <asm/arch/ppa.h>
 #include <hwconfig.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/soc.h>
 
 #include "../common/qixis.h"
 #include "ls1088a_qixis.h"
+#include "../common/vid.h"
+#include <fsl_immap.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -51,6 +55,16 @@ unsigned long long get_qixis_addr(void)
 }
 #endif
 
+#if defined(CONFIG_VID)
+int init_func_vid(void)
+{
+	if (adjust_vdd(0) < 0)
+		printf("core voltage not adjusted\n");
+
+	return 0;
+}
+#endif
+
 #if !defined(CONFIG_SPL_BUILD)
 int checkboard(void)
 {
@@ -207,6 +221,7 @@ unsigned long get_board_ddr_clk(void)
 
 	return 66666666;
 }
+#endif
 
 int select_i2c_ch_pca9547(u8 ch)
 {
@@ -221,6 +236,7 @@ int select_i2c_ch_pca9547(u8 ch)
 	return 0;
 }
 
+#if !defined(CONFIG_SPL_BUILD)
 void board_retimer_init(void)
 {
 	u8 reg;
@@ -322,7 +338,122 @@ int misc_init_r(void)
 	return 0;
 }
 #endif
+#endif
+
+int i2c_multiplexer_select_vid_channel(u8 channel)
+{
+	return select_i2c_ch_pca9547(channel);
+}
+
+#ifdef CONFIG_TARGET_LS1088AQDS
+/* read the current value(SVDD) of the LTM Regulator Voltage */
+int get_serdes_volt(void)
+{
+	int  ret, vcode = 0;
+	u8 chan = PWM_CHANNEL0;
+
+	/* Select the PAGE 0 using PMBus commands PAGE for VDD */
+	ret = i2c_write(I2C_SVDD_MONITOR_ADDR,
+			PMBUS_CMD_PAGE, 1, &chan, 1);
+	if (ret) {
+		printf("VID: failed to select VDD Page 0\n");
+		return ret;
+	}
+
+	/* Read the output voltage using PMBus command READ_VOUT */
+	ret = i2c_read(I2C_SVDD_MONITOR_ADDR,
+		       PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2);
+	if (ret) {
+		printf("VID: failed to read the volatge\n");
+		return ret;
+	}
+
+	return vcode;
+}
+
+int set_serdes_volt(int svdd)
+{
+	int ret, vdd_last;
+	u8 buff[5] = {0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND,
+			svdd & 0xFF, (svdd & 0xFF00) >> 8};
+
+	/* Write the desired voltage code to the SVDD regulator */
+	ret = i2c_write(I2C_SVDD_MONITOR_ADDR,
+			PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5);
+	if (ret) {
+		printf("VID: I2C failed to write to the volatge regulator\n");
+		return -1;
+	}
 
+	/* Wait for the volatge to get to the desired value */
+	do {
+		vdd_last = get_serdes_volt();
+		if (vdd_last < 0) {
+			printf("VID: Couldn't read sensor abort VID adjust\n");
+			return -1;
+		}
+	} while (vdd_last != svdd);
+
+	return 1;
+}
+#else
+int get_serdes_volt(void)
+{
+	return 0;
+}
+
+int set_serdes_volt(int svdd)
+{
+	int ret;
+	u8 brdcfg4;
+
+	printf("SVDD changing of RDB\n");
+
+	/* Read the BRDCFG54 via CLPD */
+	ret = i2c_read(CONFIG_SYS_I2C_FPGA_ADDR,
+		       QIXIS_BRDCFG4_OFFSET, 1, (void *)&brdcfg4, 1);
+	if (ret) {
+		printf("VID: I2C failed to read the CPLD BRDCFG4\n");
+		return -1;
+	}
+
+	brdcfg4 = brdcfg4 | 0x08;
+
+	/* Write to the BRDCFG4 */
+	ret = i2c_write(CONFIG_SYS_I2C_FPGA_ADDR,
+			QIXIS_BRDCFG4_OFFSET, 1, (void *)&brdcfg4, 1);
+	if (ret) {
+		debug("VID: I2C failed to set the SVDD CPLD BRDCFG4\n");
+		return -1;
+	}
+
+	/* Wait for the volatge to get to the desired value */
+	udelay(10000);
+
+	return 1;
+}
+#endif
+
+/* this function disables the SERDES, changes the SVDD Voltage and enables it*/
+int board_adjust_vdd(int vdd)
+{
+	int ret = 0;
+
+	debug("%s: vdd = %d\n", __func__, vdd);
+
+	/* Special settings to be performed when voltage is 900mV */
+	if (vdd == 900) {
+		ret = setup_serdes_volt(vdd);
+		if (ret < 0) {
+			ret = -1;
+			goto exit;
+		}
+	}
+exit:
+	return ret;
+}
+
+#if !defined(CONFIG_SPL_BUILD)
 int board_init(void)
 {
 	init_final_memctl_regs();

+ 10 - 0
common/board_f.c

@@ -200,6 +200,13 @@ static int init_func_i2c(void)
 }
 #endif
 
+#if defined(CONFIG_VID)
+__weak int init_func_vid(void)
+{
+	return 0;
+}
+#endif
+
 #if defined(CONFIG_HARD_SPI)
 static int init_func_spi(void)
 {
@@ -801,6 +808,9 @@ static const init_fnc_t init_sequence_f[] = {
 #if defined(CONFIG_SYS_I2C)
 	init_func_i2c,
 #endif
+#if defined(CONFIG_VID) && !defined(CONFIG_SPL)
+	init_func_vid,
+#endif
 #if defined(CONFIG_HARD_SPI)
 	init_func_spi,
 #endif

+ 6 - 1
common/hash.c

@@ -390,7 +390,7 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
 
 	if (multi_hash()) {
 		struct hash_algo *algo;
-		uint8_t output[HASH_MAX_DIGEST_SIZE];
+		u8 *output;
 		uint8_t vsum[HASH_MAX_DIGEST_SIZE];
 		void *buf;
 
@@ -405,6 +405,9 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
 			return 1;
 		}
 
+		output = memalign(ARCH_DMA_MINALIGN,
+				  sizeof(uint32_t) * HASH_MAX_DIGEST_SIZE);
+
 		buf = map_sysmem(addr, len);
 		algo->hash_func_ws(buf, len, output, algo->chunk_size);
 		unmap_sysmem(buf);
@@ -440,6 +443,8 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
 				store_result(algo, output, *argv,
 					flags & HASH_FLAG_ENV);
 			}
+		unmap_sysmem(output);
+
 		}
 
 	/* Horrible code size hack for boards that just want crc32 */

+ 19 - 1
drivers/crypto/fsl/fsl_hash.c

@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <malloc.h>
+#include <memalign.h>
 #include "jobdesc.h"
 #include "desc.h"
 #include "jr.h"
@@ -163,20 +164,37 @@ int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
 {
 	int ret = 0;
 	uint32_t *desc;
+	unsigned int size;
 
-	desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
+	desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE);
 	if (!desc) {
 		debug("Not enough memory for descriptor allocation\n");
 		return -ENOMEM;
 	}
 
+	if (!IS_ALIGNED((uintptr_t)pbuf, ARCH_DMA_MINALIGN) ||
+	    !IS_ALIGNED((uintptr_t)pout, ARCH_DMA_MINALIGN)) {
+		puts("Error: Address arguments are not aligned\n");
+		return -EINVAL;
+	}
+
+	size = ALIGN(buf_len, ARCH_DMA_MINALIGN);
+	flush_dcache_range((unsigned long)pbuf, (unsigned long)pbuf + size);
+
 	inline_cnstr_jobdesc_hash(desc, pbuf, buf_len, pout,
 				  driver_hash[algo].alg_type,
 				  driver_hash[algo].digestsize,
 				  0);
 
+	size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN);
+	flush_dcache_range((unsigned long)desc, (unsigned long)desc + size);
+
 	ret = run_descriptor_jr(desc);
 
+	size = ALIGN(driver_hash[algo].digestsize, ARCH_DMA_MINALIGN);
+	invalidate_dcache_range((unsigned long)pout,
+				(unsigned long)pout + size);
+
 	free(desc);
 	return ret;
 }

+ 3 - 1
drivers/ddr/fsl/fsl_ddr_gen4.c

@@ -95,6 +95,9 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 	if (step == 2)
 		goto step2;
 
+	/* Set cdr1 first in case 0.9v VDD is enabled for some SoCs*/
+	ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1);
+
 	if (regs->ddr_eor)
 		ddr_out32(&ddr->eor, regs->ddr_eor);
 
@@ -183,7 +186,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 	ddr_out32(&ddr->ddr_sdram_rcw_4, regs->ddr_sdram_rcw_4);
 	ddr_out32(&ddr->ddr_sdram_rcw_5, regs->ddr_sdram_rcw_5);
 	ddr_out32(&ddr->ddr_sdram_rcw_6, regs->ddr_sdram_rcw_6);
-	ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1);
 #ifdef CONFIG_DEEP_SLEEP
 	if (is_warm_boot()) {
 		ddr_out32(&ddr->sdram_cfg_2,

+ 3 - 0
include/common.h

@@ -364,6 +364,9 @@ int	embedded_dtb_select(void);
 
 int	misc_init_f   (void);
 int	misc_init_r   (void);
+#if defined(CONFIG_VID)
+int	init_func_vid(void);
+#endif
 
 /* common/exports.c */
 void	jumptable_init(void);

+ 31 - 0
include/configs/ls1088aqds.h

@@ -170,9 +170,13 @@ unsigned long get_board_ddr_clk(void);
 #define QIXIS_LBMAP_DFLTBANK		0x0e
 #define QIXIS_LBMAP_ALTBANK		0x2e
 #define QIXIS_LBMAP_SD			0x00
+#define QIXIS_LBMAP_EMMC		0x00
+#define QIXIS_LBMAP_IFC			0x00
 #define QIXIS_LBMAP_SD_QSPI		0x0e
 #define QIXIS_LBMAP_QSPI		0x0e
+#define QIXIS_RCW_SRC_IFC		0x25
 #define QIXIS_RCW_SRC_SD		0x40
+#define QIXIS_RCW_SRC_EMMC		0x41
 #define QIXIS_RCW_SRC_QSPI		0x62
 #define QIXIS_RST_CTL_RESET		0x41
 #define QIXIS_RCFG_CTL_RECONFIG_IDLE	0x20
@@ -279,6 +283,33 @@ unsigned long get_board_ddr_clk(void);
 #define I2C_MUX_CH_DEFAULT		0x8
 #define I2C_MUX_CH5			0xD
 
+#define I2C_MUX_CH_VOL_MONITOR          0xA
+
+/* Voltage monitor on channel 2*/
+#define I2C_VOL_MONITOR_ADDR           0x63
+#define I2C_VOL_MONITOR_BUS_V_OFFSET   0x2
+#define I2C_VOL_MONITOR_BUS_V_OVF      0x1
+#define I2C_VOL_MONITOR_BUS_V_SHIFT    3
+#define I2C_SVDD_MONITOR_ADDR           0x4F
+
+#define CONFIG_VID_FLS_ENV              "ls1088aqds_vdd_mv"
+#define CONFIG_VID
+
+/* The lowest and highest voltage allowed for LS1088AQDS */
+#define VDD_MV_MIN			819
+#define VDD_MV_MAX			1212
+
+#define CONFIG_VOL_MONITOR_LTC3882_SET
+#define CONFIG_VOL_MONITOR_LTC3882_READ
+
+/* PM Bus commands code for LTC3882*/
+#define PMBUS_CMD_PAGE                  0x0
+#define PMBUS_CMD_READ_VOUT             0x8B
+#define PMBUS_CMD_PAGE_PLUS_WRITE       0x05
+#define PMBUS_CMD_VOUT_COMMAND          0x21
+
+#define PWM_CHANNEL0                    0x0
+
 /*
 * RTC configuration
 */

+ 29 - 0
include/configs/ls1088ardb.h

@@ -151,6 +151,7 @@
 #endif
 
 #define CONFIG_SYS_I2C_FPGA_ADDR	0x66
+#define QIXIS_BRDCFG4_OFFSET            0x54
 #define QIXIS_LBMAP_SWITCH		2
 #define QIXIS_QMAP_MASK			0xe0
 #define QIXIS_QMAP_SHIFT		5
@@ -159,9 +160,11 @@
 #define QIXIS_LBMAP_DFLTBANK		0x00
 #define QIXIS_LBMAP_ALTBANK		0x20
 #define QIXIS_LBMAP_SD			0x00
+#define QIXIS_LBMAP_EMMC		0x00
 #define QIXIS_LBMAP_SD_QSPI		0x00
 #define QIXIS_LBMAP_QSPI		0x00
 #define QIXIS_RCW_SRC_SD		0x40
+#define QIXIS_RCW_SRC_EMMC		0x41
 #define QIXIS_RCW_SRC_QSPI		0x62
 #define QIXIS_RST_CTL_RESET		0x31
 #define QIXIS_RCFG_CTL_RECONFIG_IDLE	0x20
@@ -225,6 +228,32 @@
 
 #define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000
 
+#define I2C_MUX_CH_VOL_MONITOR          0xA
+/* Voltage monitor on channel 2*/
+#define I2C_VOL_MONITOR_ADDR           0x63
+#define I2C_VOL_MONITOR_BUS_V_OFFSET   0x2
+#define I2C_VOL_MONITOR_BUS_V_OVF      0x1
+#define I2C_VOL_MONITOR_BUS_V_SHIFT    3
+#define I2C_SVDD_MONITOR_ADDR		0x4F
+
+#define CONFIG_VID_FLS_ENV              "ls1088ardb_vdd_mv"
+#define CONFIG_VID
+
+/* The lowest and highest voltage allowed for LS1088ARDB */
+#define VDD_MV_MIN			819
+#define VDD_MV_MAX			1212
+
+#define CONFIG_VOL_MONITOR_LTC3882_SET
+#define CONFIG_VOL_MONITOR_LTC3882_READ
+
+/* PM Bus commands code for LTC3882*/
+#define PMBUS_CMD_PAGE                  0x0
+#define PMBUS_CMD_READ_VOUT             0x8B
+#define PMBUS_CMD_PAGE_PLUS_WRITE       0x05
+#define PMBUS_CMD_VOUT_COMMAND          0x21
+
+#define PWM_CHANNEL0                    0x0
+
 /*
  * I2C bus multiplexer
  */