Merge git://git.denx.de/u-boot-sunxi
diff --git a/MAINTAINERS b/MAINTAINERS
index 754db55..d459153 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -287,9 +287,10 @@
S: Maintained
T: git git://github.com/agraf/u-boot.git
F: include/efi*
-F: lib/efi*
+F: lib/efi*/
F: test/py/tests/test_efi*
F: cmd/bootefi.c
+F: tools/file2include.c
FLATTENED DEVICE TREE
M: Simon Glass <sjg@chromium.org>
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
index 179cac6..9ee0dd2 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
@@ -158,6 +158,293 @@
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)
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
index dc4a437..b9f837d 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
@@ -363,6 +363,45 @@
}
#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)
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c
index 1c694e7..4093d15 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c
@@ -85,6 +85,9 @@
#ifdef CONFIG_SPL_I2C_SUPPORT
i2c_init_all();
#endif
+#ifdef CONFIG_VID
+ init_func_vid();
+#endif
dram_init();
#ifdef CONFIG_SPL_FSL_LS_PPA
#ifndef CONFIG_SYS_MEM_RESERVE_SECURE
diff --git a/arch/arm/dts/fsl-ls1012a-frdm.dts b/arch/arm/dts/fsl-ls1012a-frdm.dts
index 983e599..6ea5f82 100644
--- a/arch/arm/dts/fsl-ls1012a-frdm.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1012a-frdm.dtsi b/arch/arm/dts/fsl-ls1012a-frdm.dtsi
index 25dcdd2..d453f5d 100644
--- a/arch/arm/dts/fsl-ls1012a-frdm.dtsi
+++ b/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"
diff --git a/arch/arm/dts/fsl-ls1012a-qds.dts b/arch/arm/dts/fsl-ls1012a-qds.dts
index 76db36c..ccc9023 100644
--- a/arch/arm/dts/fsl-ls1012a-qds.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1012a-qds.dtsi b/arch/arm/dts/fsl-ls1012a-qds.dtsi
index d17cd99..908fbed 100644
--- a/arch/arm/dts/fsl-ls1012a-qds.dtsi
+++ b/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"
diff --git a/arch/arm/dts/fsl-ls1012a-rdb.dts b/arch/arm/dts/fsl-ls1012a-rdb.dts
index f683812..400cd9e 100644
--- a/arch/arm/dts/fsl-ls1012a-rdb.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1012a-rdb.dtsi b/arch/arm/dts/fsl-ls1012a-rdb.dtsi
index bf407ae..c4b6adf 100644
--- a/arch/arm/dts/fsl-ls1012a-rdb.dtsi
+++ b/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"
diff --git a/arch/arm/dts/fsl-ls1012a.dtsi b/arch/arm/dts/fsl-ls1012a.dtsi
index 23b3cec..215e095 100644
--- a/arch/arm/dts/fsl-ls1012a.dtsi
+++ b/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"
diff --git a/arch/arm/dts/fsl-ls1043a-qds-duart.dts b/arch/arm/dts/fsl-ls1043a-qds-duart.dts
index 2124e38..cf53ab0 100644
--- a/arch/arm/dts/fsl-ls1043a-qds-duart.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1043a-qds-lpuart.dts b/arch/arm/dts/fsl-ls1043a-qds-lpuart.dts
index 18adb97..118c45d 100644
--- a/arch/arm/dts/fsl-ls1043a-qds-lpuart.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1043a-qds.dtsi b/arch/arm/dts/fsl-ls1043a-qds.dtsi
index 2101172..9611619 100644
--- a/arch/arm/dts/fsl-ls1043a-qds.dtsi
+++ b/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"
diff --git a/arch/arm/dts/fsl-ls1043a-rdb.dts b/arch/arm/dts/fsl-ls1043a-rdb.dts
index f271e71..27670a8 100644
--- a/arch/arm/dts/fsl-ls1043a-rdb.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1043a.dtsi b/arch/arm/dts/fsl-ls1043a.dtsi
index fe6698f..3cc2077 100644
--- a/arch/arm/dts/fsl-ls1043a.dtsi
+++ b/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"
diff --git a/arch/arm/dts/fsl-ls1046a-qds-duart.dts b/arch/arm/dts/fsl-ls1046a-qds-duart.dts
index 10a95ea..9a4b84f 100644
--- a/arch/arm/dts/fsl-ls1046a-qds-duart.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1046a-qds-lpuart.dts b/arch/arm/dts/fsl-ls1046a-qds-lpuart.dts
index 21243d0..1c4d362 100644
--- a/arch/arm/dts/fsl-ls1046a-qds-lpuart.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1046a-qds.dtsi b/arch/arm/dts/fsl-ls1046a-qds.dtsi
index a49ca08..4e1920b 100644
--- a/arch/arm/dts/fsl-ls1046a-qds.dtsi
+++ b/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"
diff --git a/arch/arm/dts/fsl-ls1046a-rdb.dts b/arch/arm/dts/fsl-ls1046a-rdb.dts
index 4902454..646e477 100644
--- a/arch/arm/dts/fsl-ls1046a-rdb.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1046a.dtsi b/arch/arm/dts/fsl-ls1046a.dtsi
index 408e81e..f46707d 100644
--- a/arch/arm/dts/fsl-ls1046a.dtsi
+++ b/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"
diff --git a/arch/arm/dts/fsl-ls1088a-qds.dts b/arch/arm/dts/fsl-ls1088a-qds.dts
index 9b7bef4..225c7c5 100644
--- a/arch/arm/dts/fsl-ls1088a-qds.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1088a-rdb.dts b/arch/arm/dts/fsl-ls1088a-rdb.dts
index 30ceed8..7b6ca1d 100644
--- a/arch/arm/dts/fsl-ls1088a-rdb.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls1088a.dtsi b/arch/arm/dts/fsl-ls1088a.dtsi
index 64b4fcf..f8f8654 100644
--- a/arch/arm/dts/fsl-ls1088a.dtsi
+++ b/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
*/
/ {
diff --git a/arch/arm/dts/fsl-ls2080a-qds.dts b/arch/arm/dts/fsl-ls2080a-qds.dts
index 0a7f1ff..b85b802 100644
--- a/arch/arm/dts/fsl-ls2080a-qds.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls2080a-rdb.dts b/arch/arm/dts/fsl-ls2080a-rdb.dts
index 1a1813b..04b1a71 100644
--- a/arch/arm/dts/fsl-ls2080a-rdb.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls2080a.dtsi b/arch/arm/dts/fsl-ls2080a.dtsi
index 79047d5..69273a9 100644
--- a/arch/arm/dts/fsl-ls2080a.dtsi
+++ b/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
*/
/ {
diff --git a/arch/arm/dts/fsl-ls2081a-rdb.dts b/arch/arm/dts/fsl-ls2081a-rdb.dts
index aa4aa68..ef668a3 100644
--- a/arch/arm/dts/fsl-ls2081a-rdb.dts
+++ b/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/;
diff --git a/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts b/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts
index 3230e7e..9e3875d 100644
--- a/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts
+++ b/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/;
diff --git a/arch/arm/dts/keystone-k2g-evm.dts b/arch/arm/dts/keystone-k2g-evm.dts
index de208b3..ad746c7 100644
--- a/arch/arm/dts/keystone-k2g-evm.dts
+++ b/arch/arm/dts/keystone-k2g-evm.dts
@@ -68,46 +68,45 @@
&qspi {
status = "okay";
- flash0: m25p80@0 {
- compatible = "s25fl512s","spi-flash";
- reg = <0>;
- spi-tx-bus-width = <1>;
- spi-rx-bus-width = <4>;
- spi-max-frequency = <96000000>;
- #address-cells = <1>;
- #size-cells = <1>;
- tshsl-ns = <392>;
- tsd2d-ns = <392>;
- tchsh-ns = <100>;
- tslch-ns = <100>;
+ flash0: m25p80@0 {
+ compatible = "s25fl512s","spi-flash";
+ reg = <0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <96000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cdns,tshsl-ns = <392>;
+ cdns,tsd2d-ns = <392>;
+ cdns,tchsh-ns = <100>;
+ cdns,tslch-ns = <100>;
block-size = <18>;
-
- partition@0 {
- label = "QSPI.u-boot-spl-os";
- reg = <0x00000000 0x00100000>;
- };
- partition@1 {
- label = "QSPI.u-boot-env";
- reg = <0x00100000 0x00040000>;
- };
- partition@2 {
- label = "QSPI.skern";
- reg = <0x00140000 0x0040000>;
- };
- partition@3 {
- label = "QSPI.pmmc-firmware";
- reg = <0x00180000 0x0040000>;
- };
- partition@4 {
- label = "QSPI.kernel";
- reg = <0x001C0000 0x0800000>;
- };
- partition@5 {
- label = "QSPI.file-system";
- reg = <0x009C0000 0x3640000>;
- };
- };
+ partition@0 {
+ label = "QSPI.u-boot-spl-os";
+ reg = <0x00000000 0x00100000>;
+ };
+ partition@1 {
+ label = "QSPI.u-boot-env";
+ reg = <0x00100000 0x00040000>;
+ };
+ partition@2 {
+ label = "QSPI.skern";
+ reg = <0x00140000 0x0040000>;
+ };
+ partition@3 {
+ label = "QSPI.pmmc-firmware";
+ reg = <0x00180000 0x0040000>;
+ };
+ partition@4 {
+ label = "QSPI.kernel";
+ reg = <0x001C0000 0x0800000>;
+ };
+ partition@5 {
+ label = "QSPI.file-system";
+ reg = <0x009C0000 0x3640000>;
+ };
+ };
};
&mmc0 {
diff --git a/arch/arm/dts/keystone-k2g.dtsi b/arch/arm/dts/keystone-k2g.dtsi
index 7b2fae6..9bcfea6 100644
--- a/arch/arm/dts/keystone-k2g.dtsi
+++ b/arch/arm/dts/keystone-k2g.dtsi
@@ -92,8 +92,9 @@
<0x24000000 0x4000000>;
interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_RISING>;
num-cs = <4>;
- fifo-depth = <256>;
- sram-size = <256>;
+ cdns,fifo-depth = <256>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x24000000>;
status = "disabled";
};
diff --git a/arch/arm/dts/socfpga.dtsi b/arch/arm/dts/socfpga.dtsi
index 8588221..7557aa0 100644
--- a/arch/arm/dts/socfpga.dtsi
+++ b/arch/arm/dts/socfpga.dtsi
@@ -644,8 +644,9 @@
clocks = <&qspi_clk>;
ext-decoder = <0>; /* external decoder */
num-cs = <4>;
- fifo-depth = <128>;
- sram-size = <128>;
+ cdns,fifo-depth = <128>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x00000000>;
bus-num = <2>;
status = "disabled";
};
diff --git a/arch/arm/dts/socfpga_arria10.dtsi b/arch/arm/dts/socfpga_arria10.dtsi
index 377700d..abfd0bc 100644
--- a/arch/arm/dts/socfpga_arria10.dtsi
+++ b/arch/arm/dts/socfpga_arria10.dtsi
@@ -734,8 +734,8 @@
clocks = <&l4_main_clk>;
ext-decoder = <0>; /* external decoder */
num-chipselect = <4>;
- fifo-depth = <128>;
- sram-size = <512>;
+ cdns,fifo-depth = <128>;
+ cdns,fifo-width = <4>;
bus-num = <2>;
status = "disabled";
};
diff --git a/arch/arm/dts/socfpga_arria5_socdk.dts b/arch/arm/dts/socfpga_arria5_socdk.dts
index 7265058..1e91a65 100644
--- a/arch/arm/dts/socfpga_arria5_socdk.dts
+++ b/arch/arm/dts/socfpga_arria5_socdk.dts
@@ -94,10 +94,9 @@
m25p,fast-read;
page-size = <256>;
block-size = <16>; /* 2^16, 64KB */
- read-delay = <4>; /* delay value in read data capture register */
- tshsl-ns = <50>;
- tsd2d-ns = <50>;
- tchsh-ns = <4>;
- tslch-ns = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
};
};
diff --git a/arch/arm/dts/socfpga_cyclone5_is1.dts b/arch/arm/dts/socfpga_cyclone5_is1.dts
index 16a3283..2e2b71f 100644
--- a/arch/arm/dts/socfpga_cyclone5_is1.dts
+++ b/arch/arm/dts/socfpga_cyclone5_is1.dts
@@ -93,11 +93,10 @@
m25p,fast-read;
page-size = <256>;
block-size = <16>; /* 2^16, 64KB */
- read-delay = <4>; /* delay value in read data capture register */
- tshsl-ns = <50>;
- tsd2d-ns = <50>;
- tchsh-ns = <4>;
- tslch-ns = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
};
};
diff --git a/arch/arm/dts/socfpga_cyclone5_socdk.dts b/arch/arm/dts/socfpga_cyclone5_socdk.dts
index f175ef2..95a8e65 100644
--- a/arch/arm/dts/socfpga_cyclone5_socdk.dts
+++ b/arch/arm/dts/socfpga_cyclone5_socdk.dts
@@ -104,11 +104,10 @@
m25p,fast-read;
page-size = <256>;
block-size = <16>; /* 2^16, 64KB */
- read-delay = <4>; /* delay value in read data capture register */
- tshsl-ns = <50>;
- tsd2d-ns = <50>;
- tchsh-ns = <4>;
- tslch-ns = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
};
};
diff --git a/arch/arm/dts/socfpga_cyclone5_sockit.dts b/arch/arm/dts/socfpga_cyclone5_sockit.dts
index e45c2ab..6f42b88 100644
--- a/arch/arm/dts/socfpga_cyclone5_sockit.dts
+++ b/arch/arm/dts/socfpga_cyclone5_sockit.dts
@@ -84,11 +84,10 @@
m25p,fast-read;
page-size = <256>;
block-size = <16>; /* 2^16, 64KB */
- read-delay = <4>; /* delay value in read data capture register */
- tshsl-ns = <50>;
- tsd2d-ns = <50>;
- tchsh-ns = <4>;
- tslch-ns = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
};
};
diff --git a/arch/arm/dts/socfpga_cyclone5_socrates.dts b/arch/arm/dts/socfpga_cyclone5_socrates.dts
index bdd9324..e3ae8a8 100644
--- a/arch/arm/dts/socfpga_cyclone5_socrates.dts
+++ b/arch/arm/dts/socfpga_cyclone5_socrates.dts
@@ -74,11 +74,10 @@
m25p,fast-read;
page-size = <256>;
block-size = <16>; /* 2^16, 64KB */
- read-delay = <4>; /* delay value in read data capture register */
- tshsl-ns = <50>;
- tsd2d-ns = <50>;
- tchsh-ns = <4>;
- tslch-ns = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
};
};
diff --git a/arch/arm/dts/socfpga_cyclone5_sr1500.dts b/arch/arm/dts/socfpga_cyclone5_sr1500.dts
index 739bbb7..e24830a 100644
--- a/arch/arm/dts/socfpga_cyclone5_sr1500.dts
+++ b/arch/arm/dts/socfpga_cyclone5_sr1500.dts
@@ -92,10 +92,9 @@
m25p,fast-read;
page-size = <256>;
block-size = <16>; /* 2^16, 64KB */
- read-delay = <4>; /* delay value in read data capture register */
- tshsl-ns = <50>;
- tsd2d-ns = <50>;
- tchsh-ns = <4>;
- tslch-ns = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
};
};
diff --git a/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts b/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts
index f168e4f..a0febe9 100644
--- a/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts
+++ b/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts
@@ -79,11 +79,10 @@
m25p,fast-read;
page-size = <256>;
block-size = <16>; /* 2^16, 64KB */
- read-delay = <4>; /* delay value in read data capture register */
- tshsl-ns = <50>;
- tsd2d-ns = <50>;
- tchsh-ns = <4>;
- tslch-ns = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
};
flash1: n25q00@1 {
@@ -96,11 +95,10 @@
m25p,fast-read;
page-size = <256>;
block-size = <16>; /* 2^16, 64KB */
- read-delay = <4>; /* delay value in read data capture register */
- tshsl-ns = <50>;
- tsd2d-ns = <50>;
- tchsh-ns = <4>;
- tslch-ns = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
};
};
diff --git a/arch/arm/dts/stv0991.dts b/arch/arm/dts/stv0991.dts
index fa3fd64..bceac09 100644
--- a/arch/arm/dts/stv0991.dts
+++ b/arch/arm/dts/stv0991.dts
@@ -32,7 +32,9 @@
reg = <0x80203000 0x100>,
<0x40000000 0x1000000>;
clocks = <3750000>;
- sram-size = <256>;
+ cdns,fifo-depth = <256>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x40000000>;
status = "okay";
flash0: n25q32@0 {
@@ -44,10 +46,10 @@
m25p,fast-read;
page-size = <256>;
block-size = <16>; /* 2^16, 64KB */
- tshsl-ns = <50>;
- tsd2d-ns = <50>;
- tchsh-ns = <4>;
- tslch-ns = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
};
};
};
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h b/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
index 12fd6b8..9becdf3 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
@@ -164,6 +164,7 @@
#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 @@
/* The target volt of SVDD in unit mV */
int setup_serdes_volt(u32 svdd);
#endif
-#endif
#endif /* __FSL_SERDES_H__ */
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
index 957e23b..642df2f 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
@@ -201,10 +201,15 @@
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 @@
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_ */
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/soc.h b/arch/arm/include/asm/arch-fsl-layerscape/soc.h
index 1e65e4e..cb760b5 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/soc.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/soc.h
@@ -121,6 +121,7 @@
#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);
diff --git a/arch/arm/include/asm/arch-mvebu/spi.h b/arch/arm/include/asm/arch-mvebu/spi.h
index 3545aed..1de510e 100644
--- a/arch/arm/include/asm/arch-mvebu/spi.h
+++ b/arch/arm/include/asm/arch-mvebu/spi.h
@@ -57,6 +57,12 @@
#define KWSPI_TXLSBF (1 << 13)
#define KWSPI_RXLSBF (1 << 14)
+/* Timing Parameters 1 Register */
+#define KW_SPI_TMISO_SAMPLE_OFFSET 6
+#define KW_SPI_TMISO_SAMPLE_MASK (0x3 << KW_SPI_TMISO_SAMPLE_OFFSET)
+#define KW_SPI_TMISO_SAMPLE_1 (1 << KW_SPI_TMISO_SAMPLE_OFFSET)
+#define KW_SPI_TMISO_SAMPLE_2 (2 << KW_SPI_TMISO_SAMPLE_OFFSET)
+
#define KWSPI_IRQUNMASK 1 /* unmask SPI interrupt */
#define KWSPI_IRQMASK 0 /* mask SPI interrupt */
#define KWSPI_SMEMRDIRQ 1 /* SerMem data xfer ready irq */
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index abffa10..876024f 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -112,4 +112,5 @@
CFLAGS_REMOVE_$(EFI_RELOC) := $(CFLAGS_NON_EFI)
extra-$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE) += $(EFI_CRT0) $(EFI_RELOC)
+extra-$(CONFIG_CMD_BOOTEFI_SELFTEST) += $(EFI_CRT0) $(EFI_RELOC)
extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC)
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 35e4e9b..51a70e0 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -6,47 +6,63 @@
config TARGET_IPAM390
bool "IPAM390 board"
+ select MACH_DAVINCI_DA850_EVM
+ select SOC_DA850
select SUPPORT_SPL
- select SYS_DA850_PLL_INIT
- select SYS_DA850_DDR_INIT
config TARGET_DA850EVM
bool "DA850 EVM board"
+ select MACH_DAVINCI_DA850_EVM
+ select SOC_DA850
select SUPPORT_SPL
- select SYS_DA850_PLL_INIT
- select SYS_DA850_DDR_INIT
config TARGET_EA20
bool "EA20 board"
+ select MACH_DAVINCI_DA850_EVM
+ select SOC_DA850
select BOARD_LATE_INIT
config TARGET_OMAPL138_LCDK
bool "OMAPL138 LCDK"
+ select SOC_DA8XX
select SUPPORT_SPL
- select SYS_DA850_PLL_INIT
- select SYS_DA850_DDR_INIT
config TARGET_CALIMAIN
bool "Calimain board"
- select SYS_DA850_PLL_INIT
- select SYS_DA850_DDR_INIT
+ select SOC_DA850
config TARGET_LEGOEV3
bool "LEGO MINDSTORMS EV3"
- select SYS_DA850_PLL_INIT
- select SYS_DA850_DDR_INIT
+ select MACH_DAVINCI_DA850_EVM
+ select SOC_DA850
endchoice
config SYS_SOC
default "davinci"
+config DA850_LOWLEVEL
+ bool "Enable Lowlevel DA850 initialization"
+ depends on SOC_DA850
+
config SYS_DA850_PLL_INIT
bool
config SYS_DA850_DDR_INIT
bool
+config SOC_DA850
+ bool
+ select SOC_DA8XX
+ select SYS_DA850_DDR_INIT if SUPPORT_SPL || DA850_LOWLEVEL
+
+config SOC_DA8XX
+ bool
+ select SYS_DA850_PLL_INIT if SUPPORT_SPL || DA850_LOWLEVEL
+
+config MACH_DAVINCI_DA850_EVM
+ bool
+
source "board/Barix/ipam390/Kconfig"
source "board/davinci/da8xxevm/Kconfig"
source "board/davinci/ea20/Kconfig"
diff --git a/arch/arm/mach-imx/mx6/ddr.c b/arch/arm/mach-imx/mx6/ddr.c
index 39dbd2f..43b77cf 100644
--- a/arch/arm/mach-imx/mx6/ddr.c
+++ b/arch/arm/mach-imx/mx6/ddr.c
@@ -21,10 +21,10 @@
/* Reset data FIFOs twice. */
setbits_le32(&mmdc0->mpdgctrl0, 1 << 31);
- wait_for_bit("MMDC", &mmdc0->mpdgctrl0, 1 << 31, 0, 100, 0);
+ wait_for_bit_le32(&mmdc0->mpdgctrl0, 1 << 31, 0, 100, 0);
setbits_le32(&mmdc0->mpdgctrl0, 1 << 31);
- wait_for_bit("MMDC", &mmdc0->mpdgctrl0, 1 << 31, 0, 100, 0);
+ wait_for_bit_le32(&mmdc0->mpdgctrl0, 1 << 31, 0, 100, 0);
}
static void precharge_all(const bool cs0_enable, const bool cs1_enable)
@@ -39,12 +39,12 @@
*/
if (cs0_enable) { /* CS0 */
writel(0x04008050, &mmdc0->mdscr);
- wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 1, 100, 0);
+ wait_for_bit_le32(&mmdc0->mdscr, 1 << 14, 1, 100, 0);
}
if (cs1_enable) { /* CS1 */
writel(0x04008058, &mmdc0->mdscr);
- wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 1, 100, 0);
+ wait_for_bit_le32(&mmdc0->mdscr, 1 << 14, 1, 100, 0);
}
}
@@ -146,7 +146,7 @@
* 7. Upon completion of this process the MMDC de-asserts
* the MPWLGCR[HW_WL_EN]
*/
- wait_for_bit("MMDC", &mmdc0->mpwlgcr, 1 << 0, 0, 100, 0);
+ wait_for_bit_le32(&mmdc0->mpwlgcr, 1 << 0, 0, 100, 0);
/*
* 8. check for any errors: check both PHYs for x64 configuration,
@@ -278,7 +278,7 @@
writel(0x00008028, &mmdc0->mdscr);
/* poll to make sure the con_ack bit was asserted */
- wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 1, 100, 0);
+ wait_for_bit_le32(&mmdc0->mdscr, 1 << 14, 1, 100, 0);
/*
* Check MDMISC register CALIB_PER_CS to see which CS calibration
@@ -312,7 +312,7 @@
* this bit until it clears to indicate completion of the write access.
*/
setbits_le32(&mmdc0->mpswdar0, 1);
- wait_for_bit("MMDC", &mmdc0->mpswdar0, 1 << 0, 0, 100, 0);
+ wait_for_bit_le32(&mmdc0->mpswdar0, 1 << 0, 0, 100, 0);
/* Set the RD_DL_ABS# bits to their default values
* (will be calibrated later in the read delay-line calibration).
@@ -359,7 +359,7 @@
setbits_le32(&mmdc0->mpdgctrl0, 5 << 28);
/* Poll for completion. MPDGCTRL0[HW_DG_EN] should be 0 */
- wait_for_bit("MMDC", &mmdc0->mpdgctrl0, 1 << 28, 0, 100, 0);
+ wait_for_bit_le32(&mmdc0->mpdgctrl0, 1 << 28, 0, 100, 0);
/*
* Check to see if any errors were encountered during calibration
@@ -423,7 +423,7 @@
* setting MPRDDLHWCTL[HW_RD_DL_EN] = 0. Also, ensure that
* no error bits were set.
*/
- wait_for_bit("MMDC", &mmdc0->mprddlhwctl, 1 << 4, 0, 100, 0);
+ wait_for_bit_le32(&mmdc0->mprddlhwctl, 1 << 4, 0, 100, 0);
/* check both PHYs for x64 configuration, if x32, check only PHY0 */
if (readl(&mmdc0->mprddlhwctl) & 0x0000000f)
@@ -477,7 +477,7 @@
* by setting MPWRDLHWCTL[HW_WR_DL_EN] = 0.
* Also, ensure that no error bits were set.
*/
- wait_for_bit("MMDC", &mmdc0->mpwrdlhwctl, 1 << 4, 0, 100, 0);
+ wait_for_bit_le32(&mmdc0->mpwrdlhwctl, 1 << 4, 0, 100, 0);
/* Check both PHYs for x64 configuration, if x32, check only PHY0 */
if (readl(&mmdc0->mpwrdlhwctl) & 0x0000000f)
@@ -526,7 +526,7 @@
writel(0x0, &mmdc0->mdscr); /* CS0 */
/* Poll to make sure the con_ack bit is clear */
- wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 0, 100, 0);
+ wait_for_bit_le32(&mmdc0->mdscr, 1 << 14, 0, 100, 0);
/*
* Print out the registers that were updated as a result
diff --git a/arch/arm/mach-socfpga/clock_manager.c b/arch/arm/mach-socfpga/clock_manager.c
index 6b76221..43e72a8 100644
--- a/arch/arm/mach-socfpga/clock_manager.c
+++ b/arch/arm/mach-socfpga/clock_manager.c
@@ -37,8 +37,8 @@
/* function to poll in the fsm busy bit */
int cm_wait_for_fsm(void)
{
- return wait_for_bit(__func__, (const u32 *)&clock_manager_base->stat,
- CLKMGR_STAT_BUSY, false, 20000, false);
+ return wait_for_bit_le32(&clock_manager_base->stat,
+ CLKMGR_STAT_BUSY, false, 20000, false);
}
int set_cpu_clk_info(void)
diff --git a/arch/arm/mach-socfpga/clock_manager_arria10.c b/arch/arm/mach-socfpga/clock_manager_arria10.c
index 482b854..623a266 100644
--- a/arch/arm/mach-socfpga/clock_manager_arria10.c
+++ b/arch/arm/mach-socfpga/clock_manager_arria10.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <fdtdec.h>
#include <asm/io.h>
+#include <dm.h>
#include <asm/arch/clock_manager.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -1076,6 +1077,14 @@
return cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB);
}
+/* Override weak dw_spi_get_clk implementation in designware_spi.c driver */
+int dw_spi_get_clk(struct udevice *bus, ulong *rate)
+{
+ *rate = cm_get_spi_controller_clk_hz();
+
+ return 0;
+}
+
void cm_print_clock_quick_summary(void)
{
printf("MPU %10ld kHz\n", cm_get_mpu_clk_hz() / 1000);
diff --git a/arch/arm/mach-socfpga/clock_manager_gen5.c b/arch/arm/mach-socfpga/clock_manager_gen5.c
index 31fd510..4e5b6d1 100644
--- a/arch/arm/mach-socfpga/clock_manager_gen5.c
+++ b/arch/arm/mach-socfpga/clock_manager_gen5.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <asm/io.h>
+#include <dm.h>
#include <asm/arch/clock_manager.h>
#include <wait_bit.h>
@@ -32,20 +33,18 @@
}
/* function to write a clock register that has phase information */
-static int cm_write_with_phase(u32 value, u32 reg_address, u32 mask)
+static int cm_write_with_phase(u32 value, const void *reg_address, u32 mask)
{
int ret;
/* poll until phase is zero */
- ret = wait_for_bit(__func__, (const u32 *)reg_address, mask,
- false, 20000, false);
+ ret = wait_for_bit_le32(reg_address, mask, false, 20000, false);
if (ret)
return ret;
writel(value, reg_address);
- return wait_for_bit(__func__, (const u32 *)reg_address, mask,
- false, 20000, false);
+ return wait_for_bit_le32(reg_address, mask, false, 20000, false);
}
/*
@@ -269,26 +268,26 @@
* are aligned nicely; so we can change any phase.
*/
ret = cm_write_with_phase(cfg->ddrdqsclk,
- (u32)&clock_manager_base->sdr_pll.ddrdqsclk,
+ &clock_manager_base->sdr_pll.ddrdqsclk,
CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK);
if (ret)
return ret;
/* SDRAM DDR2XDQSCLK */
ret = cm_write_with_phase(cfg->ddr2xdqsclk,
- (u32)&clock_manager_base->sdr_pll.ddr2xdqsclk,
+ &clock_manager_base->sdr_pll.ddr2xdqsclk,
CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK);
if (ret)
return ret;
ret = cm_write_with_phase(cfg->ddrdqclk,
- (u32)&clock_manager_base->sdr_pll.ddrdqclk,
+ &clock_manager_base->sdr_pll.ddrdqclk,
CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK);
if (ret)
return ret;
ret = cm_write_with_phase(cfg->s2fuser2clk,
- (u32)&clock_manager_base->sdr_pll.s2fuser2clk,
+ &clock_manager_base->sdr_pll.s2fuser2clk,
CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK);
if (ret)
return ret;
@@ -509,6 +508,14 @@
return clock;
}
+/* Override weak dw_spi_get_clk implementation in designware_spi.c driver */
+int dw_spi_get_clk(struct udevice *bus, ulong *rate)
+{
+ *rate = cm_get_spi_controller_clk_hz();
+
+ return 0;
+}
+
void cm_print_clock_quick_summary(void)
{
printf("MPU %10ld kHz\n", cm_get_mpu_clk_hz() / 1000);
diff --git a/arch/arm/mach-socfpga/reset_manager_arria10.c b/arch/arm/mach-socfpga/reset_manager_arria10.c
index ae16897..54f0ddb 100644
--- a/arch/arm/mach-socfpga/reset_manager_arria10.c
+++ b/arch/arm/mach-socfpga/reset_manager_arria10.c
@@ -222,8 +222,8 @@
clrbits_le32(&reset_manager_base->brgmodrst, mask_rstmgr);
/* Poll until all idleack to 0, timeout at 1000ms */
- return wait_for_bit(__func__, &sysmgr_regs->noc_idleack, mask_noc,
- false, 1000, false);
+ return wait_for_bit_le32(&sysmgr_regs->noc_idleack, mask_noc,
+ false, 1000, false);
}
void socfpga_reset_assert_fpga_connected_peripherals(void)
@@ -343,26 +343,26 @@
writel(ALT_SYSMGR_NOC_TMO_EN_SET_MSK, &sysmgr_regs->noc_timeout);
/* Poll until all idleack to 1 */
- ret = wait_for_bit(__func__, &sysmgr_regs->noc_idleack,
- ALT_SYSMGR_NOC_H2F_SET_MSK |
- ALT_SYSMGR_NOC_LWH2F_SET_MSK |
- ALT_SYSMGR_NOC_F2H_SET_MSK |
- ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
- ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
- ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
- true, 10000, false);
+ ret = wait_for_bit_le32(&sysmgr_regs->noc_idleack,
+ ALT_SYSMGR_NOC_H2F_SET_MSK |
+ ALT_SYSMGR_NOC_LWH2F_SET_MSK |
+ ALT_SYSMGR_NOC_F2H_SET_MSK |
+ ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
+ ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
+ ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
+ true, 10000, false);
if (ret)
return ret;
/* Poll until all idlestatus to 1 */
- ret = wait_for_bit(__func__, &sysmgr_regs->noc_idlestatus,
- ALT_SYSMGR_NOC_H2F_SET_MSK |
- ALT_SYSMGR_NOC_LWH2F_SET_MSK |
- ALT_SYSMGR_NOC_F2H_SET_MSK |
- ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
- ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
- ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
- true, 10000, false);
+ ret = wait_for_bit_le32(&sysmgr_regs->noc_idlestatus,
+ ALT_SYSMGR_NOC_H2F_SET_MSK |
+ ALT_SYSMGR_NOC_LWH2F_SET_MSK |
+ ALT_SYSMGR_NOC_F2H_SET_MSK |
+ ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
+ ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
+ ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
+ true, 10000, false);
if (ret)
return ret;
diff --git a/arch/m68k/cpu/mcf5227x/cpu.c b/arch/m68k/cpu/mcf5227x/cpu.c
index 7d611de..63cffd3 100644
--- a/arch/m68k/cpu/mcf5227x/cpu.c
+++ b/arch/m68k/cpu/mcf5227x/cpu.c
@@ -28,7 +28,8 @@
return 0;
};
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
ccm_t *ccm = (ccm_t *) MMAP_CCM;
u16 msk;
@@ -60,3 +61,4 @@
return 0;
}
+#endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/arch/m68k/cpu/mcf523x/cpu.c b/arch/m68k/cpu/mcf523x/cpu.c
index 67879c7..2e52939 100644
--- a/arch/m68k/cpu/mcf523x/cpu.c
+++ b/arch/m68k/cpu/mcf523x/cpu.c
@@ -28,7 +28,8 @@
return 0;
}
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
ccm_t *ccm = (ccm_t *) MMAP_CCM;
u16 msk;
@@ -56,6 +57,7 @@
return 0;
};
+#endif /* CONFIG_DISPLAY_CPUINFO */
#if defined(CONFIG_WATCHDOG)
/* Called by macro WATCHDOG_RESET */
diff --git a/arch/m68k/cpu/mcf52x2/cpu.c b/arch/m68k/cpu/mcf52x2/cpu.c
index 5ec7609..7b27133 100644
--- a/arch/m68k/cpu/mcf52x2/cpu.c
+++ b/arch/m68k/cpu/mcf52x2/cpu.c
@@ -37,7 +37,8 @@
return 0;
};
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
char buf1[32], buf2[32];
@@ -47,6 +48,7 @@
strmhz(buf2, gd->bus_clk));
return 0;
};
+#endif /* CONFIG_DISPLAY_CPUINFO */
#if defined(CONFIG_WATCHDOG)
/* Called by macro WATCHDOG_RESET */
@@ -94,12 +96,13 @@
#endif /* #ifdef CONFIG_M5208 */
#ifdef CONFIG_M5271
+#if defined(CONFIG_DISPLAY_CPUINFO)
/*
* Both MCF5270 and MCF5271 are members of the MPC5271 family. Try to
* determine which one we are running on, based on the Chip Identification
* Register (CIR).
*/
-int checkcpu(void)
+int print_cpuinfo(void)
{
char buf[32];
unsigned short cir; /* Chip Identification Register */
@@ -133,6 +136,7 @@
return 0;
}
+#endif /* CONFIG_DISPLAY_CPUINFO */
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
@@ -184,7 +188,8 @@
return 0;
};
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
sysctrl_t *sysctrl = (sysctrl_t *) (MMAP_CFG);
uchar msk;
@@ -209,6 +214,7 @@
printf("Freescale MCF5272 %s\n", suf);
return 0;
};
+#endif /* CONFIG_DISPLAY_CPUINFO */
#if defined(CONFIG_WATCHDOG)
/* Called by macro WATCHDOG_RESET */
@@ -268,7 +274,8 @@
return 0;
};
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
char buf[32];
@@ -276,7 +283,7 @@
strmhz(buf, CONFIG_SYS_CLK));
return 0;
};
-
+#endif /* CONFIG_DISPLAY_CPUINFO */
#if defined(CONFIG_WATCHDOG)
/* Called by macro WATCHDOG_RESET */
@@ -326,7 +333,8 @@
#endif /* #ifdef CONFIG_M5275 */
#ifdef CONFIG_M5282
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
unsigned char resetsource = MCFRESET_RSR;
@@ -342,6 +350,7 @@
(resetsource & MCFRESET_RSR_LVD) ? " Low Voltage" : "");
return 0;
}
+#endif /* CONFIG_DISPLAY_CPUINFO */
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
@@ -351,7 +360,8 @@
#endif
#ifdef CONFIG_M5249
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
char buf[32];
@@ -359,6 +369,7 @@
strmhz(buf, CONFIG_SYS_CLK));
return 0;
}
+#endif /* CONFIG_DISPLAY_CPUINFO */
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
@@ -372,7 +383,8 @@
#endif
#ifdef CONFIG_M5253
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
char buf[32];
@@ -389,6 +401,7 @@
}
return 0;
}
+#endif /* CONFIG_DISPLAY_CPUINFO */
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
diff --git a/arch/m68k/cpu/mcf530x/cpu.c b/arch/m68k/cpu/mcf530x/cpu.c
index 78f4385..3552af2 100644
--- a/arch/m68k/cpu/mcf530x/cpu.c
+++ b/arch/m68k/cpu/mcf530x/cpu.c
@@ -25,7 +25,8 @@
return 0;
}
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
char buf[32];
@@ -33,4 +34,5 @@
strmhz(buf, CONFIG_SYS_CPU_CLK));
return 0;
}
+#endif /* CONFIG_DISPLAY_CPUINFO */
#endif
diff --git a/arch/m68k/cpu/mcf532x/cpu.c b/arch/m68k/cpu/mcf532x/cpu.c
index 46b57e9..602c106 100644
--- a/arch/m68k/cpu/mcf532x/cpu.c
+++ b/arch/m68k/cpu/mcf532x/cpu.c
@@ -30,7 +30,8 @@
return 0;
};
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
ccm_t *ccm = (ccm_t *) MMAP_CCM;
u16 msk;
@@ -95,6 +96,7 @@
return 0;
};
+#endif /* CONFIG_DISPLAY_CPUINFO */
#if defined(CONFIG_WATCHDOG)
/* Called by macro WATCHDOG_RESET */
diff --git a/arch/m68k/cpu/mcf5445x/cpu.c b/arch/m68k/cpu/mcf5445x/cpu.c
index 57bdcfb..5967043 100644
--- a/arch/m68k/cpu/mcf5445x/cpu.c
+++ b/arch/m68k/cpu/mcf5445x/cpu.c
@@ -31,7 +31,8 @@
return 0;
};
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
ccm_t *ccm = (ccm_t *) MMAP_CCM;
u16 msk;
@@ -100,6 +101,7 @@
return 0;
}
+#endif /* CONFIG_DISPLAY_CPUINFO */
#if defined(CONFIG_MCFFEC)
/* Default initializations for MCFFEC controllers. To override,
diff --git a/arch/m68k/cpu/mcf547x_8x/cpu.c b/arch/m68k/cpu/mcf547x_8x/cpu.c
index b1ca5c6..9980967 100644
--- a/arch/m68k/cpu/mcf547x_8x/cpu.c
+++ b/arch/m68k/cpu/mcf547x_8x/cpu.c
@@ -34,7 +34,8 @@
return 1;
};
-int checkcpu(void)
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
{
siu_t *siu = (siu_t *) MMAP_SIU;
u16 id = 0;
@@ -91,6 +92,7 @@
return 0;
};
+#endif /* CONFIG_DISPLAY_CPUINFO */
#if defined(CONFIG_HW_WATCHDOG)
/* Called by macro WATCHDOG_RESET */
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index a190485..840dbf1 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -8,9 +8,11 @@
dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb
dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb
dtb-$(CONFIG_TARGET_XILFPGA) += nexys4ddr.dtb
+dtb-$(CONFIG_BOARD_COMTREND_AR5315U) += comtrend,ar-5315u.dtb
dtb-$(CONFIG_BOARD_COMTREND_AR5387UN) += comtrend,ar-5387un.dtb
dtb-$(CONFIG_BOARD_COMTREND_CT5361) += comtrend,ct-5361.dtb
dtb-$(CONFIG_BOARD_COMTREND_VR3032U) += comtrend,vr-3032u.dtb
+dtb-$(CONFIG_BOARD_COMTREND_WAP5813N) += comtrend,wap-5813n.dtb
dtb-$(CONFIG_BOARD_HUAWEI_HG556A) += huawei,hg556a.dtb
dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
dtb-$(CONFIG_BOARD_SAGEM_FAST1704) += sagem,f@st1704.dtb
diff --git a/arch/mips/dts/brcm,bcm3380.dtsi b/arch/mips/dts/brcm,bcm3380.dtsi
index 64245eb..f83a6ea 100644
--- a/arch/mips/dts/brcm,bcm3380.dtsi
+++ b/arch/mips/dts/brcm,bcm3380.dtsi
@@ -12,6 +12,10 @@
/ {
compatible = "brcm,bcm3380";
+ aliases {
+ spi0 = &spi;
+ };
+
cpus {
reg = <0x14e00000 0x4>;
#address-cells = <1>;
@@ -142,6 +146,19 @@
status = "disabled";
};
+ spi: spi@14e02000 {
+ compatible = "brcm,bcm6358-spi";
+ reg = <0x14e02000 0x70c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&periph_clk0 BCM3380_CLK0_SPI>;
+ resets = <&periph_rst0 BCM3380_RST0_SPI>;
+ spi-max-frequency = <25000000>;
+ num-cs = <6>;
+
+ status = "disabled";
+ };
+
leds: led-controller@14e00f00 {
compatible = "brcm,bcm6328-leds";
reg = <0x14e00f00 0x1c>;
diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi
new file mode 100644
index 0000000..54964a7
--- /dev/null
+++ b/arch/mips/dts/brcm,bcm6318.dtsi
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <dt-bindings/clock/bcm6318-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/power-domain/bcm6318-power-domain.h>
+#include <dt-bindings/reset/bcm6318-reset.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "brcm,bcm6318";
+
+ aliases {
+ spi0 = &spi;
+ };
+
+ cpus {
+ reg = <0x10000000 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ u-boot,dm-pre-reloc;
+
+ cpu@0 {
+ compatible = "brcm,bcm6318-cpu", "mips,mips4Kc";
+ device_type = "cpu";
+ reg = <0>;
+ u-boot,dm-pre-reloc;
+ };
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ u-boot,dm-pre-reloc;
+
+ hsspi_pll: hsspi-pll {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <250000000>;
+ };
+
+ periph_osc: periph-osc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <50000000>;
+ u-boot,dm-pre-reloc;
+ };
+
+ periph_clk: periph-clk {
+ compatible = "brcm,bcm6345-clk";
+ reg = <0x10000004 0x4>;
+ #clock-cells = <1>;
+ };
+ };
+
+ ubus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ u-boot,dm-pre-reloc;
+
+ periph_rst: reset-controller@10000010 {
+ compatible = "brcm,bcm6345-reset";
+ reg = <0x10000010 0x4>;
+ #reset-cells = <1>;
+ };
+
+ wdt: watchdog@10000068 {
+ compatible = "brcm,bcm6345-wdt";
+ reg = <0x10000068 0xc>;
+ clocks = <&periph_osc>;
+ };
+
+ wdt-reboot {
+ compatible = "wdt-reboot";
+ wdt = <&wdt>;
+ };
+
+ pll_cntl: syscon@10000074 {
+ compatible = "syscon";
+ reg = <0x10000074 0x4>;
+ };
+
+ syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&pll_cntl>;
+ offset = <0x0>;
+ mask = <0x1>;
+ };
+
+ gpio1: gpio-controller@10000080 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x10000080 0x4>, <0x10000088 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <18>;
+
+ status = "disabled";
+ };
+
+ gpio0: gpio-controller@10000084 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x10000084 0x4>, <0x1000008c 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ uart0: serial@10000100 {
+ compatible = "brcm,bcm6345-uart";
+ reg = <0x10000100 0x18>;
+ clocks = <&periph_osc>;
+
+ status = "disabled";
+ };
+
+ leds: led-controller@10000200 {
+ compatible = "brcm,bcm6328-leds";
+ reg = <0x10000200 0x28>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ periph_pwr: power-controller@100008e8 {
+ compatible = "brcm,bcm6328-power-domain";
+ reg = <0x100008e8 0x4>;
+ #power-domain-cells = <1>;
+ };
+
+ spi: spi@10003000 {
+ compatible = "brcm,bcm6328-hsspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10003000 0x600>;
+ clocks = <&periph_clk BCM6318_CLK_HSSPI>, <&hsspi_pll>;
+ clock-names = "hsspi", "pll";
+ resets = <&periph_rst BCM6318_RST_SPI>;
+ spi-max-frequency = <33333334>;
+ num-cs = <3>;
+
+ status = "disabled";
+ };
+
+ memory-controller@10004000 {
+ compatible = "brcm,bcm6318-mc";
+ reg = <0x10004000 0x38>;
+ u-boot,dm-pre-reloc;
+ };
+ };
+};
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi
index 113a96b..4d4e36c 100644
--- a/arch/mips/dts/brcm,bcm63268.dtsi
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -13,6 +13,11 @@
/ {
compatible = "brcm,bcm63268";
+ aliases {
+ spi0 = &lsspi;
+ spi1 = &hsspi;
+ };
+
cpus {
reg = <0x10000000 0x4>;
#address-cells = <1>;
@@ -40,6 +45,12 @@
#size-cells = <1>;
u-boot,dm-pre-reloc;
+ hsspi_pll: hsspi-pll {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <400000000>;
+ };
+
periph_osc: periph-osc {
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -136,6 +147,33 @@
#power-domain-cells = <1>;
};
+ lsspi: spi@10000800 {
+ compatible = "brcm,bcm6358-spi";
+ reg = <0x10000800 0x70c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&periph_clk BCM63268_CLK_SPI>;
+ resets = <&periph_rst BCM63268_RST_SPI>;
+ spi-max-frequency = <20000000>;
+ num-cs = <8>;
+
+ status = "disabled";
+ };
+
+ hsspi: spi@10001000 {
+ compatible = "brcm,bcm6328-hsspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10001000 0x600>;
+ clocks = <&periph_clk BCM63268_CLK_HSSPI>, <&hsspi_pll>;
+ clock-names = "hsspi", "pll";
+ resets = <&periph_rst BCM63268_RST_SPI>;
+ spi-max-frequency = <50000000>;
+ num-cs = <8>;
+
+ status = "disabled";
+ };
+
leds: led-controller@10001900 {
compatible = "brcm,bcm6328-leds";
reg = <0x10001900 0x24>;
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi
index a996075..67d9278 100644
--- a/arch/mips/dts/brcm,bcm6328.dtsi
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -13,6 +13,10 @@
/ {
compatible = "brcm,bcm6328";
+ aliases {
+ spi0 = &spi;
+ };
+
cpus {
reg = <0x10000000 0x4>;
#address-cells = <1>;
@@ -40,6 +44,12 @@
#size-cells = <1>;
u-boot,dm-pre-reloc;
+ hsspi_pll: hsspi-pll {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <133333333>;
+ };
+
periph_osc: periph-osc {
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -123,6 +133,20 @@
status = "disabled";
};
+ spi: spi@10001000 {
+ compatible = "brcm,bcm6328-hsspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10001000 0x600>;
+ clocks = <&periph_clk BCM6328_CLK_HSSPI>, <&hsspi_pll>;
+ clock-names = "hsspi", "pll";
+ resets = <&periph_rst BCM6328_RST_SPI>;
+ spi-max-frequency = <33333334>;
+ num-cs = <3>;
+
+ status = "disabled";
+ };
+
periph_pwr: power-controller@10001848 {
compatible = "brcm,bcm6328-power-domain";
reg = <0x10001848 0x4>;
diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi
index eb51a43..0cab44c 100644
--- a/arch/mips/dts/brcm,bcm6338.dtsi
+++ b/arch/mips/dts/brcm,bcm6338.dtsi
@@ -12,6 +12,10 @@
/ {
compatible = "brcm,bcm6338";
+ aliases {
+ spi0 = &spi;
+ };
+
cpus {
reg = <0xfffe0000 0x4>;
#address-cells = <1>;
@@ -109,6 +113,19 @@
status = "disabled";
};
+ spi: spi@fffe0c00 {
+ compatible = "brcm,bcm6348-spi";
+ reg = <0xfffe0c00 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&periph_clk BCM6338_CLK_SPI>;
+ resets = <&periph_rst BCM6338_RST_SPI>;
+ spi-max-frequency = <20000000>;
+ num-cs = <4>;
+
+ status = "disabled";
+ };
+
memory-controller@fffe3100 {
compatible = "brcm,bcm6338-mc";
reg = <0xfffe3100 0x38>;
diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi
index 711b643..540b9fe 100644
--- a/arch/mips/dts/brcm,bcm6348.dtsi
+++ b/arch/mips/dts/brcm,bcm6348.dtsi
@@ -12,6 +12,10 @@
/ {
compatible = "brcm,bcm6348";
+ aliases {
+ spi0 = &spi;
+ };
+
cpus {
reg = <0xfffe0000 0x4>;
#address-cells = <1>;
@@ -118,6 +122,19 @@
status = "disabled";
};
+ spi: spi@fffe0c00 {
+ compatible = "brcm,bcm6348-spi";
+ reg = <0xfffe0c00 0xc0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&periph_clk BCM6348_CLK_SPI>;
+ resets = <&periph_rst BCM6348_RST_SPI>;
+ spi-max-frequency = <20000000>;
+ num-cs = <4>;
+
+ status = "disabled";
+ };
+
memory-controller@fffe2300 {
compatible = "brcm,bcm6338-mc";
reg = <0xfffe2300 0x38>;
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi
index 4f63cf8..1662783 100644
--- a/arch/mips/dts/brcm,bcm6358.dtsi
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -12,6 +12,10 @@
/ {
compatible = "brcm,bcm6358";
+ aliases {
+ spi0 = &spi;
+ };
+
cpus {
reg = <0xfffe0000 0x4>;
#address-cells = <1>;
@@ -142,6 +146,19 @@
status = "disabled";
};
+ spi: spi@fffe0800 {
+ compatible = "brcm,bcm6358-spi";
+ reg = <0xfffe0800 0x70c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&periph_clk BCM6358_CLK_SPI>;
+ resets = <&periph_rst BCM6358_RST_SPI>;
+ spi-max-frequency = <20000000>;
+ num-cs = <4>;
+
+ status = "disabled";
+ };
+
memory-controller@fffe1200 {
compatible = "brcm,bcm6358-mc";
reg = <0xfffe1200 0x4c>;
diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi
new file mode 100644
index 0000000..1bb538a
--- /dev/null
+++ b/arch/mips/dts/brcm,bcm6368.dtsi
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <dt-bindings/clock/bcm6368-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/reset/bcm6368-reset.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "brcm,bcm6368";
+
+ aliases {
+ spi0 = &spi;
+ };
+
+ cpus {
+ reg = <0x10000000 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ u-boot,dm-pre-reloc;
+
+ cpu@0 {
+ compatible = "brcm,bcm6368-cpu", "mips,mips4Kc";
+ device_type = "cpu";
+ reg = <0>;
+ u-boot,dm-pre-reloc;
+ };
+
+ cpu@1 {
+ compatible = "brcm,bcm6368-cpu", "mips,mips4Kc";
+ device_type = "cpu";
+ reg = <1>;
+ u-boot,dm-pre-reloc;
+ };
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ u-boot,dm-pre-reloc;
+
+ periph_osc: periph-osc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <50000000>;
+ u-boot,dm-pre-reloc;
+ };
+
+ periph_clk: periph-clk {
+ compatible = "brcm,bcm6345-clk";
+ reg = <0x10000004 0x4>;
+ #clock-cells = <1>;
+ };
+ };
+
+ pflash: nor@18000000 {
+ compatible = "cfi-flash";
+ reg = <0x18000000 0x2000000>;
+ bank-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ status = "disabled";
+ };
+
+ ubus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ u-boot,dm-pre-reloc;
+
+ pll_cntl: syscon@10000008 {
+ compatible = "syscon";
+ reg = <0x10000008 0x4>;
+ };
+
+ syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&pll_cntl>;
+ offset = <0x0>;
+ mask = <0x1>;
+ };
+
+ periph_rst: reset-controller@10000010 {
+ compatible = "brcm,bcm6345-reset";
+ reg = <0x10000010 0x4>;
+ #reset-cells = <1>;
+ };
+
+ wdt: watchdog@1000005c {
+ compatible = "brcm,bcm6345-wdt";
+ reg = <0x1000005c 0xc>;
+ clocks = <&periph_osc>;
+ };
+
+ wdt-reboot {
+ compatible = "wdt-reboot";
+ wdt = <&wdt>;
+ };
+
+ gpio1: gpio-controller@10000080 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x10000080 0x4>, <0x10000088 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <6>;
+
+ status = "disabled";
+ };
+
+ gpio0: gpio-controller@10000084 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x10000084 0x4>, <0x1000008c 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ leds: led-controller@100000d0 {
+ compatible = "brcm,bcm6358-leds";
+ reg = <0x100000d0 0x8>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ uart0: serial@10000100 {
+ compatible = "brcm,bcm6345-uart";
+ reg = <0x10000100 0x18>;
+ clocks = <&periph_osc>;
+
+ status = "disabled";
+ };
+
+ uart1: serial@10000120 {
+ compatible = "brcm,bcm6345-uart";
+ reg = <0x10000120 0x18>;
+ clocks = <&periph_osc>;
+
+ status = "disabled";
+ };
+
+ spi: spi@10000800 {
+ compatible = "brcm,bcm6358-spi";
+ reg = <0x10000800 0x70c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&periph_clk BCM6368_CLK_SPI>;
+ resets = <&periph_rst BCM6368_RST_SPI>;
+ spi-max-frequency = <20000000>;
+ num-cs = <6>;
+
+ status = "disabled";
+ };
+
+ memory-controller@10001200 {
+ compatible = "brcm,bcm6358-mc";
+ reg = <0x10001200 0x4c>;
+ u-boot,dm-pre-reloc;
+ };
+ };
+};
diff --git a/arch/mips/dts/comtrend,ar-5315u.dts b/arch/mips/dts/comtrend,ar-5315u.dts
new file mode 100644
index 0000000..4e4d69b
--- /dev/null
+++ b/arch/mips/dts/comtrend,ar-5315u.dts
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "brcm,bcm6318.dtsi"
+
+/ {
+ model = "Comtrend AR-5315u";
+ compatible = "comtrend,ar5315-un", "brcm,bcm6318";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&leds {
+ status = "okay";
+
+ led@0 {
+ reg = <0>;
+ active-low;
+ label = "AR-5315u:green:wps";
+ };
+
+ led@1 {
+ reg = <1>;
+ active-low;
+ label = "AR-5315u:green:power";
+ };
+
+ led@2 {
+ reg = <2>;
+ active-low;
+ label = "AR-5315u:green:usb";
+ };
+
+ led@8 {
+ reg = <8>;
+ active-low;
+ label = "AR-5315u:green:inet";
+ };
+
+ led@9 {
+ reg = <9>;
+ active-low;
+ label = "AR-5315u:red:inet";
+ };
+
+ led@10 {
+ reg = <10>;
+ active-low;
+ label = "AR-5315u:green:dsl";
+ };
+
+ led@11 {
+ reg = <11>;
+ active-low;
+ label = "AR-5315u:red:power";
+ };
+};
+
+&spi {
+ status = "okay";
+
+ spi-flash@0 {
+ compatible = "spi-flash";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <62500000>;
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
diff --git a/arch/mips/dts/comtrend,ar-5387un.dts b/arch/mips/dts/comtrend,ar-5387un.dts
index 73f2b49..6067881 100644
--- a/arch/mips/dts/comtrend,ar-5387un.dts
+++ b/arch/mips/dts/comtrend,ar-5387un.dts
@@ -51,6 +51,18 @@
};
};
+&spi {
+ status = "okay";
+
+ spi-flash@0 {
+ compatible = "spi-flash";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <33333334>;
+ };
+};
+
&uart0 {
u-boot,dm-pre-reloc;
status = "okay";
diff --git a/arch/mips/dts/comtrend,wap-5813n.dts b/arch/mips/dts/comtrend,wap-5813n.dts
new file mode 100644
index 0000000..29386e2
--- /dev/null
+++ b/arch/mips/dts/comtrend,wap-5813n.dts
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "brcm,bcm6368.dtsi"
+
+/ {
+ model = "Comtrend WAP-5813n";
+ compatible = "comtrend,wap-5813n", "brcm,bcm6368";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ inet_green {
+ label = "WAP-5813n:green:inet";
+ gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
+ };
+
+ power_green {
+ label = "WAP-5813n:green:power";
+ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+
+ wps_green {
+ label = "WAP-5813n:green:wps";
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+ };
+
+ power_red {
+ label = "WAP-5813n:red:power";
+ gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
+ };
+
+ inet_red {
+ label = "WAP-5813n:red:inet";
+ gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&pflash {
+ status = "okay";
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
diff --git a/arch/mips/dts/netgear,cg3100d.dts b/arch/mips/dts/netgear,cg3100d.dts
index db1e2e7..5f85c73 100644
--- a/arch/mips/dts/netgear,cg3100d.dts
+++ b/arch/mips/dts/netgear,cg3100d.dts
@@ -90,6 +90,18 @@
status = "okay";
};
+&spi {
+ status = "okay";
+
+ spi-flash@0 {
+ compatible = "spi-flash";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <25000000>;
+ };
+};
+
&uart0 {
u-boot,dm-pre-reloc;
status = "okay";
diff --git a/arch/mips/dts/sagem,f@st1704.dts b/arch/mips/dts/sagem,f@st1704.dts
index be15fe5..dd0e5b8 100644
--- a/arch/mips/dts/sagem,f@st1704.dts
+++ b/arch/mips/dts/sagem,f@st1704.dts
@@ -44,6 +44,18 @@
status = "okay";
};
+&spi {
+ status = "okay";
+
+ spi-flash@0 {
+ compatible = "spi-flash";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <20000000>;
+ };
+};
+
&uart0 {
u-boot,dm-pre-reloc;
status = "okay";
diff --git a/arch/mips/mach-ath79/ar934x/clk.c b/arch/mips/mach-ath79/ar934x/clk.c
index 9b41d3d..ba2243c 100644
--- a/arch/mips/mach-ath79/ar934x/clk.c
+++ b/arch/mips/mach-ath79/ar934x/clk.c
@@ -90,7 +90,7 @@
setbits_be32(pll_reg_base + 0x8, BIT(30));
udelay(5);
- wait_for_bit("clk", pll_reg_base + 0xc, BIT(3), 1, 10, 0);
+ wait_for_bit_le32(pll_reg_base + 0xc, BIT(3), 1, 10, 0);
clrbits_be32(pll_reg_base + 0x8, BIT(30));
udelay(5);
diff --git a/arch/mips/mach-bmips/Kconfig b/arch/mips/mach-bmips/Kconfig
index e3e1da3..e4a0118 100644
--- a/arch/mips/mach-bmips/Kconfig
+++ b/arch/mips/mach-bmips/Kconfig
@@ -1,12 +1,17 @@
menu "Broadcom MIPS platforms"
depends on ARCH_BMIPS
+config SYS_MALLOC_F_LEN
+ default 0x1000
+
config SYS_SOC
default "bcm3380" if SOC_BMIPS_BCM3380
+ default "bcm6318" if SOC_BMIPS_BCM6318
default "bcm6328" if SOC_BMIPS_BCM6328
default "bcm6338" if SOC_BMIPS_BCM6338
default "bcm6348" if SOC_BMIPS_BCM6348
default "bcm6358" if SOC_BMIPS_BCM6358
+ default "bcm6368" if SOC_BMIPS_BCM6368
default "bcm63268" if SOC_BMIPS_BCM63268
choice
@@ -23,6 +28,17 @@
help
This supports BMIPS BCM3380 family.
+config SOC_BMIPS_BCM6318
+ bool "BMIPS BCM6318 family"
+ select SUPPORTS_BIG_ENDIAN
+ select SUPPORTS_CPU_MIPS32_R1
+ select MIPS_TUNE_4KC
+ select MIPS_L1_CACHE_SHIFT_4
+ select SWAP_IO_SPACE
+ select SYSRESET_SYSCON
+ help
+ This supports BMIPS BCM6318 family.
+
config SOC_BMIPS_BCM6328
bool "BMIPS BCM6328 family"
select SUPPORTS_BIG_ENDIAN
@@ -67,6 +83,17 @@
help
This supports BMIPS BCM6358 family including BCM6358 and BCM6359.
+config SOC_BMIPS_BCM6368
+ bool "BMIPS BCM6368 family"
+ select SUPPORTS_BIG_ENDIAN
+ select SUPPORTS_CPU_MIPS32_R1
+ select MIPS_TUNE_4KC
+ select MIPS_L1_CACHE_SHIFT_4
+ select SWAP_IO_SPACE
+ select SYSRESET_SYSCON
+ help
+ This supports BMIPS BCM6368 family including BCM6368 and BCM6369.
+
config SOC_BMIPS_BCM63268
bool "BMIPS BCM63268 family"
select SUPPORTS_BIG_ENDIAN
@@ -84,6 +111,17 @@
choice
prompt "Board select"
+config BOARD_COMTREND_AR5315U
+ bool "Comtrend AR-5315u"
+ depends on SOC_BMIPS_BCM6318
+ select BMIPS_SUPPORTS_BOOT_RAM
+ help
+ Comtrend AR-5315u boards have a BCM6318 SoC with 64 MB of RAM and 16
+ MB of flash (SPI).
+ Between its different peripherals there's an integrated switch with 4
+ ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
+ a BCM43217 (PCIe).
+
config BOARD_COMTREND_AR5387UN
bool "Comtrend AR-5387un"
depends on SOC_BMIPS_BCM6328
@@ -117,6 +155,17 @@
ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs,
and a BCM6362 (integrated).
+config BOARD_COMTREND_WAP5813N
+ bool "Comtrend WAP-5813n board"
+ depends on SOC_BMIPS_BCM6368
+ select BMIPS_SUPPORTS_BOOT_RAM
+ help
+ Comtrend WAP-5813n boards have a BCM6369 SoC with 64 MB of RAM and
+ 8 MB of flash (CFI).
+ Between its different peripherals there's a BCM53115 switch with 5
+ ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs,
+ and a BCM4322 (miniPCI).
+
config BOARD_HUAWEI_HG556A
bool "Huawei EchoLife HG556a"
depends on SOC_BMIPS_BCM6358
@@ -179,9 +228,11 @@
config BMIPS_SUPPORTS_BOOT_RAM
bool
+source "board/comtrend/ar5315u/Kconfig"
source "board/comtrend/ar5387un/Kconfig"
source "board/comtrend/ct5361/Kconfig"
source "board/comtrend/vr3032u/Kconfig"
+source "board/comtrend/wap5813n/Kconfig"
source "board/huawei/hg556a/Kconfig"
source "board/netgear/cg3100d/Kconfig"
source "board/sagem/f@st1704/Kconfig"
diff --git a/board/comtrend/ar5315u/Kconfig b/board/comtrend/ar5315u/Kconfig
new file mode 100644
index 0000000..4baae40
--- /dev/null
+++ b/board/comtrend/ar5315u/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_COMTREND_AR5315U
+
+config SYS_BOARD
+ default "ar5315u"
+
+config SYS_VENDOR
+ default "comtrend"
+
+config SYS_CONFIG_NAME
+ default "comtrend_ar5315u"
+
+endif
diff --git a/board/comtrend/ar5315u/MAINTAINERS b/board/comtrend/ar5315u/MAINTAINERS
new file mode 100644
index 0000000..048073c
--- /dev/null
+++ b/board/comtrend/ar5315u/MAINTAINERS
@@ -0,0 +1,6 @@
+COMTREND AR-5315U BOARD
+M: Álvaro Fernández Rojas <noltari@gmail.com>
+S: Maintained
+F: board/comtrend/ar-5315u/
+F: include/configs/comtrend_ar5315u.h
+F: configs/comtrend_ar5315u_ram_defconfig
diff --git a/board/comtrend/ar5315u/Makefile b/board/comtrend/ar5315u/Makefile
new file mode 100644
index 0000000..5d2f590
--- /dev/null
+++ b/board/comtrend/ar5315u/Makefile
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += ar-5315u.o
diff --git a/board/comtrend/ar5315u/ar-5315u.c b/board/comtrend/ar5315u/ar-5315u.c
new file mode 100644
index 0000000..bdb3aca
--- /dev/null
+++ b/board/comtrend/ar5315u/ar-5315u.c
@@ -0,0 +1,7 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
diff --git a/board/comtrend/wap5813n/Kconfig b/board/comtrend/wap5813n/Kconfig
new file mode 100644
index 0000000..2f2a14f
--- /dev/null
+++ b/board/comtrend/wap5813n/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_COMTREND_WAP5813N
+
+config SYS_BOARD
+ default "wap5813n"
+
+config SYS_VENDOR
+ default "comtrend"
+
+config SYS_CONFIG_NAME
+ default "comtrend_wap5813n"
+
+endif
diff --git a/board/comtrend/wap5813n/MAINTAINERS b/board/comtrend/wap5813n/MAINTAINERS
new file mode 100644
index 0000000..f4d9979
--- /dev/null
+++ b/board/comtrend/wap5813n/MAINTAINERS
@@ -0,0 +1,6 @@
+COMTREND WAP-5813N BOARD
+M: Álvaro Fernández Rojas <noltari@gmail.com>
+S: Maintained
+F: board/comtrend/wap-5813n/
+F: include/configs/comtrend_wap-5813n.h
+F: configs/comtrend_wap5813n_ram_defconfig
diff --git a/board/comtrend/wap5813n/Makefile b/board/comtrend/wap5813n/Makefile
new file mode 100644
index 0000000..fd77993
--- /dev/null
+++ b/board/comtrend/wap5813n/Makefile
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += wap-5813n.o
diff --git a/board/comtrend/wap5813n/wap-5813n.c b/board/comtrend/wap5813n/wap-5813n.c
new file mode 100644
index 0000000..d181ca6
--- /dev/null
+++ b/board/comtrend/wap5813n/wap-5813n.c
@@ -0,0 +1,7 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
diff --git a/board/freescale/common/Kconfig b/board/freescale/common/Kconfig
index 280f7d4..8b89c10 100644
--- a/board/freescale/common/Kconfig
+++ b/board/freescale/common/Kconfig
@@ -20,3 +20,19 @@
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.
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
index e13cb20..939e9c6 100644
--- a/board/freescale/common/Makefile
+++ b/board/freescale/common/Makefile
@@ -23,8 +23,8 @@
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
diff --git a/board/freescale/common/qixis.c b/board/freescale/common/qixis.c
index 24459f8..844c00a 100644
--- a/board/freescale/common/qixis.c
+++ b/board/freescale/common/qixis.c
@@ -235,6 +235,28 @@
#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
QIXIS_WRITE(rst_ctl, 0x30);
diff --git a/board/freescale/common/vid.c b/board/freescale/common/vid.c
index d6d1bfc..a9451c5 100644
--- a/board/freescale/common/vid.c
+++ b/board/freescale/common/vid.c
@@ -34,6 +34,16 @@
}
/*
+ * 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
*
* There are some variance in the RDB HW regarding the I2C address configuration
@@ -65,6 +75,7 @@
}
return -1;
}
+#endif
/* Maximum loop count waiting for new voltage to take effect */
#define MAX_LOOP_WAIT_NEW_VOL 100
@@ -163,6 +174,36 @@
}
#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 @@
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 @@
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 @@
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 @@
#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 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 @@
0, /* reserved */
0, /* reserved */
};
+#endif
struct vdd_drive {
u8 vid;
unsigned voltage;
@@ -340,6 +465,8 @@
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 @@
ret = -1;
goto exit;
}
+#endif
/* get the voltage ID from fuse status register */
fusesr = in_le32(&gur->dcfg_fusesr);
@@ -415,6 +543,11 @@
}
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 @@
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 @@
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 @@
ret = -1;
goto exit;
}
+#endif
/* get the voltage ID from fuse status register */
fusesr = in_be32(&gur->dcfg_fusesr);
@@ -632,6 +774,8 @@
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 @@
i2caddress = ret;
debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
}
+#endif
/*
* Read voltage monitor to check real voltage.
diff --git a/board/freescale/ls1088a/ddr.c b/board/freescale/ls1088a/ddr.c
index e24bfd5..2240454 100644
--- a/board/freescale/ls1088a/ddr.c
+++ b/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 @@
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;
}
diff --git a/board/freescale/ls1088a/ls1088a.c b/board/freescale/ls1088a/ls1088a.c
index d12bcae..0769e90 100644
--- a/board/freescale/ls1088a/ls1088a.c
+++ b/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 @@
}
#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 @@
return 66666666;
}
+#endif
int select_i2c_ch_pca9547(u8 ch)
{
@@ -221,6 +236,7 @@
return 0;
}
+#if !defined(CONFIG_SPL_BUILD)
void board_retimer_init(void)
{
u8 reg;
@@ -322,7 +338,122 @@
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();
diff --git a/board/imgtec/boston/config.mk b/board/imgtec/boston/config.mk
index 2775727..0ba8802 100644
--- a/board/imgtec/boston/config.mk
+++ b/board/imgtec/boston/config.mk
@@ -3,7 +3,10 @@
#
quiet_cmd_srec_cat = SRECCAT $@
- cmd_srec_cat = srec_cat -output $@ -$2 $< -binary -offset $3
+ cmd_srec_cat = srec_cat -output $@ -$2 \
+ $< -binary \
+ -fill 0x00 -within $< -binary -range-pad 16 \
+ -offset $3
u-boot.mcs: u-boot.bin
$(call cmd,srec_cat,intel,0x7c00000)
diff --git a/board/logicpd/omap3som/omap3logic.c b/board/logicpd/omap3som/omap3logic.c
index b30fa24..4cbbf96 100644
--- a/board/logicpd/omap3som/omap3logic.c
+++ b/board/logicpd/omap3som/omap3logic.c
@@ -40,21 +40,6 @@
DECLARE_GLOBAL_DATA_PTR;
-/* This is only needed until SPL gets OF support */
-#ifdef CONFIG_SPL_BUILD
-static const struct ns16550_platdata omap3logic_serial = {
- .base = OMAP34XX_UART1,
- .reg_shift = 2,
- .clock = V_NS16550_CLK,
- .fcr = UART_FCR_DEFVAL,
-};
-
-U_BOOT_DEVICE(omap3logic_uart) = {
- "ns16550_serial",
- &omap3logic_serial
-};
-#endif
-
/*
* two dimensional array of strucures containining board name and Linux
* machine IDs; row it selected based on CPU column is slected based
diff --git a/board/samtec/vining_2000/vining_2000.c b/board/samtec/vining_2000/vining_2000.c
index af1a3e7..cced08b 100644
--- a/board/samtec/vining_2000/vining_2000.c
+++ b/board/samtec/vining_2000/vining_2000.c
@@ -378,7 +378,7 @@
/* start auto calibration */
setbits_le32(b + ADCx_GC, ADCx_GC_CAL);
- ret = wait_for_bit("ADC", b + ADCx_GC, ADCx_GC_CAL, ADCx_GC_CAL, 10, 0);
+ ret = wait_for_bit_le32(b + ADCx_GC, ADCx_GC_CAL, ADCx_GC_CAL, 10, 0);
if (ret)
goto adc_exit;
@@ -386,7 +386,7 @@
writel(0, b + ADCx_HC0);
/* wait for conversion */
- ret = wait_for_bit("ADC", b + ADCx_HS, ADCx_HS_C0, ADCx_HS_C0, 10, 0);
+ ret = wait_for_bit_le32(b + ADCx_HS, ADCx_HS_C0, ADCx_HS_C0, 10, 0);
if (ret)
goto adc_exit;
diff --git a/cmd/Kconfig b/cmd/Kconfig
index c399169..676011d 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1372,17 +1372,20 @@
config CMD_EXT2
bool "ext2 command support"
+ select FS_EXT4
help
Enables EXT2 FS command
config CMD_EXT4
bool "ext4 command support"
+ select FS_EXT4
help
Enables EXT4 FS command
config CMD_EXT4_WRITE
depends on CMD_EXT4
bool "ext4 write command support"
+ select EXT4_WRITE
help
Enables EXT4 FS write command
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 78ff109..51213c0 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -32,6 +32,9 @@
{
efi_obj_list_initalized = 1;
+ /* Initialize EFI driver uclass */
+ efi_driver_init();
+
efi_console_register();
#ifdef CONFIG_PARTITIONS
efi_disk_register();
@@ -103,11 +106,11 @@
/* Safe fdt location is at 128MB */
new_fdt_addr = fdt_ram_start + (128 * 1024 * 1024) + fdt_size;
- if (efi_allocate_pages(1, EFI_BOOT_SERVICES_DATA, fdt_pages,
+ if (efi_allocate_pages(1, EFI_RUNTIME_SERVICES_DATA, fdt_pages,
&new_fdt_addr) != EFI_SUCCESS) {
/* If we can't put it there, put it somewhere */
new_fdt_addr = (ulong)memalign(EFI_PAGE_SIZE, fdt_size);
- if (efi_allocate_pages(1, EFI_BOOT_SERVICES_DATA, fdt_pages,
+ if (efi_allocate_pages(1, EFI_RUNTIME_SERVICES_DATA, fdt_pages,
&new_fdt_addr) != EFI_SUCCESS) {
printf("ERROR: Failed to reserve space for FDT\n");
return NULL;
@@ -122,8 +125,8 @@
}
static efi_status_t efi_do_enter(
- void *image_handle, struct efi_system_table *st,
- asmlinkage ulong (*entry)(void *image_handle,
+ efi_handle_t image_handle, struct efi_system_table *st,
+ asmlinkage ulong (*entry)(efi_handle_t image_handle,
struct efi_system_table *st))
{
efi_status_t ret = EFI_LOAD_ERROR;
@@ -136,8 +139,8 @@
#ifdef CONFIG_ARM64
static efi_status_t efi_run_in_el2(asmlinkage ulong (*entry)(
- void *image_handle, struct efi_system_table *st),
- void *image_handle, struct efi_system_table *st)
+ efi_handle_t image_handle, struct efi_system_table *st),
+ efi_handle_t image_handle, struct efi_system_table *st)
{
/* Enable caches again */
dcache_enable();
@@ -159,7 +162,7 @@
struct efi_device_path *memdp = NULL;
ulong ret;
- ulong (*entry)(void *image_handle, struct efi_system_table *st)
+ ulong (*entry)(efi_handle_t image_handle, struct efi_system_table *st)
asmlinkage;
ulong fdt_pages, fdt_size, fdt_start, fdt_end;
const efi_guid_t fdt_guid = EFI_FDT_GUID;
diff --git a/common/Kconfig b/common/Kconfig
index 4da095a..21e067c 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -533,7 +533,7 @@
config DISPLAY_CPUINFO
bool "Display information about the CPU during start up"
- default y if ARM || NIOS2 || X86 || XTENSA
+ default y if ARM || NIOS2 || X86 || XTENSA || M68K
help
Display information about the CPU that U-Boot is running on
when U-Boot starts up. The function print_cpuinfo() is called
diff --git a/common/board_f.c b/common/board_f.c
index 0bdce64..1965bda 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -200,6 +200,13 @@
}
#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)
{
@@ -780,8 +787,7 @@
console_init_f, /* stage 1 init of console */
display_options, /* say that we are here */
display_text_info, /* show debugging info if required */
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SH) || \
- defined(CONFIG_X86)
+#if defined(CONFIG_PPC) || defined(CONFIG_SH) || defined(CONFIG_X86)
checkcpu,
#endif
#if defined(CONFIG_DISPLAY_CPUINFO)
@@ -801,6 +807,9 @@
#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
diff --git a/common/hash.c b/common/hash.c
index cf4d70f..69d53ed 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -390,7 +390,7 @@
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 @@
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 @@
store_result(algo, output, *argv,
flags & HASH_FLAG_ENV);
}
+ unmap_sysmem(output);
+
}
/* Horrible code size hack for boards that just want crc32 */
diff --git a/configs/am335x_baltos_defconfig b/configs/am335x_baltos_defconfig
index 0ef9f42..548e045 100644
--- a/configs/am335x_baltos_defconfig
+++ b/configs/am335x_baltos_defconfig
@@ -55,6 +55,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am335x_boneblack_defconfig b/configs/am335x_boneblack_defconfig
index 50093cd..f14333d 100644
--- a/configs/am335x_boneblack_defconfig
+++ b/configs/am335x_boneblack_defconfig
@@ -33,6 +33,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index aa9fb97..016ec4e 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -43,6 +43,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index 9c97009..9e79d1c 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -47,6 +47,7 @@
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am335x_evm_nor_defconfig b/configs/am335x_evm_nor_defconfig
index 1813003..14aa267 100644
--- a/configs/am335x_evm_nor_defconfig
+++ b/configs/am335x_evm_nor_defconfig
@@ -34,6 +34,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am335x_evm_norboot_defconfig b/configs/am335x_evm_norboot_defconfig
index b38d7f6..22182f5 100644
--- a/configs/am335x_evm_norboot_defconfig
+++ b/configs/am335x_evm_norboot_defconfig
@@ -30,6 +30,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am335x_evm_spiboot_defconfig b/configs/am335x_evm_spiboot_defconfig
index 7a20576..71d6a28 100644
--- a/configs/am335x_evm_spiboot_defconfig
+++ b/configs/am335x_evm_spiboot_defconfig
@@ -32,6 +32,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am335x_evm_usbspl_defconfig b/configs/am335x_evm_usbspl_defconfig
index 1e80017..10d6d38 100644
--- a/configs/am335x_evm_usbspl_defconfig
+++ b/configs/am335x_evm_usbspl_defconfig
@@ -38,6 +38,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am335x_hs_evm_defconfig b/configs/am335x_hs_evm_defconfig
index 63e7a07..55565f4 100644
--- a/configs/am335x_hs_evm_defconfig
+++ b/configs/am335x_hs_evm_defconfig
@@ -56,6 +56,7 @@
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am335x_hs_evm_uart_defconfig b/configs/am335x_hs_evm_uart_defconfig
index 09aab29..7f05d56 100644
--- a/configs/am335x_hs_evm_uart_defconfig
+++ b/configs/am335x_hs_evm_uart_defconfig
@@ -53,6 +53,7 @@
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DOWNLOAD=y
diff --git a/configs/am3517_crane_defconfig b/configs/am3517_crane_defconfig
index a1766d9..2e8d943 100644
--- a/configs/am3517_crane_defconfig
+++ b/configs/am3517_crane_defconfig
@@ -31,4 +31,6 @@
CONFIG_SPL_NAND_SIMPLE=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
+CONFIG_USB_MUSB_HCD=y
+CONFIG_USB_AM35X=y
CONFIG_USB_STORAGE=y
diff --git a/configs/am3517_evm_defconfig b/configs/am3517_evm_defconfig
index e6c17c7..bb7cc3f 100644
--- a/configs/am3517_evm_defconfig
+++ b/configs/am3517_evm_defconfig
@@ -40,5 +40,6 @@
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
+CONFIG_USB_MUSB_AM35X=y
# CONFIG_FAT_WRITE is not set
CONFIG_BCH=y
diff --git a/configs/am43xx_evm_defconfig b/configs/am43xx_evm_defconfig
index c180214..c75eab3 100644
--- a/configs/am43xx_evm_defconfig
+++ b/configs/am43xx_evm_defconfig
@@ -49,6 +49,7 @@
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am43xx_evm_ethboot_defconfig b/configs/am43xx_evm_ethboot_defconfig
index 60f0552..7f2acd9 100644
--- a/configs/am43xx_evm_ethboot_defconfig
+++ b/configs/am43xx_evm_ethboot_defconfig
@@ -60,6 +60,7 @@
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am43xx_evm_qspiboot_defconfig b/configs/am43xx_evm_qspiboot_defconfig
index d6a5263..a56abc9 100644
--- a/configs/am43xx_evm_qspiboot_defconfig
+++ b/configs/am43xx_evm_qspiboot_defconfig
@@ -49,6 +49,7 @@
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am43xx_evm_usbhost_boot_defconfig b/configs/am43xx_evm_usbhost_boot_defconfig
index 28cf04a..e9c3a05 100644
--- a/configs/am43xx_evm_usbhost_boot_defconfig
+++ b/configs/am43xx_evm_usbhost_boot_defconfig
@@ -72,6 +72,7 @@
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am43xx_hs_evm_defconfig b/configs/am43xx_hs_evm_defconfig
index bed0583..e8a641e 100644
--- a/configs/am43xx_hs_evm_defconfig
+++ b/configs/am43xx_hs_evm_defconfig
@@ -60,6 +60,7 @@
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig
index b3b3cf7..0bcda4f 100644
--- a/configs/am57xx_evm_defconfig
+++ b/configs/am57xx_evm_defconfig
@@ -70,6 +70,7 @@
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig
index edfead0..2e0763c 100644
--- a/configs/am57xx_hs_evm_defconfig
+++ b/configs/am57xx_hs_evm_defconfig
@@ -73,6 +73,7 @@
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/birdland_bav335a_defconfig b/configs/birdland_bav335a_defconfig
index 61518f5..d6d5d71 100644
--- a/configs/birdland_bav335a_defconfig
+++ b/configs/birdland_bav335a_defconfig
@@ -62,6 +62,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/birdland_bav335b_defconfig b/configs/birdland_bav335b_defconfig
index c7360c3..0c14595 100644
--- a/configs/birdland_bav335b_defconfig
+++ b/configs/birdland_bav335b_defconfig
@@ -62,6 +62,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/brppt1_mmc_defconfig b/configs/brppt1_mmc_defconfig
index c41a7b4..aa3e317 100644
--- a/configs/brppt1_mmc_defconfig
+++ b/configs/brppt1_mmc_defconfig
@@ -55,6 +55,7 @@
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_LCD=y
diff --git a/configs/brppt1_nand_defconfig b/configs/brppt1_nand_defconfig
index 3844413..c8063b9 100644
--- a/configs/brppt1_nand_defconfig
+++ b/configs/brppt1_nand_defconfig
@@ -57,6 +57,7 @@
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_LCD=y
diff --git a/configs/brppt1_spi_defconfig b/configs/brppt1_spi_defconfig
index 25d8837..6385b1a 100644
--- a/configs/brppt1_spi_defconfig
+++ b/configs/brppt1_spi_defconfig
@@ -65,6 +65,7 @@
CONFIG_OMAP3_SPI=y
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_LCD=y
diff --git a/configs/brxre1_defconfig b/configs/brxre1_defconfig
index 0c2d7ed..15245dc 100644
--- a/configs/brxre1_defconfig
+++ b/configs/brxre1_defconfig
@@ -56,6 +56,7 @@
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_LCD=y
diff --git a/configs/calimain_defconfig b/configs/calimain_defconfig
index a02926c..d8ab012 100644
--- a/configs/calimain_defconfig
+++ b/configs/calimain_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_DAVINCI=y
CONFIG_TARGET_CALIMAIN=y
+CONFIG_DA850_LOWLEVEL=y
CONFIG_BOOTDELAY=0
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_CPUINFO is not set
diff --git a/configs/chiliboard_defconfig b/configs/chiliboard_defconfig
index bc69df0..a32dab7 100644
--- a/configs/chiliboard_defconfig
+++ b/configs/chiliboard_defconfig
@@ -45,6 +45,7 @@
CONFIG_OMAP3_SPI=y
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_FAT_WRITE=y
CONFIG_LZO=y
diff --git a/configs/chromebit_mickey_defconfig b/configs/chromebit_mickey_defconfig
index 2a74784..b350811 100644
--- a/configs/chromebit_mickey_defconfig
+++ b/configs/chromebit_mickey_defconfig
@@ -74,6 +74,7 @@
CONFIG_ROCKCHIP_SPI=y
CONFIG_SYSRESET=y
CONFIG_USB=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
CONFIG_USB_GADGET_VENDOR_NUM=0x2207
diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig
index 81ed7d0..f80faae 100644
--- a/configs/chromebook_jerry_defconfig
+++ b/configs/chromebook_jerry_defconfig
@@ -75,6 +75,7 @@
CONFIG_ROCKCHIP_SPI=y
CONFIG_SYSRESET=y
CONFIG_USB=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
CONFIG_USB_GADGET_VENDOR_NUM=0x2207
diff --git a/configs/chromebook_minnie_defconfig b/configs/chromebook_minnie_defconfig
index 0565c03..ff94a4d 100644
--- a/configs/chromebook_minnie_defconfig
+++ b/configs/chromebook_minnie_defconfig
@@ -74,6 +74,7 @@
CONFIG_ROCKCHIP_SPI=y
CONFIG_SYSRESET=y
CONFIG_USB=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
CONFIG_USB_GADGET_VENDOR_NUM=0x2207
diff --git a/configs/cl-som-am57x_defconfig b/configs/cl-som-am57x_defconfig
index 9c3031b..e9b6fe0 100644
--- a/configs/cl-som-am57x_defconfig
+++ b/configs/cl-som-am57x_defconfig
@@ -57,6 +57,7 @@
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
diff --git a/configs/cm_t3517_defconfig b/configs/cm_t3517_defconfig
index 819a95b..fa78bde 100644
--- a/configs/cm_t3517_defconfig
+++ b/configs/cm_t3517_defconfig
@@ -48,6 +48,7 @@
CONFIG_OMAP3_SPI=y
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
+CONFIG_USB_MUSB_AM35X=y
CONFIG_USB_STORAGE=y
CONFIG_LCD=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/cm_t35_defconfig b/configs/cm_t35_defconfig
index c61a93b..0cb6e72 100644
--- a/configs/cm_t35_defconfig
+++ b/configs/cm_t35_defconfig
@@ -50,6 +50,9 @@
CONFIG_OMAP3_SPI=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MUSB_UDC=y
+CONFIG_USB_OMAP3=y
+CONFIG_TWL4030_USB=y
CONFIG_USB_STORAGE=y
CONFIG_LCD=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/cm_t43_defconfig b/configs/cm_t43_defconfig
index a621ff2..e234bc6 100644
--- a/configs/cm_t43_defconfig
+++ b/configs/cm_t43_defconfig
@@ -72,6 +72,7 @@
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_FAT_WRITE=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/comtrend_ar5315u_ram_defconfig b/configs/comtrend_ar5315u_ram_defconfig
new file mode 100644
index 0000000..84ea67c
--- /dev/null
+++ b/configs/comtrend_ar5315u_ram_defconfig
@@ -0,0 +1,51 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x80010000
+CONFIG_ARCH_BMIPS=y
+CONFIG_SOC_BMIPS_BCM6318=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5315u"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="AR-5315un # "
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+# CONFIG_CMD_MISC is not set
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_DM_GPIO=y
+CONFIG_LED=y
+CONFIG_LED_BCM6328=y
+CONFIG_LED_BLINK=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_BCM6328_POWER_DOMAIN=y
+CONFIG_DM_RESET=y
+CONFIG_RESET_BCM6345=y
+# CONFIG_SPL_SERIAL_PRESENT is not set
+CONFIG_DM_SERIAL=y
+CONFIG_BCM6345_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_BCM63XX_HSSPI=y
diff --git a/configs/comtrend_ar5387un_ram_defconfig b/configs/comtrend_ar5387un_ram_defconfig
index b64018a..352f01d 100644
--- a/configs/comtrend_ar5387un_ram_defconfig
+++ b/configs/comtrend_ar5387un_ram_defconfig
@@ -26,6 +26,8 @@
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
# CONFIG_CMD_NET is not set
# CONFIG_CMD_NFS is not set
# CONFIG_CMD_MISC is not set
@@ -34,6 +36,10 @@
CONFIG_LED=y
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_MTD=y
CONFIG_POWER_DOMAIN=y
CONFIG_BCM6328_POWER_DOMAIN=y
CONFIG_DM_RESET=y
@@ -41,3 +47,5 @@
# CONFIG_SPL_SERIAL_PRESENT is not set
CONFIG_DM_SERIAL=y
CONFIG_BCM6345_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_BCM63XX_HSSPI=y
diff --git a/configs/comtrend_wap5813n_ram_defconfig b/configs/comtrend_wap5813n_ram_defconfig
new file mode 100644
index 0000000..aba53cc
--- /dev/null
+++ b/configs/comtrend_wap5813n_ram_defconfig
@@ -0,0 +1,43 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x80010000
+CONFIG_ARCH_BMIPS=y
+CONFIG_SOC_BMIPS_BCM6368=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="comtrend,wap-5813n"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="WAP-5813n # "
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+# CONFIG_CMD_MISC is not set
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_DM_GPIO=y
+CONFIG_BCM6345_GPIO=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_CFI_FLASH=y
+CONFIG_DM_RESET=y
+CONFIG_RESET_BCM6345=y
+# CONFIG_SPL_SERIAL_PRESENT is not set
+CONFIG_DM_SERIAL=y
+CONFIG_BCM6345_SERIAL=y
diff --git a/configs/da850_am18xxevm_defconfig b/configs/da850_am18xxevm_defconfig
index 824c383..0675401 100644
--- a/configs/da850_am18xxevm_defconfig
+++ b/configs/da850_am18xxevm_defconfig
@@ -42,4 +42,5 @@
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_DM_SPI=y
+CONFIG_DAVINCI_SPI=y
# CONFIG_FAT_WRITE is not set
diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig
index 067ddd7..4c2f8f3 100644
--- a/configs/da850evm_defconfig
+++ b/configs/da850evm_defconfig
@@ -45,4 +45,5 @@
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_DM_SPI=y
+CONFIG_DAVINCI_SPI=y
# CONFIG_FAT_WRITE is not set
diff --git a/configs/da850evm_direct_nor_defconfig b/configs/da850evm_direct_nor_defconfig
index b00eea7..72b8169 100644
--- a/configs/da850evm_direct_nor_defconfig
+++ b/configs/da850evm_direct_nor_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_DAVINCI=y
CONFIG_TARGET_DA850EVM=y
+CONFIG_DA850_LOWLEVEL=y
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
# CONFIG_SYS_MALLOC_F is not set
@@ -43,3 +44,4 @@
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SYS_NS16550=y
CONFIG_DM_SPI=y
+CONFIG_DAVINCI_SPI=y
diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig
index 716a57b..b13a27e 100644
--- a/configs/dra7xx_evm_defconfig
+++ b/configs/dra7xx_evm_defconfig
@@ -80,6 +80,7 @@
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig
index f7418c7..7ccb4f0 100644
--- a/configs/dra7xx_hs_evm_defconfig
+++ b/configs/dra7xx_hs_evm_defconfig
@@ -82,6 +82,7 @@
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
+CONFIG_OMAP_USB_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
diff --git a/configs/draco_defconfig b/configs/draco_defconfig
index be0105f..5444260 100644
--- a/configs/draco_defconfig
+++ b/configs/draco_defconfig
@@ -64,6 +64,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Siemens AG"
diff --git a/configs/ds109_defconfig b/configs/ds109_defconfig
index 6d513cf..428ac8c 100644
--- a/configs/ds109_defconfig
+++ b/configs/ds109_defconfig
@@ -22,3 +22,4 @@
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
+CONFIG_FS_EXT4=y
diff --git a/configs/duovero_defconfig b/configs/duovero_defconfig
index f52cbe7..a510294 100644
--- a/configs/duovero_defconfig
+++ b/configs/duovero_defconfig
@@ -32,6 +32,8 @@
CONFIG_OMAP3_SPI=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MUSB_UDC=y
+CONFIG_USB_OMAP3=y
CONFIG_USB_STORAGE=y
CONFIG_FAT_WRITE=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/ea20_defconfig b/configs/ea20_defconfig
index eada103..abbb00a 100644
--- a/configs/ea20_defconfig
+++ b/configs/ea20_defconfig
@@ -32,5 +32,6 @@
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SYS_NS16550=y
+CONFIG_DAVINCI_SPI=y
CONFIG_VIDEO=y
# CONFIG_VIDEO_SW_CURSOR is not set
diff --git a/configs/etamin_defconfig b/configs/etamin_defconfig
index 8e8ef6f..608faf6 100644
--- a/configs/etamin_defconfig
+++ b/configs/etamin_defconfig
@@ -64,6 +64,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Siemens AG"
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig
index 6024b86..c10bec2 100644
--- a/configs/evb-rk3288_defconfig
+++ b/configs/evb-rk3288_defconfig
@@ -65,6 +65,7 @@
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_USB=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
CONFIG_USB_GADGET_VENDOR_NUM=0x2207
diff --git a/configs/fennec-rk3288_defconfig b/configs/fennec-rk3288_defconfig
index d76e8c4..9ae1b33 100644
--- a/configs/fennec-rk3288_defconfig
+++ b/configs/fennec-rk3288_defconfig
@@ -66,6 +66,7 @@
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_DWC2=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index e9eb20c..3a0bd79 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -71,6 +71,7 @@
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_DWC2=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
CONFIG_USB_GADGET=y
diff --git a/configs/igep0032_defconfig b/configs/igep0032_defconfig
index e394aa5..b0daee1 100644
--- a/configs/igep0032_defconfig
+++ b/configs/igep0032_defconfig
@@ -39,6 +39,10 @@
CONFIG_SMC911X_32_BIT=y
CONFIG_SYS_NS16550=y
CONFIG_OMAP3_SPI=y
+CONFIG_USB=y
+CONFIG_USB_MUSB_UDC=y
+CONFIG_USB_OMAP3=y
+CONFIG_TWL4030_USB=y
CONFIG_FAT_WRITE=y
CONFIG_BCH=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/igep00x0_defconfig b/configs/igep00x0_defconfig
index d70d4c6..22dbc70 100644
--- a/configs/igep00x0_defconfig
+++ b/configs/igep00x0_defconfig
@@ -40,6 +40,10 @@
CONFIG_SMC911X_32_BIT=y
CONFIG_SYS_NS16550=y
CONFIG_OMAP3_SPI=y
+CONFIG_USB=y
+CONFIG_USB_MUSB_UDC=y
+CONFIG_USB_OMAP3=y
+CONFIG_TWL4030_USB=y
CONFIG_FAT_WRITE=y
CONFIG_BCH=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/k2e_evm_defconfig b/configs/k2e_evm_defconfig
index 317d4f0..e6dc298 100644
--- a/configs/k2e_evm_defconfig
+++ b/configs/k2e_evm_defconfig
@@ -44,6 +44,7 @@
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_DM_SPI=y
+CONFIG_DAVINCI_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/k2e_hs_evm_defconfig b/configs/k2e_hs_evm_defconfig
index b9be606..6c5e167 100644
--- a/configs/k2e_hs_evm_defconfig
+++ b/configs/k2e_hs_evm_defconfig
@@ -33,6 +33,7 @@
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_DM_SPI=y
+CONFIG_DAVINCI_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig
index 32353e9..6a1f8dc 100644
--- a/configs/k2g_evm_defconfig
+++ b/configs/k2g_evm_defconfig
@@ -47,6 +47,7 @@
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_DM_SPI=y
+CONFIG_DAVINCI_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/k2g_hs_evm_defconfig b/configs/k2g_hs_evm_defconfig
index 9c4530c..b4985b5 100644
--- a/configs/k2g_hs_evm_defconfig
+++ b/configs/k2g_hs_evm_defconfig
@@ -35,6 +35,7 @@
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_DM_SPI=y
+CONFIG_DAVINCI_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/k2hk_evm_defconfig b/configs/k2hk_evm_defconfig
index 7115443..1e3905f 100644
--- a/configs/k2hk_evm_defconfig
+++ b/configs/k2hk_evm_defconfig
@@ -44,6 +44,7 @@
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_DM_SPI=y
+CONFIG_DAVINCI_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/k2hk_hs_evm_defconfig b/configs/k2hk_hs_evm_defconfig
index f65185f..b4b08dd 100644
--- a/configs/k2hk_hs_evm_defconfig
+++ b/configs/k2hk_hs_evm_defconfig
@@ -33,6 +33,7 @@
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_DM_SPI=y
+CONFIG_DAVINCI_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/k2l_evm_defconfig b/configs/k2l_evm_defconfig
index d2ec226..074bed0 100644
--- a/configs/k2l_evm_defconfig
+++ b/configs/k2l_evm_defconfig
@@ -44,6 +44,7 @@
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_DM_SPI=y
+CONFIG_DAVINCI_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/kc1_defconfig b/configs/kc1_defconfig
index 0ddf64c..e828405 100644
--- a/configs/kc1_defconfig
+++ b/configs/kc1_defconfig
@@ -38,6 +38,7 @@
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_OMAP2PLUS=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451
diff --git a/configs/legoev3_defconfig b/configs/legoev3_defconfig
index 209250a..d131079 100644
--- a/configs/legoev3_defconfig
+++ b/configs/legoev3_defconfig
@@ -26,5 +26,6 @@
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SYS_NS16550=y
+CONFIG_DAVINCI_SPI=y
CONFIG_OF_LIBFDT=y
# CONFIG_EFI_LOADER is not set
diff --git a/configs/miqi-rk3288_defconfig b/configs/miqi-rk3288_defconfig
index d0bcbd8..3a5ec2d 100644
--- a/configs/miqi-rk3288_defconfig
+++ b/configs/miqi-rk3288_defconfig
@@ -66,6 +66,7 @@
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_DWC2=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
diff --git a/configs/mx25pdk_defconfig b/configs/mx25pdk_defconfig
index 2905614..563c7ac 100644
--- a/configs/mx25pdk_defconfig
+++ b/configs/mx25pdk_defconfig
@@ -17,5 +17,6 @@
CONFIG_CMD_FS_GENERIC=y
CONFIG_DOS_PARTITION=y
CONFIG_ENV_IS_IN_MMC=y
+CONFIG_FS_EXT4=y
CONFIG_FS_FAT=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/netgear_cg3100d_ram_defconfig b/configs/netgear_cg3100d_ram_defconfig
index 7665c78..fb998f0 100644
--- a/configs/netgear_cg3100d_ram_defconfig
+++ b/configs/netgear_cg3100d_ram_defconfig
@@ -25,6 +25,8 @@
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
# CONFIG_CMD_NET is not set
# CONFIG_CMD_NFS is not set
# CONFIG_CMD_MISC is not set
@@ -35,9 +37,15 @@
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_MTD=y
CONFIG_DM_RESET=y
CONFIG_RESET_BCM6345=y
# CONFIG_SPL_SERIAL_PRESENT is not set
CONFIG_DM_SERIAL=y
CONFIG_BCM6345_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_BCM63XX_SPI=y
CONFIG_WDT_BCM6345=y
diff --git a/configs/nokia_rx51_defconfig b/configs/nokia_rx51_defconfig
index 9057811..e93042e 100644
--- a/configs/nokia_rx51_defconfig
+++ b/configs/nokia_rx51_defconfig
@@ -26,6 +26,11 @@
CONFIG_MMC_OMAP_HS=y
CONFIG_SYS_NS16550=y
CONFIG_OMAP3_SPI=y
+CONFIG_USB=y
+CONFIG_USB_MUSB_HCD=y
+CONFIG_USB_MUSB_UDC=y
+CONFIG_USB_OMAP3=y
+CONFIG_TWL4030_USB=y
CONFIG_VIDEO=y
CONFIG_CFB_CONSOLE_ANSI=y
# CONFIG_VGA_AS_SINGLE_DEVICE is not set
diff --git a/configs/odroid-xu3_defconfig b/configs/odroid-xu3_defconfig
index 976c06a..11b1c8b 100644
--- a/configs/odroid-xu3_defconfig
+++ b/configs/odroid-xu3_defconfig
@@ -22,6 +22,7 @@
CONFIG_CMD_TIME=y
CONFIG_CMD_PMIC=y
CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_REGULATOR=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ADC=y
CONFIG_ADC_EXYNOS=y
@@ -35,6 +36,7 @@
CONFIG_DM_PMIC=y
CONFIG_PMIC_S2MPS11=y
CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_S2MPS11=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
diff --git a/configs/omap3_beagle_defconfig b/configs/omap3_beagle_defconfig
index 95c8784..318c1f9 100644
--- a/configs/omap3_beagle_defconfig
+++ b/configs/omap3_beagle_defconfig
@@ -52,6 +52,8 @@
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_OMAP2PLUS=y
+CONFIG_TWL4030_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="TI"
diff --git a/configs/omap3_evm_defconfig b/configs/omap3_evm_defconfig
index d2b8d42..0ae1852 100644
--- a/configs/omap3_evm_defconfig
+++ b/configs/omap3_evm_defconfig
@@ -56,7 +56,9 @@
CONFIG_OMAP3_SPI=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OMAP3=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_OMAP2PLUS=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451
diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig
index db72e6f..3482538 100644
--- a/configs/omap3_logic_defconfig
+++ b/configs/omap3_logic_defconfig
@@ -29,6 +29,8 @@
CONFIG_CMD_UBI=y
CONFIG_ISO_PARTITION=y
CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_OF_PLATDATA=y
CONFIG_ENV_IS_IN_NAND=y
# CONFIG_BLK is not set
CONFIG_DM_I2C=y
@@ -48,7 +50,10 @@
CONFIG_OMAP3_SPI=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OMAP3=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_OMAP2PLUS=y
+CONFIG_TWL4030_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="TI"
@@ -56,3 +61,4 @@
CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
CONFIG_USB_ETHER=y
CONFIG_BCH=y
+# CONFIG_SPL_OF_LIBFDT is not set
diff --git a/configs/omap3_zoom1_defconfig b/configs/omap3_zoom1_defconfig
index 6639c7e..1a915c5 100644
--- a/configs/omap3_zoom1_defconfig
+++ b/configs/omap3_zoom1_defconfig
@@ -41,5 +41,9 @@
CONFIG_SMC911X_32_BIT=y
CONFIG_SYS_NS16550=y
CONFIG_OMAP3_SPI=y
+CONFIG_USB=y
+CONFIG_USB_MUSB_UDC=y
+CONFIG_USB_OMAP3=y
+CONFIG_TWL4030_USB=y
CONFIG_FAT_WRITE=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/omap4_panda_defconfig b/configs/omap4_panda_defconfig
index 0faea77..aa0c36e 100644
--- a/configs/omap4_panda_defconfig
+++ b/configs/omap4_panda_defconfig
@@ -31,6 +31,8 @@
CONFIG_OMAP3_SPI=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MUSB_UDC=y
+CONFIG_USB_OMAP3=y
CONFIG_USB_STORAGE=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_SMSC95XX=y
diff --git a/configs/omap4_sdp4430_defconfig b/configs/omap4_sdp4430_defconfig
index b7ba1f3..ac49571 100644
--- a/configs/omap4_sdp4430_defconfig
+++ b/configs/omap4_sdp4430_defconfig
@@ -27,5 +27,8 @@
CONFIG_MMC_OMAP_HS=y
CONFIG_SYS_NS16550=y
CONFIG_OMAP3_SPI=y
+CONFIG_USB=y
+CONFIG_USB_MUSB_UDC=y
+CONFIG_USB_OMAP3=y
CONFIG_FAT_WRITE=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/omapl138_lcdk_defconfig b/configs/omapl138_lcdk_defconfig
index 0d4506e..944be2b 100644
--- a/configs/omapl138_lcdk_defconfig
+++ b/configs/omapl138_lcdk_defconfig
@@ -36,4 +36,5 @@
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SYS_NS16550=y
+CONFIG_DAVINCI_SPI=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/pcm051_rev1_defconfig b/configs/pcm051_rev1_defconfig
index 273fc30..c16711a 100644
--- a/configs/pcm051_rev1_defconfig
+++ b/configs/pcm051_rev1_defconfig
@@ -58,6 +58,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_ETHER=y
diff --git a/configs/pcm051_rev3_defconfig b/configs/pcm051_rev3_defconfig
index f1ddaa6..a8fe7af 100644
--- a/configs/pcm051_rev3_defconfig
+++ b/configs/pcm051_rev3_defconfig
@@ -58,6 +58,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_ETHER=y
diff --git a/configs/pengwyn_defconfig b/configs/pengwyn_defconfig
index 4bb6245..78a6b7d 100644
--- a/configs/pengwyn_defconfig
+++ b/configs/pengwyn_defconfig
@@ -62,6 +62,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_FAT_WRITE=y
diff --git a/configs/phycore-rk3288_defconfig b/configs/phycore-rk3288_defconfig
index aea47c5..969b0e6 100644
--- a/configs/phycore-rk3288_defconfig
+++ b/configs/phycore-rk3288_defconfig
@@ -69,6 +69,7 @@
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_USB=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
diff --git a/configs/poplar_defconfig b/configs/poplar_defconfig
index 8f6ac2d..71ff228 100644
--- a/configs/poplar_defconfig
+++ b/configs/poplar_defconfig
@@ -17,4 +17,5 @@
CONFIG_USB_STORAGE=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
+CONFIG_FAT_WRITE=y
CONFIG_LIB_RAND=y
diff --git a/configs/popmetal-rk3288_defconfig b/configs/popmetal-rk3288_defconfig
index 6b860bb..94f4979 100644
--- a/configs/popmetal-rk3288_defconfig
+++ b/configs/popmetal-rk3288_defconfig
@@ -66,6 +66,7 @@
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_DWC2=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
diff --git a/configs/pxm2_defconfig b/configs/pxm2_defconfig
index 0ec1591..f682300 100644
--- a/configs/pxm2_defconfig
+++ b/configs/pxm2_defconfig
@@ -67,6 +67,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Siemens AG"
diff --git a/configs/rastaban_defconfig b/configs/rastaban_defconfig
index 5ef1740..c714b07 100644
--- a/configs/rastaban_defconfig
+++ b/configs/rastaban_defconfig
@@ -64,6 +64,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Siemens AG"
diff --git a/configs/rock2_defconfig b/configs/rock2_defconfig
index 43dce46..0a95e6a 100644
--- a/configs/rock2_defconfig
+++ b/configs/rock2_defconfig
@@ -66,6 +66,7 @@
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_USB=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
CONFIG_USB_GADGET_VENDOR_NUM=0x2207
diff --git a/configs/rock_defconfig b/configs/rock_defconfig
index b174e4b..483f64b 100644
--- a/configs/rock_defconfig
+++ b/configs/rock_defconfig
@@ -47,6 +47,8 @@
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_SPL_TINY_MEMSET=y
CONFIG_TPL_TINY_MEMSET=y
CONFIG_CMD_DHRYSTONE=y
diff --git a/configs/rut_defconfig b/configs/rut_defconfig
index 1711fc7..2269747 100644
--- a/configs/rut_defconfig
+++ b/configs/rut_defconfig
@@ -68,6 +68,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Siemens AG"
diff --git a/configs/sagem_f@st1704_ram_defconfig b/configs/sagem_f@st1704_ram_defconfig
index cfc56cb..07a125c 100644
--- a/configs/sagem_f@st1704_ram_defconfig
+++ b/configs/sagem_f@st1704_ram_defconfig
@@ -26,6 +26,8 @@
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
# CONFIG_CMD_NET is not set
# CONFIG_CMD_NFS is not set
# CONFIG_CMD_MISC is not set
@@ -34,8 +36,14 @@
CONFIG_BCM6345_GPIO=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
CONFIG_DM_RESET=y
CONFIG_RESET_BCM6345=y
# CONFIG_SPL_SERIAL_PRESENT is not set
CONFIG_DM_SERIAL=y
CONFIG_BCM6345_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_BCM63XX_SPI=y
diff --git a/configs/sniper_defconfig b/configs/sniper_defconfig
index a8a592f..a3bae56 100644
--- a/configs/sniper_defconfig
+++ b/configs/sniper_defconfig
@@ -39,6 +39,8 @@
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_OMAP2PLUS=y
+CONFIG_TWL4030_USB=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451
diff --git a/configs/thuban_defconfig b/configs/thuban_defconfig
index 2575c00..df76145 100644
--- a/configs/thuban_defconfig
+++ b/configs/thuban_defconfig
@@ -64,6 +64,7 @@
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Siemens AG"
diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig
index c79dffd..a0df3fd 100644
--- a/configs/tinker-rk3288_defconfig
+++ b/configs/tinker-rk3288_defconfig
@@ -69,6 +69,7 @@
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_DWC2=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
diff --git a/configs/vyasa-rk3288_defconfig b/configs/vyasa-rk3288_defconfig
index 30ad478..5d8fa22 100644
--- a/configs/vyasa-rk3288_defconfig
+++ b/configs/vyasa-rk3288_defconfig
@@ -63,6 +63,7 @@
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_USB=y
+CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
diff --git a/doc/README.ext4 b/doc/README.ext4
index 2b0eab5..8ecd21e 100644
--- a/doc/README.ext4
+++ b/doc/README.ext4
@@ -2,10 +2,10 @@
mode or in read-write mode.
First, to enable support for both ext4 (and, automatically, ext2 as well),
-but without selecting the corresponding commands, use one of:
+but without selecting the corresponding commands, enable one of the following:
- #define CONFIG_FS_EXT4 (for read-only)
- #define CONFIG_EXT4_WRITE (for read-write)
+ CONFIG_FS_EXT4 (for read-only)
+ CONFIG_EXT4_WRITE (for read-write)
Next, to select the ext2-related commands:
@@ -20,22 +20,22 @@
use one or both of:
- #define CONFIG_CMD_EXT2
- #define CONFIG_CMD_EXT4
+ CONFIG_CMD_EXT2
+ CONFIG_CMD_EXT4
-Selecting either of the above automatically defines CONFIG_FS_EXT4 if it
-wasn't defined already.
+Selecting either of the above automatically selects CONFIG_FS_EXT4 if it
+wasn't enabled already.
-In addition, to get the write access command "ext4write", use:
+In addition, to get the write access command "ext4write", enable:
- #define CONFIG_CMD_EXT4_WRITE
+ CONFIG_CMD_EXT4_WRITE
-which automatically defines CONFIG_EXT4_WRITE if it wasn't defined
+which automatically selects CONFIG_EXT4_WRITE if it wasn't defined
already.
Also relevant are the generic filesystem commands, selected by:
- #define CONFIG_CMD_FS_GENERIC
+ CONFIG_CMD_FS_GENERIC
This does not automatically enable EXT4 support for you, you still need
to do that yourself.
diff --git a/doc/device-tree-bindings/spi/soft-spi.txt b/doc/device-tree-bindings/spi/soft-spi.txt
index d09c1a5..dfb5066 100644
--- a/doc/device-tree-bindings/spi/soft-spi.txt
+++ b/doc/device-tree-bindings/spi/soft-spi.txt
@@ -6,11 +6,15 @@
The soft SPI node requires the following properties:
-compatible: "u-boot,soft-spi"
-soft_spi_cs: GPIO number to use for SPI chip select (output)
-soft_spi_sclk: GPIO number to use for SPI clock (output)
-soft_spi_mosi: GPIO number to use for SPI MOSI line (output)
-soft_spi_miso GPIO number to use for SPI MISO line (input)
+Mandatory properties:
+compatible: "spi-gpio"
+cs-gpios: GPIOs to use for SPI chip select (output)
+gpio-sck: GPIO to use for SPI clock (output)
+And at least one of:
+gpio-mosi: GPIO to use for SPI MOSI line (output)
+gpio-miso: GPIO to use for SPI MISO line (input)
+
+Optional propertie:
spi-delay-us: Number of microseconds of delay between each CS transition
The GPIOs should be specified as required by the GPIO controller referenced.
@@ -21,11 +25,11 @@
Example:
soft-spi {
- compatible = "u-boot,soft-spi";
- cs-gpio = <&gpio 235 0>; /* Y43 */
- sclk-gpio = <&gpio 225 0>; /* Y31 */
- mosi-gpio = <&gpio 227 0>; /* Y33 */
- miso-gpio = <&gpio 224 0>; /* Y30 */
+ compatible = "spi-gpio";
+ cs-gpios = <&gpio 235 0>; /* Y43 */
+ gpio-sck = <&gpio 225 0>; /* Y31 */
+ gpio-mosi = <&gpio 227 0>; /* Y33 */
+ gpio-miso = <&gpio 224 0>; /* Y30 */
spi-delay-us = <1>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/doc/device-tree-bindings/spi/spi-cadence.txt b/doc/device-tree-bindings/spi/spi-cadence.txt
index c1e2233..74c8208 100644
--- a/doc/device-tree-bindings/spi/spi-cadence.txt
+++ b/doc/device-tree-bindings/spi/spi-cadence.txt
@@ -6,7 +6,10 @@
- reg : 1.Physical base address and size of SPI registers map.
2. Physical base address & size of NOR Flash.
- clocks : Clock phandles (see clock bindings for details).
-- sram-size : spi controller sram size.
+- cdns,fifo-depth : Size of the data FIFO in words.
+- cdns,fifo-width : Bus width of the data FIFO in bytes.
+- cdns,trigger-address : 32-bit indirect AHB trigger address.
+- cdns,is-decoded-cs : Flag to indicate whether decoder is used or not.
- status : enable in requried dts.
connected flash properties
@@ -15,14 +18,14 @@
- spi-max-frequency : Max supported spi frequency.
- page-size : Flash page size.
- block-size : Flash memory block size.
-- tshsl-ns : Added delay in master reference clocks (ref_clk) for
+- cdns,tshsl-ns : Added delay in master reference clocks (ref_clk) for
the length that the master mode chip select outputs
are de-asserted between transactions.
-- tsd2d-ns : Delay in master reference clocks (ref_clk) between one
+- cdns,tsd2d-ns : Delay in master reference clocks (ref_clk) between one
chip select being de-activated and the activation of
another.
-- tchsh-ns : Delay in master reference clocks between last bit of
+- cdns,tchsh-ns : Delay in master reference clocks between last bit of
current transaction and de-asserting the device chip
select (n_ss_out).
-- tslch-ns : Delay in master reference clocks between setting
+- cdns,tslch-ns : Delay in master reference clocks between setting
n_ss_out low and first bit transfer
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 010ed32..bfda221 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -24,6 +24,7 @@
[IF_TYPE_HOST] = "host",
[IF_TYPE_SYSTEMACE] = "ace",
[IF_TYPE_NVME] = "nvme",
+ [IF_TYPE_EFI] = "efi",
};
static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
@@ -36,8 +37,9 @@
[IF_TYPE_SD] = UCLASS_INVALID,
[IF_TYPE_SATA] = UCLASS_AHCI,
[IF_TYPE_HOST] = UCLASS_ROOT,
- [IF_TYPE_NVME] = UCLASS_NVME,
[IF_TYPE_SYSTEMACE] = UCLASS_INVALID,
+ [IF_TYPE_NVME] = UCLASS_NVME,
+ [IF_TYPE_EFI] = UCLASS_EFI,
};
static enum if_type if_typename_to_iftype(const char *if_typename)
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 876c2b8..dab106a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -6,21 +6,21 @@
#
obj-$(CONFIG_$(SPL_TPL_)CLK) += clk-uclass.o clk_fixed_rate.o
-obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
-obj-$(CONFIG_SANDBOX) += clk_sandbox.o
-obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
-obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
-obj-$(CONFIG_CLK_RENESAS) += renesas/
-obj-$(CONFIG_CLK_ZYNQ) += clk_zynq.o
-obj-$(CONFIG_CLK_ZYNQMP) += clk_zynqmp.o
obj-y += tegra/
-obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
-obj-$(CONFIG_CLK_EXYNOS) += exynos/
+obj-$(CONFIG_ARCH_ASPEED) += aspeed/
+obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_CLK_AT91) += at91/
obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
+obj-$(CONFIG_CLK_EXYNOS) += exynos/
obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
-obj-$(CONFIG_ARCH_ASPEED) += aspeed/
+obj-$(CONFIG_CLK_RENESAS) += renesas/
obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
+obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
+obj-$(CONFIG_CLK_ZYNQ) += clk_zynq.o
+obj-$(CONFIG_CLK_ZYNQMP) += clk_zynqmp.o
+obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
+obj-$(CONFIG_SANDBOX) += clk_sandbox.o
+obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
obj-$(CONFIG_STM32H7) += clk_stm32h7.o
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 83ba133..fbea720 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -13,11 +13,9 @@
#include <dt-structs.h>
#include <errno.h>
-DECLARE_GLOBAL_DATA_PTR;
-
-static inline struct clk_ops *clk_dev_ops(struct udevice *dev)
+static inline const struct clk_ops *clk_dev_ops(struct udevice *dev)
{
- return (struct clk_ops *)dev->driver->ops;
+ return (const struct clk_ops *)dev->driver->ops;
}
#if CONFIG_IS_ENABLED(OF_CONTROL)
@@ -60,7 +58,7 @@
int ret;
struct ofnode_phandle_args args;
struct udevice *dev_clk;
- struct clk_ops *ops;
+ const struct clk_ops *ops;
debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk);
@@ -68,7 +66,7 @@
clk->dev = NULL;
ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
- index, &args);
+ index, &args);
if (ret) {
debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
__func__, ret);
@@ -142,7 +140,7 @@
int clk_request(struct udevice *dev, struct clk *clk)
{
- struct clk_ops *ops = clk_dev_ops(dev);
+ const struct clk_ops *ops = clk_dev_ops(dev);
debug("%s(dev=%p, clk=%p)\n", __func__, dev, clk);
@@ -156,7 +154,7 @@
int clk_free(struct clk *clk)
{
- struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops = clk_dev_ops(clk->dev);
debug("%s(clk=%p)\n", __func__, clk);
@@ -168,7 +166,7 @@
ulong clk_get_rate(struct clk *clk)
{
- struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops = clk_dev_ops(clk->dev);
debug("%s(clk=%p)\n", __func__, clk);
@@ -180,7 +178,7 @@
ulong clk_set_rate(struct clk *clk, ulong rate)
{
- struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops = clk_dev_ops(clk->dev);
debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate);
@@ -192,7 +190,7 @@
int clk_enable(struct clk *clk)
{
- struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops = clk_dev_ops(clk->dev);
debug("%s(clk=%p)\n", __func__, clk);
@@ -204,7 +202,7 @@
int clk_disable(struct clk *clk)
{
- struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops = clk_dev_ops(clk->dev);
debug("%s(clk=%p)\n", __func__, clk);
diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c
index 63565b6..c9a9f0a 100644
--- a/drivers/clk/clk_fixed_rate.c
+++ b/drivers/clk/clk_fixed_rate.c
@@ -8,8 +8,6 @@
#include <clk-uclass.h>
#include <dm.h>
-DECLARE_GLOBAL_DATA_PTR;
-
struct clk_fixed_rate {
unsigned long fixed_rate;
};
@@ -31,8 +29,8 @@
static int clk_fixed_rate_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
- to_clk_fixed_rate(dev)->fixed_rate = dev_read_u32_default(dev,
- "clock-frequency", 0);
+ to_clk_fixed_rate(dev)->fixed_rate =
+ dev_read_u32_default(dev, "clock-frequency", 0);
#endif
return 0;
diff --git a/drivers/clk/clk_pic32.c b/drivers/clk/clk_pic32.c
index f6eef31..1778039 100644
--- a/drivers/clk/clk_pic32.c
+++ b/drivers/clk/clk_pic32.c
@@ -197,8 +197,8 @@
writel(REFO_ON | REFO_OE, reg + _CLR_OFFSET);
/* wait till previous src change is active */
- wait_for_bit(__func__, reg, REFO_DIVSW_EN | REFO_ACTIVE,
- false, CONFIG_SYS_HZ, false);
+ wait_for_bit_le32(reg, REFO_DIVSW_EN | REFO_ACTIVE,
+ false, CONFIG_SYS_HZ, false);
/* parent_id */
v = readl(reg);
@@ -223,8 +223,8 @@
writel(REFO_DIVSW_EN, reg + _SET_OFFSET);
/* wait for divider switching to complete */
- return wait_for_bit(__func__, reg, REFO_DIVSW_EN, false,
- CONFIG_SYS_HZ, false);
+ return wait_for_bit_le32(reg, REFO_DIVSW_EN, false,
+ CONFIG_SYS_HZ, false);
}
static ulong pic32_get_refclk(struct pic32_clk_priv *priv, int periph)
@@ -311,8 +311,8 @@
/* Wait for ready */
mask = MPLL_RDY | MPLL_VREG_RDY;
- return wait_for_bit(__func__, priv->syscfg_base + CFGMPLL, mask,
- true, get_tbclk(), false);
+ return wait_for_bit_le32(priv->syscfg_base + CFGMPLL, mask,
+ true, get_tbclk(), false);
}
static void pic32_clk_init(struct udevice *dev)
diff --git a/drivers/clk/renesas/clk-rcar-gen3.c b/drivers/clk/renesas/clk-rcar-gen3.c
index b26bbcc..22828fd 100644
--- a/drivers/clk/renesas/clk-rcar-gen3.c
+++ b/drivers/clk/renesas/clk-rcar-gen3.c
@@ -1046,8 +1046,8 @@
if (ret)
return ret;
clrbits_le32(priv->base + SMSTPCR(reg), bitmask);
- return wait_for_bit("MSTP", priv->base + MSTPSR(reg),
- bitmask, 0, 100, 0);
+ return wait_for_bit_le32(priv->base + MSTPSR(reg),
+ bitmask, 0, 100, 0);
} else {
setbits_le32(priv->base + SMSTPCR(reg), bitmask);
return 0;
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 9a46a7b..144ac2a 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -17,6 +17,7 @@
#include <dm/device.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
+#include <dm/of_access.h>
#include <dm/pinctrl.h>
#include <dm/platdata.h>
#include <dm/read.h>
@@ -703,8 +704,12 @@
bool device_is_compatible(struct udevice *dev, const char *compat)
{
const void *fdt = gd->fdt_blob;
+ ofnode node = dev_ofnode(dev);
- return !fdt_node_check_compatible(fdt, dev_of_offset(dev), compat);
+ if (ofnode_is_np(node))
+ return of_device_is_compatible(ofnode_to_np(node), compat, NULL, NULL);
+ else
+ return !fdt_node_check_compatible(fdt, ofnode_to_offset(node), compat);
}
bool of_machine_is_compatible(const char *compat)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 0030ab9..98f4b53 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -205,8 +205,13 @@
&flags);
if (!prop_val)
return FDT_ADDR_T_NONE;
- na = of_n_addr_cells(ofnode_to_np(node));
- return of_read_number(prop_val, na);
+
+ if (IS_ENABLED(CONFIG_OF_TRANSLATE)) {
+ return of_translate_address(ofnode_to_np(node), prop_val);
+ } else {
+ na = of_n_addr_cells(ofnode_to_np(node));
+ return of_read_number(prop_val, na);
+ }
} else {
return fdt_get_base_address(gd->fdt_blob,
ofnode_to_offset(node));
@@ -296,7 +301,8 @@
int ret;
ret = of_parse_phandle_with_args(ofnode_to_np(node),
- list_name, cells_name, index, &args);
+ list_name, cells_name, index,
+ &args);
if (ret)
return ret;
ofnode_from_of_phandle_args(&args, out_args);
@@ -305,8 +311,9 @@
int ret;
ret = fdtdec_parse_phandle_with_args(gd->fdt_blob,
- ofnode_to_offset(node), list_name, cells_name,
- cell_count, index, &args);
+ ofnode_to_offset(node),
+ list_name, cells_name,
+ cell_count, index, &args);
if (ret)
return ret;
ofnode_from_fdtdec_phandle_args(&args, out_args);
@@ -534,10 +541,10 @@
addr->phys_mid = fdt32_to_cpu(cell[1]);
addr->phys_lo = fdt32_to_cpu(cell[1]);
break;
- } else {
- cell += (FDT_PCI_ADDR_CELLS +
- FDT_PCI_SIZE_CELLS);
}
+
+ cell += (FDT_PCI_ADDR_CELLS +
+ FDT_PCI_SIZE_CELLS);
}
if (i == num) {
@@ -546,10 +553,10 @@
}
return 0;
- } else {
- ret = -EINVAL;
}
+ ret = -EINVAL;
+
fail:
debug("(not found)\n");
return ret;
@@ -642,3 +649,11 @@
return ofnode_read_resource(node, index, res);
}
+
+u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr)
+{
+ if (ofnode_is_np(node))
+ return of_translate_address(ofnode_to_np(node), in_addr);
+ else
+ return fdt_translate_address(gd->fdt_blob, ofnode_to_offset(node), in_addr);
+}
diff --git a/drivers/core/read.c b/drivers/core/read.c
index f346cc1..601d132 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -10,6 +10,11 @@
#include <mapmem.h>
#include <dm/of_access.h>
+int dev_read_u32(struct udevice *dev, const char *propname, u32 *outp)
+{
+ return ofnode_read_u32(dev_ofnode(dev), propname, outp);
+}
+
int dev_read_u32_default(struct udevice *dev, const char *propname, int def)
{
return ofnode_read_u32_default(dev_ofnode(dev), propname, def);
@@ -66,7 +71,7 @@
}
fdt_addr_t dev_read_addr_size(struct udevice *dev, const char *property,
- fdt_size_t *sizep)
+ fdt_size_t *sizep)
{
return ofnode_get_addr_size(dev_ofnode(dev), property, sizep);
}
@@ -77,7 +82,7 @@
}
int dev_read_stringlist_search(struct udevice *dev, const char *property,
- const char *string)
+ const char *string)
{
return ofnode_stringlist_search(dev_ofnode(dev), property, string);
}
@@ -94,9 +99,8 @@
}
int dev_read_phandle_with_args(struct udevice *dev, const char *list_name,
- const char *cells_name, int cell_count,
- int index,
- struct ofnode_phandle_args *out_args)
+ const char *cells_name, int cell_count,
+ int index, struct ofnode_phandle_args *out_args)
{
return ofnode_parse_phandle_with_args(dev_ofnode(dev), list_name,
cells_name, cell_count, index,
@@ -196,3 +200,8 @@
{
return ofnode_read_resource_byname(dev_ofnode(dev), name, res);
}
+
+u64 dev_translate_address(struct udevice *dev, const fdt32_t *in_addr)
+{
+ return ofnode_translate_address(dev_ofnode(dev), in_addr);
+}
diff --git a/drivers/cpu/bmips_cpu.c b/drivers/cpu/bmips_cpu.c
index 1eb744a..4ad291a 100644
--- a/drivers/cpu/bmips_cpu.c
+++ b/drivers/cpu/bmips_cpu.c
@@ -26,6 +26,10 @@
#define REG_BCM6328_OTP 0x62c
#define BCM6328_TP1_DISABLED BIT(9)
+#define REG_BCM6318_STRAP_OVRDBUS 0x900
+#define OVRDBUS_6318_FREQ_SHIFT 23
+#define OVRDBUS_6318_FREQ_MASK (0x3 << OVRDBUS_6318_FREQ_SHIFT)
+
#define REG_BCM6328_MISC_STRAPBUS 0x1a40
#define STRAPBUS_6328_FCVO_SHIFT 7
#define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT)
@@ -46,6 +50,17 @@
#define DMIPSPLLCFG_6358_N2_SHIFT 29
#define DMIPSPLLCFG_6358_N2_MASK (0x7 << DMIPSPLLCFG_6358_N2_SHIFT)
+#define REG_BCM6368_DDR_DMIPSPLLCFG 0x12a0
+#define DMIPSPLLCFG_6368_P1_SHIFT 0
+#define DMIPSPLLCFG_6368_P1_MASK (0xf << DMIPSPLLCFG_6368_P1_SHIFT)
+#define DMIPSPLLCFG_6368_P2_SHIFT 4
+#define DMIPSPLLCFG_6368_P2_MASK (0xf << DMIPSPLLCFG_6368_P2_SHIFT)
+#define DMIPSPLLCFG_6368_NDIV_SHIFT 16
+#define DMIPSPLLCFG_6368_NDIV_MASK (0x1ff << DMIPSPLLCFG_6368_NDIV_SHIFT)
+#define REG_BCM6368_DDR_DMIPSPLLDIV 0x12a4
+#define DMIPSPLLDIV_6368_MDIV_SHIFT 0
+#define DMIPSPLLDIV_6368_MDIV_MASK (0xff << DMIPSPLLDIV_6368_MDIV_SHIFT)
+
#define REG_BCM63268_MISC_STRAPBUS 0x1814
#define STRAPBUS_63268_FCVO_SHIFT 21
#define STRAPBUS_63268_FCVO_MASK (0xf << STRAPBUS_63268_FCVO_SHIFT)
@@ -101,6 +116,28 @@
return 333000000;
}
+static ulong bcm6318_get_cpu_freq(struct bmips_cpu_priv *priv)
+{
+ unsigned int mips_pll_fcvo;
+
+ mips_pll_fcvo = readl_be(priv->regs + REG_BCM6318_STRAP_OVRDBUS);
+ mips_pll_fcvo = (mips_pll_fcvo & OVRDBUS_6318_FREQ_MASK)
+ >> OVRDBUS_6318_FREQ_SHIFT;
+
+ switch (mips_pll_fcvo) {
+ case 0:
+ return 166000000;
+ case 1:
+ return 400000000;
+ case 2:
+ return 250000000;
+ case 3:
+ return 333000000;
+ default:
+ return 0;
+ }
+}
+
static ulong bcm6328_get_cpu_freq(struct bmips_cpu_priv *priv)
{
unsigned int mips_pll_fcvo;
@@ -157,6 +194,22 @@
return (16 * 1000000 * n1 * n2) / m1;
}
+static ulong bcm6368_get_cpu_freq(struct bmips_cpu_priv *priv)
+{
+ unsigned int tmp, p1, p2, ndiv, m1;
+
+ tmp = readl_be(priv->regs + REG_BCM6368_DDR_DMIPSPLLCFG);
+ p1 = (tmp & DMIPSPLLCFG_6368_P1_MASK) >> DMIPSPLLCFG_6368_P1_SHIFT;
+ p2 = (tmp & DMIPSPLLCFG_6368_P2_MASK) >> DMIPSPLLCFG_6368_P2_SHIFT;
+ ndiv = (tmp & DMIPSPLLCFG_6368_NDIV_MASK) >>
+ DMIPSPLLCFG_6368_NDIV_SHIFT;
+
+ tmp = readl_be(priv->regs + REG_BCM6368_DDR_DMIPSPLLDIV);
+ m1 = (tmp & DMIPSPLLDIV_6368_MDIV_MASK) >> DMIPSPLLDIV_6368_MDIV_SHIFT;
+
+ return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
+}
+
static ulong bcm63268_get_cpu_freq(struct bmips_cpu_priv *priv)
{
unsigned int mips_pll_fcvo;
@@ -206,6 +259,12 @@
.get_cpu_count = bcm6358_get_cpu_count,
};
+static const struct bmips_cpu_hw bmips_cpu_bcm6318 = {
+ .get_cpu_desc = bmips_short_cpu_desc,
+ .get_cpu_freq = bcm6318_get_cpu_freq,
+ .get_cpu_count = bcm6345_get_cpu_count,
+};
+
static const struct bmips_cpu_hw bmips_cpu_bcm6328 = {
.get_cpu_desc = bmips_long_cpu_desc,
.get_cpu_freq = bcm6328_get_cpu_freq,
@@ -230,6 +289,12 @@
.get_cpu_count = bcm6358_get_cpu_count,
};
+static const struct bmips_cpu_hw bmips_cpu_bcm6368 = {
+ .get_cpu_desc = bmips_short_cpu_desc,
+ .get_cpu_freq = bcm6368_get_cpu_freq,
+ .get_cpu_count = bcm6358_get_cpu_count,
+};
+
static const struct bmips_cpu_hw bmips_cpu_bcm63268 = {
.get_cpu_desc = bmips_long_cpu_desc,
.get_cpu_freq = bcm63268_get_cpu_freq,
@@ -315,6 +380,9 @@
.compatible = "brcm,bcm3380-cpu",
.data = (ulong)&bmips_cpu_bcm3380,
}, {
+ .compatible = "brcm,bcm6318-cpu",
+ .data = (ulong)&bmips_cpu_bcm6318,
+ }, {
.compatible = "brcm,bcm6328-cpu",
.data = (ulong)&bmips_cpu_bcm6328,
}, {
@@ -327,6 +395,9 @@
.compatible = "brcm,bcm6358-cpu",
.data = (ulong)&bmips_cpu_bcm6358,
}, {
+ .compatible = "brcm,bcm6368-cpu",
+ .data = (ulong)&bmips_cpu_bcm6368,
+ }, {
.compatible = "brcm,bcm63268-cpu",
.data = (ulong)&bmips_cpu_bcm63268,
},
diff --git a/drivers/crypto/fsl/fsl_hash.c b/drivers/crypto/fsl/fsl_hash.c
index a63eba3..9373a39 100644
--- a/drivers/crypto/fsl/fsl_hash.c
+++ b/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 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;
}
diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c
index 058c9b9..b3a27ec 100644
--- a/drivers/ddr/fsl/fsl_ddr_gen4.c
+++ b/drivers/ddr/fsl/fsl_ddr_gen4.c
@@ -95,6 +95,9 @@
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 @@
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,
diff --git a/drivers/ddr/microchip/ddr2.c b/drivers/ddr/microchip/ddr2.c
index 6056418..a52427c 100644
--- a/drivers/ddr/microchip/ddr2.c
+++ b/drivers/ddr/microchip/ddr2.c
@@ -57,8 +57,8 @@
writel(SCL_START | SCL_EN, &ddr2_phy->scl_start);
/* Wait for SCL for data byte to pass */
- return wait_for_bit(__func__, &ddr2_phy->scl_start, SCL_LUBPASS,
- true, CONFIG_SYS_HZ, false);
+ return wait_for_bit_le32(&ddr2_phy->scl_start, SCL_LUBPASS,
+ true, CONFIG_SYS_HZ, false);
}
/* DDR2 Controller initialization */
@@ -256,8 +256,8 @@
writel(INIT_START, &ctrl->memcon);
/* wait for all host cmds to be transmitted */
- wait_for_bit(__func__, &ctrl->cmdissue, CMD_VALID, false,
- CONFIG_SYS_HZ, false);
+ wait_for_bit_le32(&ctrl->cmdissue, CMD_VALID, false,
+ CONFIG_SYS_HZ, false);
/* inform all cmds issued, ready for normal operation */
writel(INIT_START | INIT_DONE, &ctrl->memcon);
diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c
index 5c1a68a..d576396 100644
--- a/drivers/fpga/socfpga_arria10.c
+++ b/drivers/fpga/socfpga_arria10.c
@@ -62,8 +62,7 @@
static int wait_for_user_mode(void)
{
- return wait_for_bit(__func__,
- &fpga_manager_base->imgcfg_stat,
+ return wait_for_bit_le32(&fpga_manager_base->imgcfg_stat,
ALT_FPGAMGR_IMGCFG_STAT_F2S_USERMODE_SET_MSK,
1, FPGA_TIMEOUT_MSEC, false);
}
@@ -115,19 +114,17 @@
/* Poll until f2s_nconfig_pin and f2s_nstatus_pin; loop until de-asserted,
* timeout at 1000ms
*/
- return wait_for_bit(__func__,
- &fpga_manager_base->imgcfg_stat,
- mask,
- false, FPGA_TIMEOUT_MSEC, false);
+ return wait_for_bit_le32(&fpga_manager_base->imgcfg_stat,
+ mask,
+ false, FPGA_TIMEOUT_MSEC, false);
}
static int wait_for_f2s_nstatus_pin(unsigned long value)
{
/* Poll until f2s to specific value, timeout at 1000ms */
- return wait_for_bit(__func__,
- &fpga_manager_base->imgcfg_stat,
- ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN_SET_MSK,
- value, FPGA_TIMEOUT_MSEC, false);
+ return wait_for_bit_le32(&fpga_manager_base->imgcfg_stat,
+ ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN_SET_MSK,
+ value, FPGA_TIMEOUT_MSEC, false);
}
/* set CD ratio */
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index ab0627a..bc29611 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -17,6 +17,11 @@
help
Enable write access to MMC and SD Cards
+config MMC_BROKEN_CD
+ bool "Poll for broken card detection case"
+ help
+ If card detection feature is broken, just poll to detect.
+
config DM_MMC
bool "Enable MMC controllers using Driver Model"
depends on DM
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 71c62f4..8d1e2f8 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -528,14 +528,19 @@
static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
{
+ struct fsl_esdhc *regs = priv->esdhc_regs;
int div = 1;
#ifdef ARCH_MXC
+#ifdef CONFIG_MX53
+ /* For i.MX53 eSDHCv3, SYSCTL.SDCLKFS may not be set to 0. */
+ int pre_div = (regs == (struct fsl_esdhc *)MMC_SDHC3_BASE_ADDR) ? 2 : 1;
+#else
int pre_div = 1;
+#endif
#else
int pre_div = 2;
#endif
int ddr_pre_div = mmc->ddr_mode ? 2 : 1;
- struct fsl_esdhc *regs = priv->esdhc_regs;
int sdhc_clk = priv->sdhc_clk;
uint clk;
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 26c6ab7..a3536b1 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -140,13 +140,12 @@
cfg->host_caps |= MMC_MODE_1BIT;
break;
default:
- debug("warning: %s invalid bus-width property. using 1-bit\n",
- dev_read_name(dev));
- cfg->host_caps |= MMC_MODE_1BIT;
- break;
+ dev_err(dev, "Invalid \"bus-width\" value %u!\n", val);
+ return -EINVAL;
}
- cfg->f_max = dev_read_u32_default(dev, "max-frequency", 52000000);
+ /* f_max is obtained from the optional "max-frequency" property */
+ dev_read_u32(dev, "max-frequency", &cfg->f_max);
if (dev_read_bool(dev, "cap-sd-highspeed"))
cfg->host_caps |= MMC_CAP(SD_HS);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 53c8191..255310a 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1501,11 +1501,13 @@
int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
{
- if (clock > mmc->cfg->f_max)
- clock = mmc->cfg->f_max;
+ if (!disable) {
+ if (clock > mmc->cfg->f_max)
+ clock = mmc->cfg->f_max;
- if (clock < mmc->cfg->f_min)
- clock = mmc->cfg->f_min;
+ if (clock < mmc->cfg->f_min)
+ clock = mmc->cfg->f_min;
+ }
mmc->clock = clock;
mmc->clk_disable = disable;
@@ -2449,7 +2451,7 @@
static int mmc_power_off(struct mmc *mmc)
{
- mmc_set_clock(mmc, 1, true);
+ mmc_set_clock(mmc, 0, true);
#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
if (mmc->vmmc_supply) {
int ret = regulator_set_enable(mmc->vmmc_supply, false);
@@ -2491,8 +2493,12 @@
mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
+#if !defined(CONFIG_MMC_BROKEN_CD)
/* we pretend there's no card when init is NULL */
no_card = mmc_getcd(mmc) == 0;
+#else
+ no_card = 0;
+#endif
#if !CONFIG_IS_ENABLED(DM_MMC)
no_card = no_card || (mmc->cfg->ops->init == NULL);
#endif
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
index 9117ab6..f0661bd 100644
--- a/drivers/mmc/msm_sdhci.c
+++ b/drivers/mmc/msm_sdhci.c
@@ -109,15 +109,15 @@
/* Wait for reset to be written to register */
- if (wait_for_bit(__func__, prv->base + SDCC_MCI_STATUS2,
- SDCC_MCI_STATUS2_MCI_ACT, false, 10, false)) {
+ if (wait_for_bit_le32(prv->base + SDCC_MCI_STATUS2,
+ SDCC_MCI_STATUS2_MCI_ACT, false, 10, false)) {
printf("msm_sdhci: reset request failed\n");
return -EIO;
}
/* SW reset can take upto 10HCLK + 15MCLK cycles. (min 40us) */
- if (wait_for_bit(__func__, prv->base + SDCC_MCI_POWER,
- SDCC_MCI_POWER_SW_RST, false, 2, false)) {
+ if (wait_for_bit_le32(prv->base + SDCC_MCI_POWER,
+ SDCC_MCI_POWER_SW_RST, false, 2, false)) {
printf("msm_sdhci: stuck in reset\n");
return -ETIMEDOUT;
}
diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c
index 72d1c64..0b174fc 100644
--- a/drivers/mmc/sdhci-cadence.c
+++ b/drivers/mmc/sdhci-cadence.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <dm.h>
+#include <linux/bitfield.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/sizes.h>
@@ -19,15 +20,14 @@
#define SDHCI_CDNS_HRS04_ACK BIT(26)
#define SDHCI_CDNS_HRS04_RD BIT(25)
#define SDHCI_CDNS_HRS04_WR BIT(24)
-#define SDHCI_CDNS_HRS04_RDATA_SHIFT 16
-#define SDHCI_CDNS_HRS04_WDATA_SHIFT 8
-#define SDHCI_CDNS_HRS04_ADDR_SHIFT 0
+#define SDHCI_CDNS_HRS04_RDATA GENMASK(23, 16)
+#define SDHCI_CDNS_HRS04_WDATA GENMASK(15, 8)
+#define SDHCI_CDNS_HRS04_ADDR GENMASK(5, 0)
#define SDHCI_CDNS_HRS06 0x18 /* eMMC control */
#define SDHCI_CDNS_HRS06_TUNE_UP BIT(15)
-#define SDHCI_CDNS_HRS06_TUNE_SHIFT 8
-#define SDHCI_CDNS_HRS06_TUNE_MASK 0x3f
-#define SDHCI_CDNS_HRS06_MODE_MASK 0x7
+#define SDHCI_CDNS_HRS06_TUNE GENMASK(13, 8)
+#define SDHCI_CDNS_HRS06_MODE GENMASK(2, 0)
#define SDHCI_CDNS_HRS06_MODE_SD 0x0
#define SDHCI_CDNS_HRS06_MODE_MMC_SDR 0x2
#define SDHCI_CDNS_HRS06_MODE_MMC_DDR 0x3
@@ -52,6 +52,13 @@
#define SDHCI_CDNS_PHY_DLY_HSMMC 0x0c
#define SDHCI_CDNS_PHY_DLY_STROBE 0x0d
+/*
+ * The tuned val register is 6 bit-wide, but not the whole of the range is
+ * available. The range 0-42 seems to be available (then 43 wraps around to 0)
+ * but I am not quite sure if it is official. Use only 0 to 39 for safety.
+ */
+#define SDHCI_CDNS_MAX_TUNING_LOOP 40
+
struct sdhci_cdns_plat {
struct mmc_config cfg;
struct mmc mmc;
@@ -84,8 +91,8 @@
u32 tmp;
int ret;
- tmp = (data << SDHCI_CDNS_HRS04_WDATA_SHIFT) |
- (addr << SDHCI_CDNS_HRS04_ADDR_SHIFT);
+ tmp = FIELD_PREP(SDHCI_CDNS_HRS04_WDATA, data) |
+ FIELD_PREP(SDHCI_CDNS_HRS04_ADDR, addr);
writel(tmp, reg);
tmp |= SDHCI_CDNS_HRS04_WR;
@@ -135,25 +142,23 @@
* The mode should be decided by MMC_TIMING_* like Linux, but
* U-Boot does not support timing. Use the clock frequency instead.
*/
- if (clock <= 26000000)
+ if (clock <= 26000000) {
mode = SDHCI_CDNS_HRS06_MODE_SD; /* use this for Legacy */
- else if (clock <= 52000000) {
+ } else if (clock <= 52000000) {
if (mmc->ddr_mode)
mode = SDHCI_CDNS_HRS06_MODE_MMC_DDR;
else
mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR;
} else {
- /*
- * REVISIT:
- * The IP supports HS200/HS400, revisit once U-Boot support it
- */
- printf("unsupported frequency %d\n", clock);
- return;
+ if (mmc->ddr_mode)
+ mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400;
+ else
+ mode = SDHCI_CDNS_HRS06_MODE_MMC_HS200;
}
tmp = readl(plat->hrs_addr + SDHCI_CDNS_HRS06);
- tmp &= ~SDHCI_CDNS_HRS06_MODE_MASK;
- tmp |= mode;
+ tmp &= ~SDHCI_CDNS_HRS06_MODE;
+ tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_MODE, mode);
writel(tmp, plat->hrs_addr + SDHCI_CDNS_HRS06);
}
@@ -161,6 +166,69 @@
.set_control_reg = sdhci_cdns_set_control_reg,
};
+static int sdhci_cdns_set_tune_val(struct sdhci_cdns_plat *plat,
+ unsigned int val)
+{
+ void __iomem *reg = plat->hrs_addr + SDHCI_CDNS_HRS06;
+ u32 tmp;
+
+ if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE, val)))
+ return -EINVAL;
+
+ tmp = readl(reg);
+ tmp &= ~SDHCI_CDNS_HRS06_TUNE;
+ tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_TUNE, val);
+ tmp |= SDHCI_CDNS_HRS06_TUNE_UP;
+ writel(tmp, reg);
+
+ return readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS06_TUNE_UP),
+ 1);
+}
+
+static int __maybe_unused sdhci_cdns_execute_tuning(struct udevice *dev,
+ unsigned int opcode)
+{
+ struct sdhci_cdns_plat *plat = dev_get_platdata(dev);
+ struct mmc *mmc = &plat->mmc;
+ int cur_streak = 0;
+ int max_streak = 0;
+ int end_of_streak = 0;
+ int i;
+
+ /*
+ * This handler only implements the eMMC tuning that is specific to
+ * this controller. The tuning for SD timing should be handled by the
+ * SDHCI core.
+ */
+ if (!IS_MMC(mmc))
+ return -ENOTSUPP;
+
+ if (WARN_ON(opcode != MMC_CMD_SEND_TUNING_BLOCK_HS200))
+ return -EINVAL;
+
+ for (i = 0; i < SDHCI_CDNS_MAX_TUNING_LOOP; i++) {
+ if (sdhci_cdns_set_tune_val(plat, i) ||
+ mmc_send_tuning(mmc, opcode, NULL)) { /* bad */
+ cur_streak = 0;
+ } else { /* good */
+ cur_streak++;
+ if (cur_streak > max_streak) {
+ max_streak = cur_streak;
+ end_of_streak = i;
+ }
+ }
+ }
+
+ if (!max_streak) {
+ dev_err(dev, "no tuning point found\n");
+ return -EIO;
+ }
+
+ return sdhci_cdns_set_tune_val(plat, end_of_streak - max_streak / 2);
+}
+
+static struct dm_mmc_ops sdhci_cdns_mmc_ops;
+
static int sdhci_cdns_bind(struct udevice *dev)
{
struct sdhci_cdns_plat *plat = dev_get_platdata(dev);
@@ -189,6 +257,14 @@
host->ioaddr = plat->hrs_addr + SDHCI_CDNS_SRS_BASE;
host->ops = &sdhci_cdns_ops;
host->quirks |= SDHCI_QUIRK_WAIT_SEND_CMD;
+ sdhci_cdns_mmc_ops = sdhci_ops;
+#ifdef MMC_SUPPORTS_TUNING
+ sdhci_cdns_mmc_ops.execute_tuning = sdhci_cdns_execute_tuning;
+#endif
+
+ ret = mmc_of_parse(dev, &plat->cfg);
+ if (ret)
+ return ret;
ret = sdhci_cdns_phy_init(plat, gd->fdt_blob, dev_of_offset(dev));
if (ret)
@@ -219,5 +295,5 @@
.probe = sdhci_cdns_probe,
.priv_auto_alloc_size = sizeof(struct sdhci_host),
.platdata_auto_alloc_size = sizeof(struct sdhci_cdns_plat),
- .ops = &sdhci_ops,
+ .ops = &sdhci_cdns_mmc_ops,
};
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index e2ddf5d..d31793a 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -86,8 +86,8 @@
do {
stat = sdhci_readl(host, SDHCI_INT_STATUS);
if (stat & SDHCI_INT_ERROR) {
- printf("%s: Error detected in status(0x%X)!\n",
- __func__, stat);
+ pr_debug("%s: Error detected in status(0x%X)!\n",
+ __func__, stat);
return -EIO;
}
if (!transfer_done && (stat & rdy)) {
@@ -594,7 +594,7 @@
if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
cfg->voltages |= host->voltages;
- cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
+ cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
/* Since Host Controller Version3.0 */
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
diff --git a/drivers/mtd/pic32_flash.c b/drivers/mtd/pic32_flash.c
index e1a8d3b..8bbf2fa 100644
--- a/drivers/mtd/pic32_flash.c
+++ b/drivers/mtd/pic32_flash.c
@@ -66,8 +66,8 @@
static int flash_wait_till_busy(const char *func, ulong timeout)
{
- int ret = wait_for_bit(__func__, &nvm_regs_p->ctrl.raw,
- NVM_WR, false, timeout, false);
+ int ret = wait_for_bit_le32(&nvm_regs_p->ctrl.raw,
+ NVM_WR, false, timeout, false);
return ret ? ERR_TIMOUT : ERR_OK;
}
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 7b29637..09143d7 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -55,10 +55,16 @@
}
#ifndef CONFIG_DM_SPI_FLASH
-static struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus)
+struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
+ unsigned int max_hz, unsigned int spi_mode)
{
+ struct spi_slave *bus;
struct spi_flash *flash;
+ bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
+ if (!bus)
+ return NULL;
+
/* Allocate space if needed (not used by sf-uclass */
flash = calloc(1, sizeof(*flash));
if (!flash) {
@@ -76,30 +82,6 @@
return flash;
}
-struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
- unsigned int max_hz, unsigned int spi_mode)
-{
- struct spi_slave *bus;
-
- bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
- if (!bus)
- return NULL;
- return spi_flash_probe_tail(bus);
-}
-
-#ifdef CONFIG_OF_SPI_FLASH
-struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
- int spi_node)
-{
- struct spi_slave *bus;
-
- bus = spi_setup_slave_fdt(blob, slave_node, spi_node);
- if (!bus)
- return NULL;
- return spi_flash_probe_tail(bus);
-}
-#endif
-
void spi_flash_free(struct spi_flash *flash)
{
#ifdef CONFIG_SPI_FLASH_MTD
@@ -120,7 +102,7 @@
}
static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
- const void *buf)
+ const void *buf)
{
struct spi_flash *flash = dev_get_uclass_priv(dev);
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 51e28bf..294d9f9 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -405,7 +405,7 @@
if (spi->max_write_size)
chunk_len = min(chunk_len,
- (size_t)spi->max_write_size);
+ spi->max_write_size - sizeof(cmd));
spi_flash_addr(write_addr, cmd);
@@ -516,6 +516,9 @@
else
read_len = remain_len;
+ if (spi->max_read_size)
+ read_len = min(read_len, spi->max_read_size);
+
spi_flash_addr(read_addr, cmd);
ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len);
diff --git a/drivers/net/ag7xxx.c b/drivers/net/ag7xxx.c
index 00e6806..f281870 100644
--- a/drivers/net/ag7xxx.c
+++ b/drivers/net/ag7xxx.c
@@ -164,8 +164,8 @@
writel(AG7XXX_ETH_MII_MGMT_CMD_READ,
regs + AG7XXX_ETH_MII_MGMT_CMD);
- ret = wait_for_bit("ag7xxx", regs + AG7XXX_ETH_MII_MGMT_IND,
- AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0);
+ ret = wait_for_bit_le32(regs + AG7XXX_ETH_MII_MGMT_IND,
+ AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0);
if (ret)
return ret;
@@ -185,8 +185,8 @@
regs + AG7XXX_ETH_MII_MGMT_ADDRESS);
writel(val, regs + AG7XXX_ETH_MII_MGMT_CTRL);
- ret = wait_for_bit("ag7xxx", regs + AG7XXX_ETH_MII_MGMT_IND,
- AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0);
+ ret = wait_for_bit_le32(regs + AG7XXX_ETH_MII_MGMT_IND,
+ AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0);
return ret;
}
@@ -510,13 +510,13 @@
/* Stop the TX DMA. */
writel(0, priv->regs + AG7XXX_ETH_DMA_TX_CTRL);
- wait_for_bit("ag7xxx", priv->regs + AG7XXX_ETH_DMA_TX_CTRL, ~0, 0,
- 1000, 0);
+ wait_for_bit_le32(priv->regs + AG7XXX_ETH_DMA_TX_CTRL, ~0, 0,
+ 1000, 0);
/* Stop the RX DMA. */
writel(0, priv->regs + AG7XXX_ETH_DMA_RX_CTRL);
- wait_for_bit("ag7xxx", priv->regs + AG7XXX_ETH_DMA_RX_CTRL, ~0, 0,
- 1000, 0);
+ wait_for_bit_le32(priv->regs + AG7XXX_ETH_DMA_RX_CTRL, ~0, 0,
+ 1000, 0);
}
/*
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 00076cf..232e803 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -361,8 +361,9 @@
static int eqos_mdio_wait_idle(struct eqos_priv *eqos)
{
- return wait_for_bit(__func__, &eqos->mac_regs->mdio_address,
- EQOS_MAC_MDIO_ADDRESS_GB, false, 1000000, true);
+ return wait_for_bit_le32(&eqos->mac_regs->mdio_address,
+ EQOS_MAC_MDIO_ADDRESS_GB, false,
+ 1000000, true);
}
static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
@@ -588,15 +589,15 @@
setbits_le32(&eqos->tegra186_regs->auto_cal_config,
EQOS_AUTO_CAL_CONFIG_START | EQOS_AUTO_CAL_CONFIG_ENABLE);
- ret = wait_for_bit(__func__, &eqos->tegra186_regs->auto_cal_status,
- EQOS_AUTO_CAL_STATUS_ACTIVE, true, 10, false);
+ ret = wait_for_bit_le32(&eqos->tegra186_regs->auto_cal_status,
+ EQOS_AUTO_CAL_STATUS_ACTIVE, true, 10, false);
if (ret) {
pr_err("calibrate didn't start");
goto failed;
}
- ret = wait_for_bit(__func__, &eqos->tegra186_regs->auto_cal_status,
- EQOS_AUTO_CAL_STATUS_ACTIVE, false, 10, false);
+ ret = wait_for_bit_le32(&eqos->tegra186_regs->auto_cal_status,
+ EQOS_AUTO_CAL_STATUS_ACTIVE, false, 10, false);
if (ret) {
pr_err("calibrate didn't finish");
goto failed;
@@ -862,8 +863,8 @@
eqos->reg_access_ok = true;
- ret = wait_for_bit(__func__, &eqos->dma_regs->mode,
- EQOS_DMA_MODE_SWR, false, 10, false);
+ ret = wait_for_bit_le32(&eqos->dma_regs->mode,
+ EQOS_DMA_MODE_SWR, false, 10, false);
if (ret) {
pr_err("EQOS_DMA_MODE_SWR stuck");
goto err_stop_resets;
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index a6df950..51a6c97 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -548,8 +548,8 @@
ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(addr, reg));
ethoc_write(priv, MIICOMMAND, MIICOMMAND_READ);
- rc = wait_for_bit(__func__, ethoc_reg(priv, MIISTATUS),
- MIISTATUS_BUSY, false, CONFIG_SYS_HZ, false);
+ rc = wait_for_bit_le32(ethoc_reg(priv, MIISTATUS),
+ MIISTATUS_BUSY, false, CONFIG_SYS_HZ, false);
if (rc == 0) {
u32 data = ethoc_read(priv, MIIRX_DATA);
@@ -571,8 +571,8 @@
ethoc_write(priv, MIITX_DATA, val);
ethoc_write(priv, MIICOMMAND, MIICOMMAND_WRITE);
- rc = wait_for_bit(__func__, ethoc_reg(priv, MIISTATUS),
- MIISTATUS_BUSY, false, CONFIG_SYS_HZ, false);
+ rc = wait_for_bit_le32(ethoc_reg(priv, MIISTATUS),
+ MIISTATUS_BUSY, false, CONFIG_SYS_HZ, false);
if (rc == 0) {
/* reset MII command register */
diff --git a/drivers/net/pic32_eth.c b/drivers/net/pic32_eth.c
index 0b89911..7129372 100644
--- a/drivers/net/pic32_eth.c
+++ b/drivers/net/pic32_eth.c
@@ -64,8 +64,8 @@
writel(ETHCON_ON | ETHCON_TXRTS | ETHCON_RXEN, &ectl_p->con1.clr);
/* wait till busy */
- wait_for_bit(__func__, &ectl_p->stat.raw, ETHSTAT_BUSY, false,
- CONFIG_SYS_HZ, false);
+ wait_for_bit_le32(&ectl_p->stat.raw, ETHSTAT_BUSY, false,
+ CONFIG_SYS_HZ, false);
/* turn controller ON to access PHY over MII */
writel(ETHCON_ON, &ectl_p->con1.set);
@@ -239,8 +239,8 @@
writel(ETHCON_ON | ETHCON_TXRTS | ETHCON_RXEN, &ectl_p->con1.clr);
/* wait till busy */
- wait_for_bit(__func__, &ectl_p->stat.raw, ETHSTAT_BUSY, false,
- CONFIG_SYS_HZ, false);
+ wait_for_bit_le32(&ectl_p->stat.raw, ETHSTAT_BUSY, false,
+ CONFIG_SYS_HZ, false);
/* decrement received buffcnt to zero. */
while (readl(&ectl_p->stat.raw) & ETHSTAT_BUFCNT)
writel(ETHCON_BUFCDEC, &ectl_p->con1.set);
@@ -375,8 +375,8 @@
mdelay(10);
/* wait until everything is down */
- wait_for_bit(__func__, &ectl_p->stat.raw, ETHSTAT_BUSY, false,
- 2 * CONFIG_SYS_HZ, false);
+ wait_for_bit_le32(&ectl_p->stat.raw, ETHSTAT_BUSY, false,
+ 2 * CONFIG_SYS_HZ, false);
/* clear any existing interrupt event */
writel(0xffffffff, &ectl_p->irq.clr);
diff --git a/drivers/net/pic32_mdio.c b/drivers/net/pic32_mdio.c
index 578fc96..6ae5c40 100644
--- a/drivers/net/pic32_mdio.c
+++ b/drivers/net/pic32_mdio.c
@@ -22,8 +22,8 @@
struct pic32_mii_regs *mii_regs = bus->priv;
/* Wait for the previous operation to finish */
- wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
- false, CONFIG_SYS_HZ, true);
+ wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
+ false, CONFIG_SYS_HZ, true);
/* Put phyaddr and regaddr into MIIMADD */
v = (addr << MIIMADD_PHYADDR_SHIFT) | (reg & MIIMADD_REGADDR);
@@ -36,8 +36,8 @@
udelay(12);
/* Wait for write to complete */
- wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
- false, CONFIG_SYS_HZ, true);
+ wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
+ false, CONFIG_SYS_HZ, true);
return 0;
}
@@ -48,8 +48,8 @@
struct pic32_mii_regs *mii_regs = bus->priv;
/* Wait for the previous operation to finish */
- wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
- false, CONFIG_SYS_HZ, true);
+ wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
+ false, CONFIG_SYS_HZ, true);
/* Put phyaddr and regaddr into MIIMADD */
v = (addr << MIIMADD_PHYADDR_SHIFT) | (reg & MIIMADD_REGADDR);
@@ -62,9 +62,9 @@
udelay(12);
/* Wait for read to complete */
- wait_for_bit(__func__, &mii_regs->mind.raw,
- MIIMIND_NOTVALID | MIIMIND_BUSY,
- false, CONFIG_SYS_HZ, false);
+ wait_for_bit_le32(&mii_regs->mind.raw,
+ MIIMIND_NOTVALID | MIIMIND_BUSY,
+ false, CONFIG_SYS_HZ, false);
/* Clear the command register */
writel(0, &mii_regs->mcmd.raw);
@@ -82,22 +82,22 @@
writel(MIIMCFG_RSTMGMT, &mii_regs->mcfg.raw);
/* Wait for the operation to finish */
- wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
+ wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
false, CONFIG_SYS_HZ, true);
/* Clear reset bit */
writel(0, &mii_regs->mcfg);
/* Wait for the operation to finish */
- wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
- false, CONFIG_SYS_HZ, true);
+ wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
+ false, CONFIG_SYS_HZ, true);
/* Set the MII Management Clock (MDC) - no faster than 2.5 MHz */
writel(MIIMCFG_CLKSEL_DIV40, &mii_regs->mcfg.raw);
/* Wait for the operation to finish */
- wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
- false, CONFIG_SYS_HZ, true);
+ wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
+ false, CONFIG_SYS_HZ, true);
return 0;
}
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index dc743e1..26bd915 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -222,8 +222,8 @@
writel(CCC_OPC_CONFIG, eth->iobase + RAVB_REG_CCC);
/* Check the operating mode is changed to the config mode. */
- return wait_for_bit(dev->name, (void *)eth->iobase + RAVB_REG_CSR,
- CSR_OPS_CONFIG, true, 100, true);
+ return wait_for_bit_le32(eth->iobase + RAVB_REG_CSR,
+ CSR_OPS_CONFIG, true, 100, true);
}
static void ravb_base_desc_init(struct ravb_priv *eth)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
index 9a2a578..70a2e95 100644
--- a/drivers/net/xilinx_axi_emac.c
+++ b/drivers/net/xilinx_axi_emac.c
@@ -366,8 +366,8 @@
* processor mode and hence bypass in this mode
*/
if (!priv->eth_hasnobuf) {
- err = wait_for_bit(__func__, (const u32 *)®s->is,
- XAE_INT_MGTRDY_MASK, true, 200, false);
+ err = wait_for_bit_le32(®s->is, XAE_INT_MGTRDY_MASK,
+ true, 200, false);
if (err) {
printf("%s: Timeout\n", __func__);
return 1;
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 1dfd631..2cc49bc 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -192,8 +192,8 @@
struct zynq_gem_regs *regs = priv->iobase;
int err;
- err = wait_for_bit(__func__, ®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
- true, 20000, false);
+ err = wait_for_bit_le32(®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
+ true, 20000, false);
if (err)
return err;
@@ -205,8 +205,8 @@
/* Write mgtcr and wait for completion */
writel(mgtcr, ®s->phymntnc);
- err = wait_for_bit(__func__, ®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
- true, 20000, false);
+ err = wait_for_bit_le32(®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
+ true, 20000, false);
if (err)
return err;
@@ -514,8 +514,8 @@
if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED)
printf("TX buffers exhausted in mid frame\n");
- return wait_for_bit(__func__, ®s->txsr, ZYNQ_GEM_TSR_DONE,
- true, 20000, true);
+ return wait_for_bit_le32(®s->txsr, ZYNQ_GEM_TSR_DONE,
+ true, 20000, true);
}
/* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */
diff --git a/drivers/power/pmic/s2mps11.c b/drivers/power/pmic/s2mps11.c
index 522105e..3f9525b 100644
--- a/drivers/power/pmic/s2mps11.c
+++ b/drivers/power/pmic/s2mps11.c
@@ -15,6 +15,12 @@
DECLARE_GLOBAL_DATA_PTR;
+static const struct pmic_child_info pmic_children_info[] = {
+ { .prefix = S2MPS11_OF_LDO_PREFIX, .driver = S2MPS11_LDO_DRIVER },
+ { .prefix = S2MPS11_OF_BUCK_PREFIX, .driver = S2MPS11_BUCK_DRIVER },
+ { },
+};
+
static int s2mps11_reg_count(struct udevice *dev)
{
return S2MPS11_REG_COUNT;
@@ -43,6 +49,27 @@
return ret;
}
+static int s2mps11_probe(struct udevice *dev)
+{
+ ofnode regulators_node;
+ int children;
+
+ regulators_node = dev_read_subnode(dev, "voltage-regulators");
+ if (!ofnode_valid(regulators_node)) {
+ debug("%s: %s regulators subnode not found!", __func__,
+ dev->name);
+ return -ENXIO;
+ }
+
+ debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
+
+ children = pmic_bind_children(dev, regulators_node, pmic_children_info);
+ if (!children)
+ debug("%s: %s - no child found\n", __func__, dev->name);
+
+ return 0;
+}
+
static struct dm_pmic_ops s2mps11_ops = {
.reg_count = s2mps11_reg_count,
.read = s2mps11_read,
@@ -59,4 +86,5 @@
.id = UCLASS_PMIC,
.of_match = s2mps11_ids,
.ops = &s2mps11_ops,
+ .probe = s2mps11_probe,
};
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index 26fb936..5b4ac10 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -101,6 +101,14 @@
by the PMIC device. This driver is controlled by a device tree node
which includes voltage limits.
+config DM_REGULATOR_S2MPS11
+ bool "Enable driver for S2MPS11 regulator"
+ depends on DM_REGULATOR && PMIC_S2MPS11
+ ---help---
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR S2MPS11.
+ The driver implements get/set api for: value and enable.
+
config REGULATOR_S5M8767
bool "Enable support for S5M8767 regulator"
depends on DM_REGULATOR && PMIC_S5M8767
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index 7a2e76d..728e814 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -14,6 +14,7 @@
obj-$(CONFIG_$(SPL_)DM_REGULATOR_FIXED) += fixed.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_GPIO) += gpio-regulator.o
obj-$(CONFIG_REGULATOR_RK8XX) += rk8xx.o
+obj-$(CONFIG_DM_REGULATOR_S2MPS11) += s2mps11_regulator.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o
diff --git a/drivers/power/regulator/s2mps11_regulator.c b/drivers/power/regulator/s2mps11_regulator.c
new file mode 100644
index 0000000..3af20e6
--- /dev/null
+++ b/drivers/power/regulator/s2mps11_regulator.c
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2018 Samsung Electronics
+ * Jaehoon Chung <jh80.chung@samsung.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/s2mps11.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MODE(_id, _val, _name) { \
+ .id = _id, \
+ .register_value = _val, \
+ .name = _name, \
+}
+
+/* BUCK : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 */
+static struct dm_regulator_mode s2mps11_buck_modes[] = {
+ MODE(OP_OFF, S2MPS11_BUCK_MODE_OFF, "OFF"),
+ MODE(OP_STANDBY, S2MPS11_BUCK_MODE_STANDBY, "ON/OFF"),
+ MODE(OP_ON, S2MPS11_BUCK_MODE_STANDBY, "ON"),
+};
+
+static struct dm_regulator_mode s2mps11_ldo_modes[] = {
+ MODE(OP_OFF, S2MPS11_LDO_MODE_OFF, "OFF"),
+ MODE(OP_STANDBY, S2MPS11_LDO_MODE_STANDBY, "ON/OFF"),
+ MODE(OP_STANDBY_LPM, S2MPS11_LDO_MODE_STANDBY_LPM, "ON/LPM"),
+ MODE(OP_ON, S2MPS11_LDO_MODE_ON, "ON"),
+};
+
+static const char s2mps11_buck_ctrl[] = {
+ 0xff, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x37, 0x39, 0x3b
+};
+
+static const char s2mps11_buck_out[] = {
+ 0xff, 0x26, 0x28, 0x2a, 0x2c, 0x2f, 0x34, 0x36, 0x38, 0x3a, 0x3c
+};
+
+static int s2mps11_buck_hex2volt(int buck, int hex)
+{
+ unsigned int uV = 0;
+
+ if (hex < 0)
+ goto bad;
+
+ switch (buck) {
+ case 7:
+ case 8:
+ case 10:
+ if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
+ goto bad;
+
+ uV = hex * S2MPS11_BUCK_HSTEP + S2MPS11_BUCK_UV_HMIN;
+ break;
+ case 9:
+ if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX)
+ goto bad;
+ uV = hex * S2MPS11_BUCK9_STEP * 2 + S2MPS11_BUCK9_UV_MIN;
+ break;
+ default:
+ if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX)
+ goto bad;
+ else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX)
+ goto bad;
+
+ uV = hex * S2MPS11_BUCK_LSTEP + S2MPS11_BUCK_UV_MIN;
+ break;
+ }
+
+ return uV;
+bad:
+ pr_err("Value: %#x is wrong for BUCK%d", hex, buck);
+ return -EINVAL;
+}
+
+static int s2mps11_buck_volt2hex(int buck, int uV)
+{
+ int hex;
+
+ switch (buck) {
+ case 7:
+ case 8:
+ case 10:
+ hex = (uV - S2MPS11_BUCK_UV_HMIN) / S2MPS11_BUCK_HSTEP;
+ if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
+ goto bad;
+
+ break;
+ case 9:
+ hex = (uV - S2MPS11_BUCK9_UV_MIN) / S2MPS11_BUCK9_STEP;
+ if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX)
+ goto bad;
+ break;
+ default:
+ hex = (uV - S2MPS11_BUCK_UV_MIN) / S2MPS11_BUCK_LSTEP;
+ if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX)
+ goto bad;
+ else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX)
+ goto bad;
+ break;
+ };
+
+ if (hex >= 0)
+ return hex;
+
+bad:
+ pr_err("Value: %d uV is wrong for BUCK%d", uV, buck);
+ return -EINVAL;
+}
+
+static int s2mps11_buck_val(struct udevice *dev, int op, int *uV)
+{
+ int hex, buck, ret;
+ u32 mask, addr;
+ u8 val;
+
+ buck = dev->driver_data;
+ if (buck < 1 || buck > S2MPS11_BUCK_NUM) {
+ pr_err("Wrong buck number: %d\n", buck);
+ return -EINVAL;
+ }
+
+ if (op == PMIC_OP_GET)
+ *uV = 0;
+
+ addr = s2mps11_buck_out[buck];
+
+ switch (buck) {
+ case 9:
+ mask = S2MPS11_BUCK9_VOLT_MASK;
+ break;
+ default:
+ mask = S2MPS11_BUCK_VOLT_MASK;
+ break;
+ }
+
+ ret = pmic_read(dev->parent, addr, &val, 1);
+ if (ret)
+ return ret;
+
+ if (op == PMIC_OP_GET) {
+ val &= mask;
+ ret = s2mps11_buck_hex2volt(buck, val);
+ if (ret < 0)
+ return ret;
+ *uV = ret;
+ return 0;
+ }
+
+ hex = s2mps11_buck_volt2hex(buck, *uV);
+ if (hex < 0)
+ return hex;
+
+ val &= ~mask;
+ val |= hex;
+ ret = pmic_write(dev->parent, addr, &val, 1);
+
+ return ret;
+}
+
+static int s2mps11_buck_mode(struct udevice *dev, int op, int *opmode)
+{
+ unsigned int addr, mode;
+ unsigned char val;
+ int buck, ret;
+
+ buck = dev->driver_data;
+ if (buck < 1 || buck > S2MPS11_BUCK_NUM) {
+ pr_err("Wrong buck number: %d\n", buck);
+ return -EINVAL;
+ }
+
+ addr = s2mps11_buck_ctrl[buck];
+
+ ret = pmic_read(dev->parent, addr, &val, 1);
+ if (ret)
+ return ret;
+
+ if (op == PMIC_OP_GET) {
+ val &= (S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT);
+ switch (val) {
+ case S2MPS11_BUCK_MODE_OFF:
+ *opmode = OP_OFF;
+ break;
+ case S2MPS11_BUCK_MODE_STANDBY:
+ *opmode = OP_STANDBY;
+ break;
+ case S2MPS11_BUCK_MODE_ON:
+ *opmode = OP_ON;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ switch (*opmode) {
+ case OP_OFF:
+ mode = S2MPS11_BUCK_MODE_OFF;
+ break;
+ case OP_STANDBY:
+ mode = S2MPS11_BUCK_MODE_STANDBY;
+ break;
+ case OP_ON:
+ mode = S2MPS11_BUCK_MODE_ON;
+ break;
+ default:
+ pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
+ return -EINVAL;
+ }
+
+ val &= ~(S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT);
+ val |= mode;
+ ret = pmic_write(dev->parent, addr, &val, 1);
+
+ return ret;
+}
+
+static int s2mps11_buck_enable(struct udevice *dev, int op, bool *enable)
+{
+ int ret, on_off;
+
+ if (op == PMIC_OP_GET) {
+ ret = s2mps11_buck_mode(dev, op, &on_off);
+ if (ret)
+ return ret;
+ switch (on_off) {
+ case OP_OFF:
+ *enable = false;
+ break;
+ case OP_ON:
+ *enable = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else if (op == PMIC_OP_SET) {
+ if (*enable)
+ on_off = OP_ON;
+ else
+ on_off = OP_OFF;
+
+ ret = s2mps11_buck_mode(dev, op, &on_off);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int buck_get_value(struct udevice *dev)
+{
+ int uV;
+ int ret;
+
+ ret = s2mps11_buck_val(dev, PMIC_OP_GET, &uV);
+ if (ret)
+ return ret;
+ return uV;
+}
+
+static int buck_set_value(struct udevice *dev, int uV)
+{
+ return s2mps11_buck_val(dev, PMIC_OP_SET, &uV);
+}
+
+static int buck_get_enable(struct udevice *dev)
+{
+ bool enable = false;
+ int ret;
+
+ ret = s2mps11_buck_enable(dev, PMIC_OP_GET, &enable);
+ if (ret)
+ return ret;
+ return enable;
+}
+
+static int buck_set_enable(struct udevice *dev, bool enable)
+{
+ return s2mps11_buck_enable(dev, PMIC_OP_SET, &enable);
+}
+
+static int buck_get_mode(struct udevice *dev)
+{
+ int mode;
+ int ret;
+
+ ret = s2mps11_buck_mode(dev, PMIC_OP_GET, &mode);
+ if (ret)
+ return ret;
+
+ return mode;
+}
+
+static int buck_set_mode(struct udevice *dev, int mode)
+{
+ return s2mps11_buck_mode(dev, PMIC_OP_SET, &mode);
+}
+
+static int s2mps11_buck_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ uc_pdata->type = REGULATOR_TYPE_BUCK;
+ uc_pdata->mode = s2mps11_buck_modes;
+ uc_pdata->mode_count = ARRAY_SIZE(s2mps11_buck_modes);
+
+ return 0;
+}
+
+static const struct dm_regulator_ops s2mps11_buck_ops = {
+ .get_value = buck_get_value,
+ .set_value = buck_set_value,
+ .get_enable = buck_get_enable,
+ .set_enable = buck_set_enable,
+ .get_mode = buck_get_mode,
+ .set_mode = buck_set_mode,
+};
+
+U_BOOT_DRIVER(s2mps11_buck) = {
+ .name = S2MPS11_BUCK_DRIVER,
+ .id = UCLASS_REGULATOR,
+ .ops = &s2mps11_buck_ops,
+ .probe = s2mps11_buck_probe,
+};
+
+static int s2mps11_ldo_hex2volt(int ldo, int hex)
+{
+ unsigned int uV = 0;
+
+ if (hex > S2MPS11_LDO_VOLT_MAX_HEX) {
+ pr_err("Value: %#x is wrong for LDO%d", hex, ldo);
+ return -EINVAL;
+ }
+
+ switch (ldo) {
+ case 1:
+ case 6:
+ case 11:
+ case 22:
+ case 23:
+ uV = hex * S2MPS11_LDO_STEP + S2MPS11_LDO_UV_MIN;
+ break;
+ default:
+ uV = hex * S2MPS11_LDO_STEP * 2 + S2MPS11_LDO_UV_MIN;
+ break;
+ }
+
+ return uV;
+}
+
+static int s2mps11_ldo_volt2hex(int ldo, int uV)
+{
+ int hex = 0;
+
+ switch (ldo) {
+ case 1:
+ case 6:
+ case 11:
+ case 22:
+ case 23:
+ hex = (uV - S2MPS11_LDO_UV_MIN) / S2MPS11_LDO_STEP;
+ break;
+ default:
+ hex = (uV - S2MPS11_LDO_UV_MIN) / (S2MPS11_LDO_STEP * 2);
+ break;
+ }
+
+ if (hex >= 0 && hex <= S2MPS11_LDO_VOLT_MAX_HEX)
+ return hex;
+
+ pr_err("Value: %d uV is wrong for LDO%d", uV, ldo);
+ return -EINVAL;
+
+ return 0;
+}
+
+static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV)
+{
+ unsigned int addr;
+ unsigned char val;
+ int hex, ldo, ret;
+
+ ldo = dev->driver_data;
+ if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
+ pr_err("Wrong ldo number: %d\n", ldo);
+ return -EINVAL;
+ }
+
+ addr = S2MPS11_REG_L1CTRL + ldo - 1;
+
+ ret = pmic_read(dev->parent, addr, &val, 1);
+ if (ret)
+ return ret;
+
+ if (op == PMIC_OP_GET) {
+ *uV = 0;
+ val &= S2MPS11_LDO_VOLT_MASK;
+ ret = s2mps11_ldo_hex2volt(ldo, val);
+ if (ret < 0)
+ return ret;
+
+ *uV = ret;
+ return 0;
+ }
+
+ hex = s2mps11_ldo_volt2hex(ldo, *uV);
+ if (hex < 0)
+ return hex;
+
+ val &= ~S2MPS11_LDO_VOLT_MASK;
+ val |= hex;
+ ret = pmic_write(dev->parent, addr, &val, 1);
+
+ return ret;
+}
+
+static int s2mps11_ldo_mode(struct udevice *dev, int op, int *opmode)
+{
+ unsigned int addr, mode;
+ unsigned char val;
+ int ldo, ret;
+
+ ldo = dev->driver_data;
+ if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
+ pr_err("Wrong ldo number: %d\n", ldo);
+ return -EINVAL;
+ }
+ addr = S2MPS11_REG_L1CTRL + ldo - 1;
+
+ ret = pmic_read(dev->parent, addr, &val, 1);
+ if (ret)
+ return ret;
+
+ if (op == PMIC_OP_GET) {
+ val &= (S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
+ switch (val) {
+ case S2MPS11_LDO_MODE_OFF:
+ *opmode = OP_OFF;
+ break;
+ case S2MPS11_LDO_MODE_STANDBY:
+ *opmode = OP_STANDBY;
+ break;
+ case S2MPS11_LDO_MODE_STANDBY_LPM:
+ *opmode = OP_STANDBY_LPM;
+ break;
+ case S2MPS11_LDO_MODE_ON:
+ *opmode = OP_ON;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ switch (*opmode) {
+ case OP_OFF:
+ mode = S2MPS11_LDO_MODE_OFF;
+ break;
+ case OP_STANDBY:
+ mode = S2MPS11_LDO_MODE_STANDBY;
+ break;
+ case OP_STANDBY_LPM:
+ mode = S2MPS11_LDO_MODE_STANDBY_LPM;
+ break;
+ case OP_ON:
+ mode = S2MPS11_LDO_MODE_ON;
+ break;
+ default:
+ pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo);
+ return -EINVAL;
+ }
+
+ val &= ~(S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
+ val |= mode;
+ ret = pmic_write(dev->parent, addr, &val, 1);
+
+ return ret;
+}
+
+static int s2mps11_ldo_enable(struct udevice *dev, int op, bool *enable)
+{
+ int ret, on_off;
+
+ if (op == PMIC_OP_GET) {
+ ret = s2mps11_ldo_mode(dev, op, &on_off);
+ if (ret)
+ return ret;
+ switch (on_off) {
+ case OP_OFF:
+ *enable = false;
+ break;
+ case OP_ON:
+ *enable = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else if (op == PMIC_OP_SET) {
+ if (*enable)
+ on_off = OP_ON;
+ else
+ on_off = OP_OFF;
+
+ ret = s2mps11_ldo_mode(dev, op, &on_off);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ldo_get_value(struct udevice *dev)
+{
+ int uV;
+ int ret;
+
+ ret = s2mps11_ldo_val(dev, PMIC_OP_GET, &uV);
+ if (ret)
+ return ret;
+
+ return uV;
+}
+
+static int ldo_set_value(struct udevice *dev, int uV)
+{
+ return s2mps11_ldo_val(dev, PMIC_OP_SET, &uV);
+}
+
+static int ldo_get_enable(struct udevice *dev)
+{
+ bool enable = false;
+ int ret;
+
+ ret = s2mps11_ldo_enable(dev, PMIC_OP_GET, &enable);
+ if (ret)
+ return ret;
+ return enable;
+}
+
+static int ldo_set_enable(struct udevice *dev, bool enable)
+{
+ return s2mps11_ldo_enable(dev, PMIC_OP_SET, &enable);
+}
+
+static int ldo_get_mode(struct udevice *dev)
+{
+ int mode, ret;
+
+ ret = s2mps11_ldo_mode(dev, PMIC_OP_GET, &mode);
+ if (ret)
+ return ret;
+ return mode;
+}
+
+static int ldo_set_mode(struct udevice *dev, int mode)
+{
+ return s2mps11_ldo_mode(dev, PMIC_OP_SET, &mode);
+}
+
+static int s2mps11_ldo_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ uc_pdata->type = REGULATOR_TYPE_LDO;
+ uc_pdata->mode = s2mps11_ldo_modes;
+ uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes);
+
+ return 0;
+}
+
+static const struct dm_regulator_ops s2mps11_ldo_ops = {
+ .get_value = ldo_get_value,
+ .set_value = ldo_set_value,
+ .get_enable = ldo_get_enable,
+ .set_enable = ldo_set_enable,
+ .get_mode = ldo_get_mode,
+ .set_mode = ldo_set_mode,
+};
+
+U_BOOT_DRIVER(s2mps11_ldo) = {
+ .name = S2MPS11_LDO_DRIVER,
+ .id = UCLASS_REGULATOR,
+ .ops = &s2mps11_ldo_ops,
+ .probe = s2mps11_ldo_probe,
+};
diff --git a/drivers/ram/bmips_ram.c b/drivers/ram/bmips_ram.c
index 3f9d9a8..7a5dfac 100644
--- a/drivers/ram/bmips_ram.c
+++ b/drivers/ram/bmips_ram.c
@@ -23,6 +23,8 @@
#define SDRAM_CFG_32B_MASK (1 << SDRAM_CFG_32B_SHIFT)
#define SDRAM_CFG_BANK_SHIFT 13
#define SDRAM_CFG_BANK_MASK (1 << SDRAM_CFG_BANK_SHIFT)
+#define SDRAM_6318_SPACE_SHIFT 4
+#define SDRAM_6318_SPACE_MASK (0xf << SDRAM_6318_SPACE_SHIFT)
#define MEMC_CFG_REG 0x4
#define MEMC_CFG_32B_SHIFT 1
@@ -45,6 +47,16 @@
const struct bmips_ram_hw *hw;
};
+static ulong bcm6318_get_ram_size(struct bmips_ram_priv *priv)
+{
+ u32 val;
+
+ val = readl_be(priv->regs + SDRAM_CFG_REG);
+ val = (val & SDRAM_6318_SPACE_MASK) >> SDRAM_6318_SPACE_SHIFT;
+
+ return (1 << (val + 20));
+}
+
static ulong bcm6328_get_ram_size(struct bmips_ram_priv *priv)
{
return readl_be(priv->regs + DDR_CSEND_REG) << 24;
@@ -102,6 +114,10 @@
.get_info = bmips_ram_get_info,
};
+static const struct bmips_ram_hw bmips_ram_bcm6318 = {
+ .get_ram_size = bcm6318_get_ram_size,
+};
+
static const struct bmips_ram_hw bmips_ram_bcm6328 = {
.get_ram_size = bcm6328_get_ram_size,
};
@@ -116,6 +132,9 @@
static const struct udevice_id bmips_ram_ids[] = {
{
+ .compatible = "brcm,bcm6318-mc",
+ .data = (ulong)&bmips_ram_bcm6318,
+ }, {
.compatible = "brcm,bcm6328-mc",
.data = (ulong)&bmips_ram_bcm6328,
}, {
diff --git a/drivers/reset/sti-reset.c b/drivers/reset/sti-reset.c
index 17786f9..0fc5a28 100644
--- a/drivers/reset/sti-reset.c
+++ b/drivers/reset/sti-reset.c
@@ -266,8 +266,8 @@
return 0;
reg = (void __iomem *)base + ch->ack_offset;
- if (wait_for_bit(__func__, reg, BIT(ch->ack_bit), ctrl_val,
- 1000, false)) {
+ if (wait_for_bit_le32(reg, BIT(ch->ack_bit), ctrl_val,
+ 1000, false)) {
pr_err("Stuck on waiting ack reset_ctl=%p dev=%p id=%lu\n",
reset_ctl, reset_ctl->dev, reset_ctl->id);
diff --git a/drivers/serial/serial_pic32.c b/drivers/serial/serial_pic32.c
index b0e01aa..0632d26 100644
--- a/drivers/serial/serial_pic32.c
+++ b/drivers/serial/serial_pic32.c
@@ -51,8 +51,8 @@
u32 div = DIV_ROUND_CLOSEST(clk, baudrate * 16);
/* wait for TX FIFO to empty */
- wait_for_bit(__func__, base + U_STA, UART_TX_EMPTY,
- true, CONFIG_SYS_HZ, false);
+ wait_for_bit_le32(base + U_STA, UART_TX_EMPTY,
+ true, CONFIG_SYS_HZ, false);
/* send break */
writel(UART_TX_BRK, base + U_STASET);
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 494639f..1e95dc4 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -40,6 +40,22 @@
many AT91 (ARM) chips. This driver can be used to access
the SPI Flash, such as AT25DF321.
+config BCM63XX_HSSPI
+ bool "BCM63XX HSSPI driver"
+ depends on ARCH_BMIPS
+ help
+ Enable the BCM6328 HSSPI driver. This driver can be used to
+ access the SPI NOR flash on platforms embedding this Broadcom
+ SPI core.
+
+config BCM63XX_SPI
+ bool "BCM6348 SPI driver"
+ depends on ARCH_BMIPS
+ help
+ Enable the BCM6348/BCM6358 SPI driver. This driver can be used to
+ access the SPI NOR flash on platforms embedding these Broadcom
+ SPI cores.
+
config CADENCE_QSPI
bool "Cadence QSPI driver"
help
@@ -217,6 +233,12 @@
used to access the SPI flash on AE3XX and AE250 platforms embedding
this Andestech IP core.
+config DAVINCI_SPI
+ bool "Davinci & Keystone SPI driver"
+ depends on ARCH_DAVINCI || ARCH_KEYSTONE
+ help
+ Enable the Davinci SPI driver
+
config TI_QSPI
bool "TI QSPI driver"
help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index e3184db..4b6000f 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -18,6 +18,8 @@
obj-$(CONFIG_ALTERA_SPI) += altera_spi.o
obj-$(CONFIG_ATH79_SPI) += ath79_spi.o
obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
+obj-$(CONFIG_BCM63XX_HSSPI) += bcm63xx_hsspi.o
+obj-$(CONFIG_BCM63XX_SPI) += bcm63xx_spi.o
obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
obj-$(CONFIG_CF_SPI) += cf_spi.o
obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 228e714..8010ab4 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -394,8 +394,8 @@
* Wait until the transfer is completely done before
* we deactivate CS.
*/
- wait_for_bit(__func__, ®_base->sr,
- ATMEL_SPI_SR_TXEMPTY, true, 1000, false);
+ wait_for_bit_le32(®_base->sr,
+ ATMEL_SPI_SR_TXEMPTY, true, 1000, false);
atmel_spi_cs_deactivate(dev);
}
diff --git a/drivers/spi/bcm63xx_hsspi.c b/drivers/spi/bcm63xx_hsspi.c
new file mode 100644
index 0000000..3393166
--- /dev/null
+++ b/drivers/spi/bcm63xx_hsspi.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/spi/spi-bcm63xx-hsspi.c:
+ * Copyright (C) 2000-2010 Broadcom Corporation
+ * Copyright (C) 2012-2013 Jonas Gorski <jogo@openwrt.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <spi.h>
+#include <reset.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define HSSPI_PP 0
+
+#define SPI_MAX_SYNC_CLOCK 30000000
+
+/* SPI Control register */
+#define SPI_CTL_REG 0x000
+#define SPI_CTL_CS_POL_SHIFT 0
+#define SPI_CTL_CS_POL_MASK (0xff << SPI_CTL_CS_POL_SHIFT)
+#define SPI_CTL_CLK_GATE_SHIFT 16
+#define SPI_CTL_CLK_GATE_MASK (1 << SPI_CTL_CLK_GATE_SHIFT)
+#define SPI_CTL_CLK_POL_SHIFT 17
+#define SPI_CTL_CLK_POL_MASK (1 << SPI_CTL_CLK_POL_SHIFT)
+
+/* SPI Interrupts registers */
+#define SPI_IR_STAT_REG 0x008
+#define SPI_IR_ST_MASK_REG 0x00c
+#define SPI_IR_MASK_REG 0x010
+
+#define SPI_IR_CLEAR_ALL 0xff001f1f
+
+/* SPI Ping-Pong Command registers */
+#define SPI_CMD_REG (0x080 + (0x40 * (HSSPI_PP)) + 0x00)
+#define SPI_CMD_OP_SHIFT 0
+#define SPI_CMD_OP_START (0x1 << SPI_CMD_OP_SHIFT)
+#define SPI_CMD_PFL_SHIFT 8
+#define SPI_CMD_PFL_MASK (0x7 << SPI_CMD_PFL_SHIFT)
+#define SPI_CMD_SLAVE_SHIFT 12
+#define SPI_CMD_SLAVE_MASK (0x7 << SPI_CMD_SLAVE_SHIFT)
+
+/* SPI Ping-Pong Status registers */
+#define SPI_STAT_REG (0x080 + (0x40 * (HSSPI_PP)) + 0x04)
+#define SPI_STAT_SRCBUSY_SHIFT 1
+#define SPI_STAT_SRCBUSY_MASK (1 << SPI_STAT_SRCBUSY_SHIFT)
+
+/* SPI Profile Clock registers */
+#define SPI_PFL_CLK_REG(x) (0x100 + (0x20 * (x)) + 0x00)
+#define SPI_PFL_CLK_FREQ_SHIFT 0
+#define SPI_PFL_CLK_FREQ_MASK (0x3fff << SPI_PFL_CLK_FREQ_SHIFT)
+#define SPI_PFL_CLK_RSTLOOP_SHIFT 15
+#define SPI_PFL_CLK_RSTLOOP_MASK (1 << SPI_PFL_CLK_RSTLOOP_SHIFT)
+
+/* SPI Profile Signal registers */
+#define SPI_PFL_SIG_REG(x) (0x100 + (0x20 * (x)) + 0x04)
+#define SPI_PFL_SIG_LATCHRIS_SHIFT 12
+#define SPI_PFL_SIG_LATCHRIS_MASK (1 << SPI_PFL_SIG_LATCHRIS_SHIFT)
+#define SPI_PFL_SIG_LAUNCHRIS_SHIFT 13
+#define SPI_PFL_SIG_LAUNCHRIS_MASK (1 << SPI_PFL_SIG_LAUNCHRIS_SHIFT)
+#define SPI_PFL_SIG_ASYNCIN_SHIFT 16
+#define SPI_PFL_SIG_ASYNCIN_MASK (1 << SPI_PFL_SIG_ASYNCIN_SHIFT)
+
+/* SPI Profile Mode registers */
+#define SPI_PFL_MODE_REG(x) (0x100 + (0x20 * (x)) + 0x08)
+#define SPI_PFL_MODE_FILL_SHIFT 0
+#define SPI_PFL_MODE_FILL_MASK (0xff << SPI_PFL_MODE_FILL_SHIFT)
+#define SPI_PFL_MODE_MDRDSZ_SHIFT 16
+#define SPI_PFL_MODE_MDRDSZ_MASK (1 << SPI_PFL_MODE_MDRDSZ_SHIFT)
+#define SPI_PFL_MODE_MDWRSZ_SHIFT 18
+#define SPI_PFL_MODE_MDWRSZ_MASK (1 << SPI_PFL_MODE_MDWRSZ_SHIFT)
+#define SPI_PFL_MODE_3WIRE_SHIFT 20
+#define SPI_PFL_MODE_3WIRE_MASK (1 << SPI_PFL_MODE_3WIRE_SHIFT)
+
+/* SPI Ping-Pong FIFO registers */
+#define HSSPI_FIFO_SIZE 0x200
+#define HSSPI_FIFO_BASE (0x200 + \
+ (HSSPI_FIFO_SIZE * HSSPI_PP))
+
+/* SPI Ping-Pong FIFO OP register */
+#define HSSPI_FIFO_OP_SIZE 0x2
+#define HSSPI_FIFO_OP_REG (HSSPI_FIFO_BASE + 0x00)
+#define HSSPI_FIFO_OP_BYTES_SHIFT 0
+#define HSSPI_FIFO_OP_BYTES_MASK (0x3ff << HSSPI_FIFO_OP_BYTES_SHIFT)
+#define HSSPI_FIFO_OP_MBIT_SHIFT 11
+#define HSSPI_FIFO_OP_MBIT_MASK (1 << HSSPI_FIFO_OP_MBIT_SHIFT)
+#define HSSPI_FIFO_OP_CODE_SHIFT 13
+#define HSSPI_FIFO_OP_READ_WRITE (1 << HSSPI_FIFO_OP_CODE_SHIFT)
+#define HSSPI_FIFO_OP_CODE_W (2 << HSSPI_FIFO_OP_CODE_SHIFT)
+#define HSSPI_FIFO_OP_CODE_R (3 << HSSPI_FIFO_OP_CODE_SHIFT)
+
+struct bcm63xx_hsspi_priv {
+ void __iomem *regs;
+ ulong clk_rate;
+ uint8_t num_cs;
+ uint8_t cs_pols;
+ uint speed;
+};
+
+static int bcm63xx_hsspi_cs_info(struct udevice *bus, uint cs,
+ struct spi_cs_info *info)
+{
+ struct bcm63xx_hsspi_priv *priv = dev_get_priv(bus);
+
+ if (cs >= priv->num_cs) {
+ printf("no cs %u\n", cs);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int bcm63xx_hsspi_set_mode(struct udevice *bus, uint mode)
+{
+ struct bcm63xx_hsspi_priv *priv = dev_get_priv(bus);
+
+ /* clock polarity */
+ if (mode & SPI_CPOL)
+ setbits_be32(priv->regs + SPI_CTL_REG, SPI_CTL_CLK_POL_MASK);
+ else
+ clrbits_be32(priv->regs + SPI_CTL_REG, SPI_CTL_CLK_POL_MASK);
+
+ return 0;
+}
+
+static int bcm63xx_hsspi_set_speed(struct udevice *bus, uint speed)
+{
+ struct bcm63xx_hsspi_priv *priv = dev_get_priv(bus);
+
+ priv->speed = speed;
+
+ return 0;
+}
+
+static void bcm63xx_hsspi_activate_cs(struct bcm63xx_hsspi_priv *priv,
+ struct dm_spi_slave_platdata *plat)
+{
+ uint32_t clr, set;
+
+ /* profile clock */
+ set = DIV_ROUND_UP(priv->clk_rate, priv->speed);
+ set = DIV_ROUND_UP(2048, set);
+ set &= SPI_PFL_CLK_FREQ_MASK;
+ set |= SPI_PFL_CLK_RSTLOOP_MASK;
+ writel_be(set, priv->regs + SPI_PFL_CLK_REG(plat->cs));
+
+ /* profile signal */
+ set = 0;
+ clr = SPI_PFL_SIG_LAUNCHRIS_MASK |
+ SPI_PFL_SIG_LATCHRIS_MASK |
+ SPI_PFL_SIG_ASYNCIN_MASK;
+
+ /* latch/launch config */
+ if (plat->mode & SPI_CPHA)
+ set |= SPI_PFL_SIG_LAUNCHRIS_MASK;
+ else
+ set |= SPI_PFL_SIG_LATCHRIS_MASK;
+
+ /* async clk */
+ if (priv->speed > SPI_MAX_SYNC_CLOCK)
+ set |= SPI_PFL_SIG_ASYNCIN_MASK;
+
+ clrsetbits_be32(priv->regs + SPI_PFL_SIG_REG(plat->cs), clr, set);
+
+ /* global control */
+ set = 0;
+ clr = 0;
+
+ /* invert cs polarity */
+ if (priv->cs_pols & BIT(plat->cs))
+ clr |= BIT(plat->cs);
+ else
+ set |= BIT(plat->cs);
+
+ /* invert dummy cs polarity */
+ if (priv->cs_pols & BIT(!plat->cs))
+ clr |= BIT(!plat->cs);
+ else
+ set |= BIT(!plat->cs);
+
+ clrsetbits_be32(priv->regs + SPI_CTL_REG, clr, set);
+}
+
+static void bcm63xx_hsspi_deactivate_cs(struct bcm63xx_hsspi_priv *priv)
+{
+ /* restore cs polarities */
+ clrsetbits_be32(priv->regs + SPI_CTL_REG, SPI_CTL_CS_POL_MASK,
+ priv->cs_pols);
+}
+
+/*
+ * BCM63xx HSSPI driver doesn't allow keeping CS active between transfers
+ * because they are controlled by HW.
+ * However, it provides a mechanism to prepend write transfers prior to read
+ * transfers (with a maximum prepend of 15 bytes), which is usually enough for
+ * SPI-connected flashes since reading requires prepending a write transfer of
+ * 5 bytes. On the other hand it also provides a way to invert each CS
+ * polarity, not only between transfers like the older BCM63xx SPI driver, but
+ * also the rest of the time.
+ *
+ * Instead of using the prepend mechanism, this implementation inverts the
+ * polarity of both the desired CS and another dummy CS when the bus is
+ * claimed. This way, the dummy CS is restored to its inactive value when
+ * transfers are issued and the desired CS is preserved in its active value
+ * all the time. This hack is also used in the upstream linux driver and
+ * allows keeping CS active between trasnfers even if the HW doesn't give
+ * this possibility.
+ */
+static int bcm63xx_hsspi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev->parent);
+ struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
+ size_t data_bytes = bitlen / 8;
+ size_t step_size = HSSPI_FIFO_SIZE;
+ uint16_t opcode = 0;
+ uint32_t val;
+ const uint8_t *tx = dout;
+ uint8_t *rx = din;
+
+ if (flags & SPI_XFER_BEGIN)
+ bcm63xx_hsspi_activate_cs(priv, plat);
+
+ /* fifo operation */
+ if (tx && rx)
+ opcode = HSSPI_FIFO_OP_READ_WRITE;
+ else if (rx)
+ opcode = HSSPI_FIFO_OP_CODE_R;
+ else if (tx)
+ opcode = HSSPI_FIFO_OP_CODE_W;
+
+ if (opcode != HSSPI_FIFO_OP_CODE_R)
+ step_size -= HSSPI_FIFO_OP_SIZE;
+
+ /* dual mode */
+ if ((opcode == HSSPI_FIFO_OP_CODE_R && plat->mode == SPI_RX_DUAL) ||
+ (opcode == HSSPI_FIFO_OP_CODE_W && plat->mode == SPI_TX_DUAL))
+ opcode |= HSSPI_FIFO_OP_MBIT_MASK;
+
+ /* profile mode */
+ val = SPI_PFL_MODE_FILL_MASK |
+ SPI_PFL_MODE_MDRDSZ_MASK |
+ SPI_PFL_MODE_MDWRSZ_MASK;
+ if (plat->mode & SPI_3WIRE)
+ val |= SPI_PFL_MODE_3WIRE_MASK;
+ writel_be(val, priv->regs + SPI_PFL_MODE_REG(plat->cs));
+
+ /* transfer loop */
+ while (data_bytes > 0) {
+ size_t curr_step = min(step_size, data_bytes);
+ int ret;
+
+ /* copy tx data */
+ if (tx) {
+ memcpy_toio(priv->regs + HSSPI_FIFO_BASE +
+ HSSPI_FIFO_OP_SIZE, tx, curr_step);
+ tx += curr_step;
+ }
+
+ /* set fifo operation */
+ writew_be(opcode | (curr_step & HSSPI_FIFO_OP_BYTES_MASK),
+ priv->regs + HSSPI_FIFO_OP_REG);
+
+ /* issue the transfer */
+ val = SPI_CMD_OP_START;
+ val |= (plat->cs << SPI_CMD_PFL_SHIFT) &
+ SPI_CMD_PFL_MASK;
+ val |= (!plat->cs << SPI_CMD_SLAVE_SHIFT) &
+ SPI_CMD_SLAVE_MASK;
+ writel_be(val, priv->regs + SPI_CMD_REG);
+
+ /* wait for completion */
+ ret = wait_for_bit_be32(priv->regs + SPI_STAT_REG,
+ SPI_STAT_SRCBUSY_MASK, false,
+ 1000, false);
+ if (ret) {
+ printf("interrupt timeout\n");
+ return ret;
+ }
+
+ /* copy rx data */
+ if (rx) {
+ memcpy_fromio(rx, priv->regs + HSSPI_FIFO_BASE,
+ curr_step);
+ rx += curr_step;
+ }
+
+ data_bytes -= curr_step;
+ }
+
+ if (flags & SPI_XFER_END)
+ bcm63xx_hsspi_deactivate_cs(priv);
+
+ return 0;
+}
+
+static const struct dm_spi_ops bcm63xx_hsspi_ops = {
+ .cs_info = bcm63xx_hsspi_cs_info,
+ .set_mode = bcm63xx_hsspi_set_mode,
+ .set_speed = bcm63xx_hsspi_set_speed,
+ .xfer = bcm63xx_hsspi_xfer,
+};
+
+static const struct udevice_id bcm63xx_hsspi_ids[] = {
+ { .compatible = "brcm,bcm6328-hsspi", },
+ { /* sentinel */ }
+};
+
+static int bcm63xx_hsspi_child_pre_probe(struct udevice *dev)
+{
+ struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev->parent);
+ struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
+
+ /* check cs */
+ if (plat->cs >= priv->num_cs) {
+ printf("no cs %u\n", plat->cs);
+ return -ENODEV;
+ }
+
+ /* cs polarity */
+ if (plat->mode & SPI_CS_HIGH)
+ priv->cs_pols |= BIT(plat->cs);
+ else
+ priv->cs_pols &= ~BIT(plat->cs);
+
+ return 0;
+}
+
+static int bcm63xx_hsspi_probe(struct udevice *dev)
+{
+ struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev);
+ struct reset_ctl rst_ctl;
+ struct clk clk;
+ fdt_addr_t addr;
+ fdt_size_t size;
+ int ret;
+
+ addr = devfdt_get_addr_size_index(dev, 0, &size);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->regs = ioremap(addr, size);
+ priv->num_cs = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+ "num-cs", 8);
+
+ /* enable clock */
+ ret = clk_get_by_name(dev, "hsspi", &clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_enable(&clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_free(&clk);
+ if (ret < 0)
+ return ret;
+
+ /* get clock rate */
+ ret = clk_get_by_name(dev, "pll", &clk);
+ if (ret < 0)
+ return ret;
+
+ priv->clk_rate = clk_get_rate(&clk);
+
+ ret = clk_free(&clk);
+ if (ret < 0)
+ return ret;
+
+ /* perform reset */
+ ret = reset_get_by_index(dev, 0, &rst_ctl);
+ if (ret < 0)
+ return ret;
+
+ ret = reset_deassert(&rst_ctl);
+ if (ret < 0)
+ return ret;
+
+ ret = reset_free(&rst_ctl);
+ if (ret < 0)
+ return ret;
+
+ /* initialize hardware */
+ writel_be(0, priv->regs + SPI_IR_MASK_REG);
+
+ /* clear pending interrupts */
+ writel_be(SPI_IR_CLEAR_ALL, priv->regs + SPI_IR_STAT_REG);
+
+ /* enable clk gate */
+ setbits_be32(priv->regs + SPI_CTL_REG, SPI_CTL_CLK_GATE_MASK);
+
+ /* read default cs polarities */
+ priv->cs_pols = readl_be(priv->regs + SPI_CTL_REG) &
+ SPI_CTL_CS_POL_MASK;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(bcm63xx_hsspi) = {
+ .name = "bcm63xx_hsspi",
+ .id = UCLASS_SPI,
+ .of_match = bcm63xx_hsspi_ids,
+ .ops = &bcm63xx_hsspi_ops,
+ .priv_auto_alloc_size = sizeof(struct bcm63xx_hsspi_priv),
+ .child_pre_probe = bcm63xx_hsspi_child_pre_probe,
+ .probe = bcm63xx_hsspi_probe,
+};
diff --git a/drivers/spi/bcm63xx_spi.c b/drivers/spi/bcm63xx_spi.c
new file mode 100644
index 0000000..f0df687
--- /dev/null
+++ b/drivers/spi/bcm63xx_spi.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/spi/spi-bcm63xx.c:
+ * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <spi.h>
+#include <reset.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* BCM6348 SPI core */
+#define SPI_6348_CLK 0x06
+#define SPI_6348_CMD 0x00
+#define SPI_6348_CTL 0x40
+#define SPI_6348_CTL_SHIFT 6
+#define SPI_6348_FILL 0x07
+#define SPI_6348_IR_MASK 0x04
+#define SPI_6348_IR_STAT 0x02
+#define SPI_6348_RX 0x80
+#define SPI_6348_RX_SIZE 0x3f
+#define SPI_6348_TX 0x41
+#define SPI_6348_TX_SIZE 0x3f
+
+/* BCM6358 SPI core */
+#define SPI_6358_CLK 0x706
+#define SPI_6358_CMD 0x700
+#define SPI_6358_CTL 0x000
+#define SPI_6358_CTL_SHIFT 14
+#define SPI_6358_FILL 0x707
+#define SPI_6358_IR_MASK 0x702
+#define SPI_6358_IR_STAT 0x704
+#define SPI_6358_RX 0x400
+#define SPI_6358_RX_SIZE 0x220
+#define SPI_6358_TX 0x002
+#define SPI_6358_TX_SIZE 0x21e
+
+/* SPI Clock register */
+#define SPI_CLK_SHIFT 0
+#define SPI_CLK_20MHZ (0 << SPI_CLK_SHIFT)
+#define SPI_CLK_0_391MHZ (1 << SPI_CLK_SHIFT)
+#define SPI_CLK_0_781MHZ (2 << SPI_CLK_SHIFT)
+#define SPI_CLK_1_563MHZ (3 << SPI_CLK_SHIFT)
+#define SPI_CLK_3_125MHZ (4 << SPI_CLK_SHIFT)
+#define SPI_CLK_6_250MHZ (5 << SPI_CLK_SHIFT)
+#define SPI_CLK_12_50MHZ (6 << SPI_CLK_SHIFT)
+#define SPI_CLK_25MHZ (7 << SPI_CLK_SHIFT)
+#define SPI_CLK_MASK (7 << SPI_CLK_SHIFT)
+#define SPI_CLK_SSOFF_SHIFT 3
+#define SPI_CLK_SSOFF_2 (2 << SPI_CLK_SSOFF_SHIFT)
+#define SPI_CLK_SSOFF_MASK (7 << SPI_CLK_SSOFF_SHIFT)
+#define SPI_CLK_BSWAP_SHIFT 7
+#define SPI_CLK_BSWAP_MASK (1 << SPI_CLK_BSWAP_SHIFT)
+
+/* SPI Command register */
+#define SPI_CMD_OP_SHIFT 0
+#define SPI_CMD_OP_START (0x3 << SPI_CMD_OP_SHIFT)
+#define SPI_CMD_SLAVE_SHIFT 4
+#define SPI_CMD_SLAVE_MASK (0xf << SPI_CMD_SLAVE_SHIFT)
+#define SPI_CMD_PREPEND_SHIFT 8
+#define SPI_CMD_PREPEND_BYTES 0xf
+#define SPI_CMD_3WIRE_SHIFT 12
+#define SPI_CMD_3WIRE_MASK (1 << SPI_CMD_3WIRE_SHIFT)
+
+/* SPI Control register */
+#define SPI_CTL_TYPE_FD_RW 0
+#define SPI_CTL_TYPE_HD_W 1
+#define SPI_CTL_TYPE_HD_R 2
+
+/* SPI Interrupt registers */
+#define SPI_IR_DONE_SHIFT 0
+#define SPI_IR_DONE_MASK (1 << SPI_IR_DONE_SHIFT)
+#define SPI_IR_RXOVER_SHIFT 1
+#define SPI_IR_RXOVER_MASK (1 << SPI_IR_RXOVER_SHIFT)
+#define SPI_IR_TXUNDER_SHIFT 2
+#define SPI_IR_TXUNDER_MASK (1 << SPI_IR_TXUNDER_SHIFT)
+#define SPI_IR_TXOVER_SHIFT 3
+#define SPI_IR_TXOVER_MASK (1 << SPI_IR_TXOVER_SHIFT)
+#define SPI_IR_RXUNDER_SHIFT 4
+#define SPI_IR_RXUNDER_MASK (1 << SPI_IR_RXUNDER_SHIFT)
+#define SPI_IR_CLEAR_MASK (SPI_IR_DONE_MASK |\
+ SPI_IR_RXOVER_MASK |\
+ SPI_IR_TXUNDER_MASK |\
+ SPI_IR_TXOVER_MASK |\
+ SPI_IR_RXUNDER_MASK)
+
+enum bcm63xx_regs_spi {
+ SPI_CLK,
+ SPI_CMD,
+ SPI_CTL,
+ SPI_CTL_SHIFT,
+ SPI_FILL,
+ SPI_IR_MASK,
+ SPI_IR_STAT,
+ SPI_RX,
+ SPI_RX_SIZE,
+ SPI_TX,
+ SPI_TX_SIZE,
+};
+
+struct bcm63xx_spi_priv {
+ const unsigned long *regs;
+ void __iomem *base;
+ size_t tx_bytes;
+ uint8_t num_cs;
+};
+
+#define SPI_CLK_CNT 8
+static const unsigned bcm63xx_spi_freq_table[SPI_CLK_CNT][2] = {
+ { 25000000, SPI_CLK_25MHZ },
+ { 20000000, SPI_CLK_20MHZ },
+ { 12500000, SPI_CLK_12_50MHZ },
+ { 6250000, SPI_CLK_6_250MHZ },
+ { 3125000, SPI_CLK_3_125MHZ },
+ { 1563000, SPI_CLK_1_563MHZ },
+ { 781000, SPI_CLK_0_781MHZ },
+ { 391000, SPI_CLK_0_391MHZ }
+};
+
+static int bcm63xx_spi_cs_info(struct udevice *bus, uint cs,
+ struct spi_cs_info *info)
+{
+ struct bcm63xx_spi_priv *priv = dev_get_priv(bus);
+
+ if (cs >= priv->num_cs) {
+ printf("no cs %u\n", cs);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int bcm63xx_spi_set_mode(struct udevice *bus, uint mode)
+{
+ struct bcm63xx_spi_priv *priv = dev_get_priv(bus);
+ const unsigned long *regs = priv->regs;
+
+ if (mode & SPI_LSB_FIRST)
+ setbits_8(priv->base + regs[SPI_CLK], SPI_CLK_BSWAP_MASK);
+ else
+ clrbits_8(priv->base + regs[SPI_CLK], SPI_CLK_BSWAP_MASK);
+
+ return 0;
+}
+
+static int bcm63xx_spi_set_speed(struct udevice *bus, uint speed)
+{
+ struct bcm63xx_spi_priv *priv = dev_get_priv(bus);
+ const unsigned long *regs = priv->regs;
+ uint8_t clk_cfg;
+ int i;
+
+ /* default to lowest clock configuration */
+ clk_cfg = SPI_CLK_0_391MHZ;
+
+ /* find the closest clock configuration */
+ for (i = 0; i < SPI_CLK_CNT; i++) {
+ if (speed >= bcm63xx_spi_freq_table[i][0]) {
+ clk_cfg = bcm63xx_spi_freq_table[i][1];
+ break;
+ }
+ }
+
+ /* write clock configuration */
+ clrsetbits_8(priv->base + regs[SPI_CLK],
+ SPI_CLK_SSOFF_MASK | SPI_CLK_MASK,
+ clk_cfg | SPI_CLK_SSOFF_2);
+
+ return 0;
+}
+
+/*
+ * BCM63xx SPI driver doesn't allow keeping CS active between transfers since
+ * they are HW controlled.
+ * However, it provides a mechanism to prepend write transfers prior to read
+ * transfers (with a maximum prepend of 15 bytes), which is usually enough for
+ * SPI-connected flashes since reading requires prepending a write transfer of
+ * 5 bytes.
+ *
+ * This implementation takes advantage of the prepend mechanism and combines
+ * multiple transfers into a single one where possible (single/multiple write
+ * transfer(s) followed by a final read/write transfer).
+ * However, it's not possible to buffer reads, which means that read transfers
+ * should always be done as the final ones.
+ * On the other hand, take into account that combining write transfers into
+ * a single one is just buffering and doesn't require prepend mechanism.
+ */
+static int bcm63xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct bcm63xx_spi_priv *priv = dev_get_priv(dev->parent);
+ const unsigned long *regs = priv->regs;
+ size_t data_bytes = bitlen / 8;
+
+ if (flags & SPI_XFER_BEGIN) {
+ /* clear prepends */
+ priv->tx_bytes = 0;
+
+ /* initialize hardware */
+ writeb_be(0, priv->base + regs[SPI_IR_MASK]);
+ }
+
+ if (din) {
+ /* buffering reads not possible since cs is hw controlled */
+ if (!(flags & SPI_XFER_END)) {
+ printf("unable to buffer reads\n");
+ return -EINVAL;
+ }
+
+ /* check rx size */
+ if (data_bytes > regs[SPI_RX_SIZE]) {
+ printf("max rx bytes exceeded\n");
+ return -EMSGSIZE;
+ }
+ }
+
+ if (dout) {
+ /* check tx size */
+ if (priv->tx_bytes + data_bytes > regs[SPI_TX_SIZE]) {
+ printf("max tx bytes exceeded\n");
+ return -EMSGSIZE;
+ }
+
+ /* copy tx data */
+ memcpy_toio(priv->base + regs[SPI_TX] + priv->tx_bytes,
+ dout, data_bytes);
+ priv->tx_bytes += data_bytes;
+ }
+
+ if (flags & SPI_XFER_END) {
+ struct dm_spi_slave_platdata *plat =
+ dev_get_parent_platdata(dev);
+ uint16_t val, cmd;
+ int ret;
+
+ /* determine control config */
+ if (dout && !din) {
+ /* buffered write transfers */
+ val = priv->tx_bytes;
+ val |= (SPI_CTL_TYPE_HD_W << regs[SPI_CTL_SHIFT]);
+ priv->tx_bytes = 0;
+ } else {
+ if (dout && din && (flags & SPI_XFER_ONCE)) {
+ /* full duplex read/write */
+ val = data_bytes;
+ val |= (SPI_CTL_TYPE_FD_RW <<
+ regs[SPI_CTL_SHIFT]);
+ priv->tx_bytes = 0;
+ } else {
+ /* prepended write transfer */
+ val = data_bytes;
+ val |= (SPI_CTL_TYPE_HD_R <<
+ regs[SPI_CTL_SHIFT]);
+ if (priv->tx_bytes > SPI_CMD_PREPEND_BYTES) {
+ printf("max prepend bytes exceeded\n");
+ return -EMSGSIZE;
+ }
+ }
+ }
+
+ if (regs[SPI_CTL_SHIFT] >= 8)
+ writew_be(val, priv->base + regs[SPI_CTL]);
+ else
+ writeb_be(val, priv->base + regs[SPI_CTL]);
+
+ /* clear interrupts */
+ writeb_be(SPI_IR_CLEAR_MASK, priv->base + regs[SPI_IR_STAT]);
+
+ /* issue the transfer */
+ cmd = SPI_CMD_OP_START;
+ cmd |= (plat->cs << SPI_CMD_SLAVE_SHIFT) & SPI_CMD_SLAVE_MASK;
+ cmd |= (priv->tx_bytes << SPI_CMD_PREPEND_SHIFT);
+ if (plat->mode & SPI_3WIRE)
+ cmd |= SPI_CMD_3WIRE_MASK;
+ writew_be(cmd, priv->base + regs[SPI_CMD]);
+
+ /* enable interrupts */
+ writeb_be(SPI_IR_DONE_MASK, priv->base + regs[SPI_IR_MASK]);
+
+ ret = wait_for_bit_8(priv->base + regs[SPI_IR_STAT],
+ SPI_IR_DONE_MASK, true, 1000, false);
+ if (ret) {
+ printf("interrupt timeout\n");
+ return ret;
+ }
+
+ /* copy rx data */
+ if (din)
+ memcpy_fromio(din, priv->base + regs[SPI_RX],
+ data_bytes);
+ }
+
+ return 0;
+}
+
+static const struct dm_spi_ops bcm63xx_spi_ops = {
+ .cs_info = bcm63xx_spi_cs_info,
+ .set_mode = bcm63xx_spi_set_mode,
+ .set_speed = bcm63xx_spi_set_speed,
+ .xfer = bcm63xx_spi_xfer,
+};
+
+static const unsigned long bcm6348_spi_regs[] = {
+ [SPI_CLK] = SPI_6348_CLK,
+ [SPI_CMD] = SPI_6348_CMD,
+ [SPI_CTL] = SPI_6348_CTL,
+ [SPI_CTL_SHIFT] = SPI_6348_CTL_SHIFT,
+ [SPI_FILL] = SPI_6348_FILL,
+ [SPI_IR_MASK] = SPI_6348_IR_MASK,
+ [SPI_IR_STAT] = SPI_6348_IR_STAT,
+ [SPI_RX] = SPI_6348_RX,
+ [SPI_RX_SIZE] = SPI_6348_RX_SIZE,
+ [SPI_TX] = SPI_6348_TX,
+ [SPI_TX_SIZE] = SPI_6348_TX_SIZE,
+};
+
+static const unsigned long bcm6358_spi_regs[] = {
+ [SPI_CLK] = SPI_6358_CLK,
+ [SPI_CMD] = SPI_6358_CMD,
+ [SPI_CTL] = SPI_6358_CTL,
+ [SPI_CTL_SHIFT] = SPI_6358_CTL_SHIFT,
+ [SPI_FILL] = SPI_6358_FILL,
+ [SPI_IR_MASK] = SPI_6358_IR_MASK,
+ [SPI_IR_STAT] = SPI_6358_IR_STAT,
+ [SPI_RX] = SPI_6358_RX,
+ [SPI_RX_SIZE] = SPI_6358_RX_SIZE,
+ [SPI_TX] = SPI_6358_TX,
+ [SPI_TX_SIZE] = SPI_6358_TX_SIZE,
+};
+
+static const struct udevice_id bcm63xx_spi_ids[] = {
+ {
+ .compatible = "brcm,bcm6348-spi",
+ .data = (ulong)&bcm6348_spi_regs,
+ }, {
+ .compatible = "brcm,bcm6358-spi",
+ .data = (ulong)&bcm6358_spi_regs,
+ }, { /* sentinel */ }
+};
+
+static int bcm63xx_spi_child_pre_probe(struct udevice *dev)
+{
+ struct bcm63xx_spi_priv *priv = dev_get_priv(dev->parent);
+ const unsigned long *regs = priv->regs;
+ struct spi_slave *slave = dev_get_parent_priv(dev);
+ struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
+
+ /* check cs */
+ if (plat->cs >= priv->num_cs) {
+ printf("no cs %u\n", plat->cs);
+ return -ENODEV;
+ }
+
+ /* max read/write sizes */
+ slave->max_read_size = regs[SPI_RX_SIZE];
+ slave->max_write_size = regs[SPI_TX_SIZE];
+
+ return 0;
+}
+
+static int bcm63xx_spi_probe(struct udevice *dev)
+{
+ struct bcm63xx_spi_priv *priv = dev_get_priv(dev);
+ const unsigned long *regs =
+ (const unsigned long *)dev_get_driver_data(dev);
+ struct reset_ctl rst_ctl;
+ struct clk clk;
+ fdt_addr_t addr;
+ fdt_size_t size;
+ int ret;
+
+ addr = devfdt_get_addr_size_index(dev, 0, &size);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->regs = regs;
+ priv->base = ioremap(addr, size);
+ priv->num_cs = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+ "num-cs", 8);
+
+ /* enable clock */
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_enable(&clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_free(&clk);
+ if (ret < 0)
+ return ret;
+
+ /* perform reset */
+ ret = reset_get_by_index(dev, 0, &rst_ctl);
+ if (ret < 0)
+ return ret;
+
+ ret = reset_deassert(&rst_ctl);
+ if (ret < 0)
+ return ret;
+
+ ret = reset_free(&rst_ctl);
+ if (ret < 0)
+ return ret;
+
+ /* initialize hardware */
+ writeb_be(0, priv->base + regs[SPI_IR_MASK]);
+
+ /* set fill register */
+ writeb_be(0xff, priv->base + regs[SPI_FILL]);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(bcm63xx_spi) = {
+ .name = "bcm63xx_spi",
+ .id = UCLASS_SPI,
+ .of_match = bcm63xx_spi_ids,
+ .ops = &bcm63xx_spi_ops,
+ .priv_auto_alloc_size = sizeof(struct bcm63xx_spi_priv),
+ .child_pre_probe = bcm63xx_spi_child_pre_probe,
+ .probe = bcm63xx_spi_probe,
+};
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 9a6e41f..7b312f8 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -212,7 +212,7 @@
/* Set Chip select */
cadence_qspi_apb_chipselect(base, spi_chip_select(dev),
- CONFIG_CQSPI_DECODER);
+ plat->is_decoded_cs);
if ((flags & SPI_XFER_END) || (flags == 0)) {
if (priv->cmd_len == 0) {
@@ -296,7 +296,11 @@
plat->regbase = (void *)data[0];
plat->ahbbase = (void *)data[2];
- plat->sram_size = fdtdec_get_int(blob, node, "sram-size", 128);
+ plat->is_decoded_cs = fdtdec_get_bool(blob, node, "cdns,is-decoded-cs");
+ plat->fifo_depth = fdtdec_get_uint(blob, node, "cdns,fifo-depth", 128);
+ plat->fifo_width = fdtdec_get_uint(blob, node, "cdns,fifo-width", 4);
+ plat->trigger_address = fdtdec_get_uint(blob, node,
+ "cdns,trigger-address", 0);
/* All other paramters are embedded in the child node */
subnode = fdt_first_subnode(blob, node);
@@ -310,12 +314,12 @@
500000);
/* Read other parameters from DT */
- plat->page_size = fdtdec_get_int(blob, subnode, "page-size", 256);
- plat->block_size = fdtdec_get_int(blob, subnode, "block-size", 16);
- plat->tshsl_ns = fdtdec_get_int(blob, subnode, "tshsl-ns", 200);
- plat->tsd2d_ns = fdtdec_get_int(blob, subnode, "tsd2d-ns", 255);
- plat->tchsh_ns = fdtdec_get_int(blob, subnode, "tchsh-ns", 20);
- plat->tslch_ns = fdtdec_get_int(blob, subnode, "tslch-ns", 20);
+ plat->page_size = fdtdec_get_uint(blob, subnode, "page-size", 256);
+ plat->block_size = fdtdec_get_uint(blob, subnode, "block-size", 16);
+ plat->tshsl_ns = fdtdec_get_uint(blob, subnode, "cdns,tshsl-ns", 200);
+ plat->tsd2d_ns = fdtdec_get_uint(blob, subnode, "cdns,tsd2d-ns", 255);
+ plat->tchsh_ns = fdtdec_get_uint(blob, subnode, "cdns,tchsh-ns", 20);
+ plat->tslch_ns = fdtdec_get_uint(blob, subnode, "cdns,tslch-ns", 20);
debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n",
__func__, plat->regbase, plat->ahbbase, plat->max_hz,
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index d1927a4..9106b09 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -18,14 +18,18 @@
unsigned int max_hz;
void *regbase;
void *ahbbase;
+ bool is_decoded_cs;
+ u32 fifo_depth;
+ u32 fifo_width;
+ u32 trigger_address;
+ /* Flash parameters */
u32 page_size;
u32 block_size;
u32 tshsl_ns;
u32 tsd2d_ns;
u32 tchsh_ns;
u32 tslch_ns;
- u32 sram_size;
};
struct cadence_spi_priv {
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index e02f221..aa3a9ff 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -30,17 +30,13 @@
#include <linux/errno.h>
#include <wait_bit.h>
#include <spi.h>
-#include <bouncebuf.h>
+#include <malloc.h>
#include "cadence_qspi.h"
#define CQSPI_REG_POLL_US 1 /* 1us */
#define CQSPI_REG_RETRY 10000
#define CQSPI_POLL_IDLE_RETRY 3
-#define CQSPI_FIFO_WIDTH 4
-
-#define CQSPI_REG_SRAM_THRESHOLD_WORDS 50
-
/* Transfer mode */
#define CQSPI_INST_TYPE_SINGLE 0
#define CQSPI_INST_TYPE_DUAL 1
@@ -51,9 +47,6 @@
#define CQSPI_DUMMY_CLKS_PER_BYTE 8
#define CQSPI_DUMMY_BYTES_MAX 4
-#define CQSPI_REG_SRAM_FILL_THRESHOLD \
- ((CQSPI_REG_SRAM_SIZE_WORD / 2) * CQSPI_FIFO_WIDTH)
-
/****************************************************************************
* Controller's configuration and status register (offset from QSPI_BASE)
****************************************************************************/
@@ -400,7 +393,7 @@
writel(0, plat->regbase + CQSPI_REG_REMAP);
/* Indirect mode configurations */
- writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
+ writel(plat->fifo_depth / 2, plat->regbase + CQSPI_REG_SRAMPARTITION);
/* Disable all interrupts */
writel(0, plat->regbase + CQSPI_REG_IRQMASK);
@@ -560,7 +553,7 @@
addr_bytes = cmdlen - 1;
/* Setup the indirect trigger address */
- writel((u32)plat->ahbbase,
+ writel(plat->trigger_address,
plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
/* Configure the opcode */
@@ -634,8 +627,6 @@
{
unsigned int remaining = n_rx;
unsigned int bytes_to_read = 0;
- struct bounce_buffer bb;
- u8 *bb_rxbuf;
int ret;
writel(n_rx, plat->regbase + CQSPI_REG_INDIRECTRDBYTES);
@@ -644,11 +635,6 @@
writel(CQSPI_REG_INDIRECTRD_START,
plat->regbase + CQSPI_REG_INDIRECTRD);
- ret = bounce_buffer_start(&bb, (void *)rxbuf, n_rx, GEN_BB_WRITE);
- if (ret)
- return ret;
- bb_rxbuf = bb.bounce_buffer;
-
while (remaining > 0) {
ret = cadence_qspi_wait_for_data(plat);
if (ret < 0) {
@@ -659,24 +645,27 @@
bytes_to_read = ret;
while (bytes_to_read != 0) {
- bytes_to_read *= CQSPI_FIFO_WIDTH;
+ bytes_to_read *= plat->fifo_width;
bytes_to_read = bytes_to_read > remaining ?
remaining : bytes_to_read;
- readsl(plat->ahbbase, bb_rxbuf, bytes_to_read >> 2);
- if (bytes_to_read % 4)
- readsb(plat->ahbbase,
- bb_rxbuf + rounddown(bytes_to_read, 4),
- bytes_to_read % 4);
-
- bb_rxbuf += bytes_to_read;
+ /*
+ * Handle non-4-byte aligned access to avoid
+ * data abort.
+ */
+ if (((uintptr_t)rxbuf % 4) || (bytes_to_read % 4))
+ readsb(plat->ahbbase, rxbuf, bytes_to_read);
+ else
+ readsl(plat->ahbbase, rxbuf,
+ bytes_to_read >> 2);
+ rxbuf += bytes_to_read;
remaining -= bytes_to_read;
bytes_to_read = cadence_qspi_get_rd_sram_level(plat);
}
}
/* Check indirect done status */
- ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_INDIRECTRD,
- CQSPI_REG_INDIRECTRD_DONE, 1, 10, 0);
+ ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTRD,
+ CQSPI_REG_INDIRECTRD_DONE, 1, 10, 0);
if (ret) {
printf("Indirect read completion error (%i)\n", ret);
goto failrd;
@@ -685,7 +674,6 @@
/* Clear indirect completion status */
writel(CQSPI_REG_INDIRECTRD_DONE,
plat->regbase + CQSPI_REG_INDIRECTRD);
- bounce_buffer_stop(&bb);
return 0;
@@ -693,7 +681,6 @@
/* Cancel the indirect read */
writel(CQSPI_REG_INDIRECTRD_CANCEL,
plat->regbase + CQSPI_REG_INDIRECTRD);
- bounce_buffer_stop(&bb);
return ret;
}
@@ -710,7 +697,7 @@
return -EINVAL;
}
/* Setup the indirect trigger address */
- writel((u32)plat->ahbbase,
+ writel(plat->trigger_address,
plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
/* Configure the opcode */
@@ -733,19 +720,22 @@
{
unsigned int page_size = plat->page_size;
unsigned int remaining = n_tx;
+ const u8 *bb_txbuf = txbuf;
+ void *bounce_buf = NULL;
unsigned int write_bytes;
int ret;
- struct bounce_buffer bb;
- u8 *bb_txbuf;
/*
- * Handle non-4-byte aligned accesses via bounce buffer to
- * avoid data abort.
+ * Use bounce buffer for non 32 bit aligned txbuf to avoid data
+ * aborts
*/
- ret = bounce_buffer_start(&bb, (void *)txbuf, n_tx, GEN_BB_READ);
- if (ret)
- return ret;
- bb_txbuf = bb.bounce_buffer;
+ if ((uintptr_t)txbuf % 4) {
+ bounce_buf = malloc(n_tx);
+ if (!bounce_buf)
+ return -ENOMEM;
+ memcpy(bounce_buf, txbuf, n_tx);
+ bb_txbuf = bounce_buf;
+ }
/* Configure the indirect read transfer bytes */
writel(n_tx, plat->regbase + CQSPI_REG_INDIRECTWRBYTES);
@@ -762,9 +752,9 @@
bb_txbuf + rounddown(write_bytes, 4),
write_bytes % 4);
- ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_SDRAMLEVEL,
- CQSPI_REG_SDRAMLEVEL_WR_MASK <<
- CQSPI_REG_SDRAMLEVEL_WR_LSB, 0, 10, 0);
+ ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_SDRAMLEVEL,
+ CQSPI_REG_SDRAMLEVEL_WR_MASK <<
+ CQSPI_REG_SDRAMLEVEL_WR_LSB, 0, 10, 0);
if (ret) {
printf("Indirect write timed out (%i)\n", ret);
goto failwr;
@@ -775,24 +765,26 @@
}
/* Check indirect done status */
- ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_INDIRECTWR,
- CQSPI_REG_INDIRECTWR_DONE, 1, 10, 0);
+ ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTWR,
+ CQSPI_REG_INDIRECTWR_DONE, 1, 10, 0);
if (ret) {
printf("Indirect write completion error (%i)\n", ret);
goto failwr;
}
- bounce_buffer_stop(&bb);
/* Clear indirect completion status */
writel(CQSPI_REG_INDIRECTWR_DONE,
plat->regbase + CQSPI_REG_INDIRECTWR);
+ if (bounce_buf)
+ free(bounce_buf);
return 0;
failwr:
/* Cancel the indirect write */
writel(CQSPI_REG_INDIRECTWR_CANCEL,
plat->regbase + CQSPI_REG_INDIRECTWR);
- bounce_buffer_stop(&bb);
+ if (bounce_buf)
+ free(bounce_buf);
return ret;
}
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 5aa507b..c501aee 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -11,6 +11,7 @@
*/
#include <common.h>
+#include <clk.h>
#include <dm.h>
#include <errno.h>
#include <malloc.h>
@@ -18,7 +19,6 @@
#include <fdtdec.h>
#include <linux/compat.h>
#include <asm/io.h>
-#include <asm/arch/clock_manager.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -94,6 +94,8 @@
void __iomem *regs;
unsigned int freq; /* Default frequency */
unsigned int mode;
+ struct clk clk;
+ unsigned long bus_clk_rate;
int bits_per_word;
u8 cs; /* chip select pin */
@@ -176,14 +178,53 @@
debug("%s: fifo_len=%d\n", __func__, priv->fifo_len);
}
+/*
+ * We define dw_spi_get_clk function as 'weak' as some targets
+ * (like SOCFPGA_GEN5 and SOCFPGA_ARRIA10) don't use standard clock API
+ * and implement dw_spi_get_clk their own way in their clock manager.
+ */
+__weak int dw_spi_get_clk(struct udevice *bus, ulong *rate)
+{
+ struct dw_spi_priv *priv = dev_get_priv(bus);
+ int ret;
+
+ ret = clk_get_by_index(bus, 0, &priv->clk);
+ if (ret)
+ return ret;
+
+ ret = clk_enable(&priv->clk);
+ if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
+ return ret;
+
+ *rate = clk_get_rate(&priv->clk);
+ if (!*rate)
+ goto err_rate;
+
+ debug("%s: get spi controller clk via device tree: %lu Hz\n",
+ __func__, *rate);
+
+ return 0;
+
+err_rate:
+ clk_disable(&priv->clk);
+ clk_free(&priv->clk);
+
+ return -EINVAL;
+}
+
static int dw_spi_probe(struct udevice *bus)
{
struct dw_spi_platdata *plat = dev_get_platdata(bus);
struct dw_spi_priv *priv = dev_get_priv(bus);
+ int ret;
priv->regs = plat->regs;
priv->freq = plat->frequency;
+ ret = dw_spi_get_clk(bus, &priv->bus_clk_rate);
+ if (ret)
+ return ret;
+
/* Currently only bits_per_word == 8 supported */
priv->bits_per_word = 8;
@@ -369,7 +410,7 @@
spi_enable_chip(priv, 0);
/* clk_div doesn't support odd number */
- clk_div = cm_get_spi_controller_clk_hz() / speed;
+ clk_div = priv->bus_clk_rate / speed;
clk_div = (clk_div + 1) & 0xfffe;
dw_writel(priv, DW_SPI_BAUDR, clk_div);
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index 2f5345f..5dc69a6 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -1018,11 +1018,11 @@
priv->num_chipselect = plat->num_chipselect;
/* make sure controller is not busy anywhere */
- ret = wait_for_bit(__func__, &priv->regs->sr,
- QSPI_SR_BUSY_MASK |
- QSPI_SR_AHB_ACC_MASK |
- QSPI_SR_IP_ACC_MASK,
- false, 100, false);
+ ret = wait_for_bit_le32(&priv->regs->sr,
+ QSPI_SR_BUSY_MASK |
+ QSPI_SR_AHB_ACC_MASK |
+ QSPI_SR_IP_ACC_MASK,
+ false, 100, false);
if (ret) {
debug("ERROR : The controller is busy\n");
@@ -1185,11 +1185,11 @@
priv = dev_get_priv(bus);
/* make sure controller is not busy anywhere */
- ret = wait_for_bit(__func__, &priv->regs->sr,
- QSPI_SR_BUSY_MASK |
- QSPI_SR_AHB_ACC_MASK |
- QSPI_SR_IP_ACC_MASK,
- false, 100, false);
+ ret = wait_for_bit_le32(&priv->regs->sr,
+ QSPI_SR_BUSY_MASK |
+ QSPI_SR_AHB_ACC_MASK |
+ QSPI_SR_IP_ACC_MASK,
+ false, 100, false);
if (ret) {
debug("ERROR : The controller is busy\n");
diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c
index 0c6bd29..1ad8cde 100644
--- a/drivers/spi/kirkwood_spi.c
+++ b/drivers/spi/kirkwood_spi.c
@@ -243,6 +243,10 @@
/* Here now the DM part */
+struct mvebu_spi_dev {
+ bool is_errata_50mhz_ac;
+};
+
struct mvebu_spi_platdata {
struct kwspi_registers *spireg;
};
@@ -269,10 +273,44 @@
return 0;
}
+static void mvebu_spi_50mhz_ac_timing_erratum(struct udevice *bus, uint mode)
+{
+ struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
+ struct kwspi_registers *reg = plat->spireg;
+ u32 data;
+
+ /*
+ * Erratum description: (Erratum NO. FE-9144572) The device
+ * SPI interface supports frequencies of up to 50 MHz.
+ * However, due to this erratum, when the device core clock is
+ * 250 MHz and the SPI interfaces is configured for 50MHz SPI
+ * clock and CPOL=CPHA=1 there might occur data corruption on
+ * reads from the SPI device.
+ * Erratum Workaround:
+ * Work in one of the following configurations:
+ * 1. Set CPOL=CPHA=0 in "SPI Interface Configuration
+ * Register".
+ * 2. Set TMISO_SAMPLE value to 0x2 in "SPI Timing Parameters 1
+ * Register" before setting the interface.
+ */
+ data = readl(®->timing1);
+ data &= ~KW_SPI_TMISO_SAMPLE_MASK;
+
+ if (CONFIG_SYS_TCLK == 250000000 &&
+ mode & SPI_CPOL &&
+ mode & SPI_CPHA)
+ data |= KW_SPI_TMISO_SAMPLE_2;
+ else
+ data |= KW_SPI_TMISO_SAMPLE_1;
+
+ writel(data, ®->timing1);
+}
+
static int mvebu_spi_set_mode(struct udevice *bus, uint mode)
{
struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
struct kwspi_registers *reg = plat->spireg;
+ const struct mvebu_spi_dev *drvdata;
u32 data = readl(®->cfg);
data &= ~(KWSPI_CPHA | KWSPI_CPOL | KWSPI_RXLSBF | KWSPI_TXLSBF);
@@ -286,6 +324,10 @@
writel(data, ®->cfg);
+ drvdata = (struct mvebu_spi_dev *)dev_get_driver_data(bus);
+ if (drvdata->is_errata_50mhz_ac)
+ mvebu_spi_50mhz_ac_timing_erratum(bus, mode);
+
return 0;
}
@@ -343,10 +385,31 @@
*/
};
+static const struct mvebu_spi_dev armada_xp_spi_dev_data = {
+ .is_errata_50mhz_ac = false,
+};
+
+static const struct mvebu_spi_dev armada_375_spi_dev_data = {
+ .is_errata_50mhz_ac = false,
+};
+
+static const struct mvebu_spi_dev armada_380_spi_dev_data = {
+ .is_errata_50mhz_ac = true,
+};
+
static const struct udevice_id mvebu_spi_ids[] = {
- { .compatible = "marvell,armada-375-spi" },
- { .compatible = "marvell,armada-380-spi" },
- { .compatible = "marvell,armada-xp-spi" },
+ {
+ .compatible = "marvell,armada-375-spi",
+ .data = (ulong)&armada_375_spi_dev_data
+ },
+ {
+ .compatible = "marvell,armada-380-spi",
+ .data = (ulong)&armada_380_spi_dev_data
+ },
+ {
+ .compatible = "marvell,armada-xp-spi",
+ .data = (ulong)&armada_xp_spi_dev_data
+ },
{ }
};
diff --git a/drivers/spi/mvebu_a3700_spi.c b/drivers/spi/mvebu_a3700_spi.c
index ec49073..d1708a8 100644
--- a/drivers/spi/mvebu_a3700_spi.c
+++ b/drivers/spi/mvebu_a3700_spi.c
@@ -95,8 +95,9 @@
din_8 = din;
while (bytelen) {
- ret = wait_for_bit(__func__, ®->ctrl,
- MVEBU_SPI_A3700_XFER_RDY, true, 100, false);
+ ret = wait_for_bit_le32(®->ctrl,
+ MVEBU_SPI_A3700_XFER_RDY,
+ true,100, false);
if (ret)
return ret;
@@ -109,9 +110,9 @@
writel(pending_dout, ®->dout);
if (din) {
- ret = wait_for_bit(__func__, ®->ctrl,
- MVEBU_SPI_A3700_XFER_RDY,
- true, 100, false);
+ ret = wait_for_bit_le32(®->ctrl,
+ MVEBU_SPI_A3700_XFER_RDY,
+ true, 100, false);
if (ret)
return ret;
@@ -160,8 +161,9 @@
/* Deactivate CS */
if (flags & SPI_XFER_END) {
- ret = wait_for_bit(__func__, ®->ctrl,
- MVEBU_SPI_A3700_XFER_RDY, true, 100, false);
+ ret = wait_for_bit_le32(®->ctrl,
+ MVEBU_SPI_A3700_XFER_RDY,
+ true, 100, false);
if (ret)
return ret;
@@ -231,8 +233,8 @@
/* Flush read/write FIFO */
data = readl(®->cfg);
writel(data | MVEBU_SPI_A3700_FIFO_FLUSH, ®->cfg);
- ret = wait_for_bit(__func__, ®->cfg, MVEBU_SPI_A3700_FIFO_FLUSH,
- false, 1000, false);
+ ret = wait_for_bit_le32(®->cfg, MVEBU_SPI_A3700_FIFO_FLUSH,
+ false, 1000, false);
if (ret)
return ret;
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index e06a603..15d90a5 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -50,7 +50,6 @@
struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
struct spi_slave *slave = dev_get_parent_priv(dev);
int speed;
- int ret;
speed = slave->max_hz;
if (spi->max_hz) {
@@ -62,7 +61,8 @@
if (!speed)
speed = 100000;
if (speed != slave->speed) {
- ret = spi_set_speed_mode(bus, speed, slave->mode);
+ int ret = spi_set_speed_mode(bus, speed, slave->mode);
+
if (ret)
return ret;
slave->speed = speed;
@@ -129,7 +129,6 @@
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
struct dm_spi_ops *ops = spi_get_ops(bus);
-
if (ops->claim_bus)
ops->claim_bus += gd->reloc_off;
if (ops->release_bus)
@@ -348,22 +347,6 @@
}
/* Compatibility function - to be removed */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int node,
- int bus_node)
-{
- struct udevice *bus, *dev;
- int ret;
-
- ret = uclass_get_device_by_of_offset(UCLASS_SPI, bus_node, &bus);
- if (ret)
- return NULL;
- ret = device_get_child_by_of_offset(bus, node, &dev);
- if (ret)
- return NULL;
- return dev_get_parent_priv(dev);
-}
-
-/* Compatibility function - to be removed */
struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
unsigned int speed, unsigned int mode)
{
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 7d81fbd..45e73d2 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -12,7 +12,7 @@
int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen)
{
if (wordlen == 0 || wordlen > 32) {
- printf("spi: invalid wordlen %d\n", wordlen);
+ printf("spi: invalid wordlen %u\n", wordlen);
return -1;
}
@@ -24,11 +24,12 @@
void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
unsigned int cs)
{
- struct spi_slave *slave;
- void *ptr;
+ u8 *ptr;
ptr = malloc(size);
if (ptr) {
+ struct spi_slave *slave;
+
memset(ptr, '\0', size);
slave = (struct spi_slave *)(ptr + offset);
slave->bus = bus;
@@ -38,23 +39,3 @@
return ptr;
}
-
-#ifdef CONFIG_OF_SPI
-struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
- int node)
-{
- int cs, max_hz, mode = 0;
-
- cs = fdtdec_get_int(blob, node, "reg", -1);
- max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 100000);
- if (fdtdec_get_bool(blob, node, "spi-cpol"))
- mode |= SPI_CPOL;
- if (fdtdec_get_bool(blob, node, "spi-cpha"))
- mode |= SPI_CPHA;
- if (fdtdec_get_bool(blob, node, "spi-cs-high"))
- mode |= SPI_CS_HIGH;
- if (fdtdec_get_bool(blob, node, "spi-half-duplex"))
- mode |= SPI_PREAMBLE;
- return spi_setup_slave(busnum, cs, max_hz, mode);
-}
-#endif
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index e7658b4..7de4105 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -51,10 +51,14 @@
source "drivers/usb/dwc3/Kconfig"
+source "drivers/usb/musb/Kconfig"
+
source "drivers/usb/musb-new/Kconfig"
source "drivers/usb/emul/Kconfig"
+source "drivers/usb/phy/Kconfig"
+
source "drivers/usb/ulpi/Kconfig"
comment "USB peripherals"
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index 1293e18..540c016 100644
--- a/drivers/usb/host/dwc2.c
+++ b/drivers/usb/host/dwc2.c
@@ -108,8 +108,8 @@
writel(DWC2_GRSTCTL_TXFFLSH | (num << DWC2_GRSTCTL_TXFNUM_OFFSET),
®s->grstctl);
- ret = wait_for_bit(__func__, ®s->grstctl, DWC2_GRSTCTL_TXFFLSH,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->grstctl, DWC2_GRSTCTL_TXFFLSH,
+ false, 1000, false);
if (ret)
printf("%s: Timeout!\n", __func__);
@@ -127,8 +127,8 @@
int ret;
writel(DWC2_GRSTCTL_RXFFLSH, ®s->grstctl);
- ret = wait_for_bit(__func__, ®s->grstctl, DWC2_GRSTCTL_RXFFLSH,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->grstctl, DWC2_GRSTCTL_RXFFLSH,
+ false, 1000, false);
if (ret)
printf("%s: Timeout!\n", __func__);
@@ -145,15 +145,15 @@
int ret;
/* Wait for AHB master IDLE state. */
- ret = wait_for_bit(__func__, ®s->grstctl, DWC2_GRSTCTL_AHBIDLE,
- true, 1000, false);
+ ret = wait_for_bit_le32(®s->grstctl, DWC2_GRSTCTL_AHBIDLE,
+ true, 1000, false);
if (ret)
printf("%s: Timeout!\n", __func__);
/* Core Soft Reset */
writel(DWC2_GRSTCTL_CSFTRST, ®s->grstctl);
- ret = wait_for_bit(__func__, ®s->grstctl, DWC2_GRSTCTL_CSFTRST,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->grstctl, DWC2_GRSTCTL_CSFTRST,
+ false, 1000, false);
if (ret)
printf("%s: Timeout!\n", __func__);
@@ -267,8 +267,8 @@
clrsetbits_le32(®s->hc_regs[i].hcchar,
DWC2_HCCHAR_EPDIR,
DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS);
- ret = wait_for_bit(__func__, ®s->hc_regs[i].hcchar,
- DWC2_HCCHAR_CHEN, false, 1000, false);
+ ret = wait_for_bit_le32(®s->hc_regs[i].hcchar,
+ DWC2_HCCHAR_CHEN, false, 1000, false);
if (ret)
printf("%s: Timeout!\n", __func__);
}
@@ -783,8 +783,8 @@
int ret;
uint32_t hcint, hctsiz;
- ret = wait_for_bit(__func__, &hc_regs->hcint, DWC2_HCINT_CHHLTD, true,
- 1000, false);
+ ret = wait_for_bit_le32(&hc_regs->hcint, DWC2_HCINT_CHHLTD, true,
+ 1000, false);
if (ret)
return ret;
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 2c0c633..f5320ca 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -133,8 +133,7 @@
setbits_le32(&ehci->usbcmd, CMD_RESET);
/* Wait for reset */
- if (wait_for_bit(__func__, &ehci->usbcmd, CMD_RESET, false, 30,
- false)) {
+ if (wait_for_bit_le32(&ehci->usbcmd, CMD_RESET, false, 30, false)) {
printf("Stuck on USB reset.\n");
return -ETIMEDOUT;
}
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index fe2627e..2c8fc3c 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -142,13 +142,12 @@
/* Stop then Reset */
clrbits_le32(usb_cmd, UCMD_RUN_STOP);
- ret = wait_for_bit(__func__, usb_cmd, UCMD_RUN_STOP, false, 10000,
- false);
+ ret = wait_for_bit_le32(usb_cmd, UCMD_RUN_STOP, false, 10000, false);
if (ret)
return ret;
setbits_le32(usb_cmd, UCMD_RESET);
- ret = wait_for_bit(__func__, usb_cmd, UCMD_RESET, false, 10000, false);
+ ret = wait_for_bit_le32(usb_cmd, UCMD_RESET, false, 10000, false);
if (ret)
return ret;
diff --git a/drivers/usb/host/ohci-lpc32xx.c b/drivers/usb/host/ohci-lpc32xx.c
index 2f2b4b9..44a4980 100644
--- a/drivers/usb/host/ohci-lpc32xx.c
+++ b/drivers/usb/host/ohci-lpc32xx.c
@@ -143,8 +143,8 @@
setbits_le32(&clk_pwr->usb_ctrl, CLK_USBCTRL_POSTDIV_2POW(0x01));
setbits_le32(&clk_pwr->usb_ctrl, CLK_USBCTRL_PLL_PWRUP);
- ret = wait_for_bit(__func__, &clk_pwr->usb_ctrl, CLK_USBCTRL_PLL_STS,
- true, CONFIG_SYS_HZ, false);
+ ret = wait_for_bit_le32(&clk_pwr->usb_ctrl, CLK_USBCTRL_PLL_STS,
+ true, CONFIG_SYS_HZ, false);
if (ret)
return ret;
@@ -178,8 +178,8 @@
/* enable I2C clock */
writel(OTG_CLK_I2C_EN, &otg->otg_clk_ctrl);
- ret = wait_for_bit(__func__, &otg->otg_clk_sts, OTG_CLK_I2C_EN, true,
- CONFIG_SYS_HZ, false);
+ ret = wait_for_bit_le32(&otg->otg_clk_sts, OTG_CLK_I2C_EN, true,
+ CONFIG_SYS_HZ, false);
if (ret)
return ret;
@@ -199,8 +199,8 @@
OTG_CLK_I2C_EN | OTG_CLK_HOST_EN;
writel(mask, &otg->otg_clk_ctrl);
- ret = wait_for_bit(__func__, &otg->otg_clk_sts, mask, true,
- CONFIG_SYS_HZ, false);
+ ret = wait_for_bit_le32(&otg->otg_clk_sts, mask, true,
+ CONFIG_SYS_HZ, false);
if (ret)
return ret;
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
index d47c996..71202d7 100644
--- a/drivers/usb/host/xhci-rcar.c
+++ b/drivers/usb/host/xhci-rcar.c
@@ -55,18 +55,18 @@
setbits_le32(regs + RCAR_USB3_DL_CTRL,
RCAR_USB3_DL_CTRL_FW_SET_DATA0);
- ret = wait_for_bit("xhci-rcar", regs + RCAR_USB3_DL_CTRL,
- RCAR_USB3_DL_CTRL_FW_SET_DATA0, false,
- 10, false);
+ ret = wait_for_bit_le32(regs + RCAR_USB3_DL_CTRL,
+ RCAR_USB3_DL_CTRL_FW_SET_DATA0, false,
+ 10, false);
if (ret)
break;
}
clrbits_le32(regs + RCAR_USB3_DL_CTRL, RCAR_USB3_DL_CTRL_ENABLE);
- ret = wait_for_bit("xhci-rcar", regs + RCAR_USB3_DL_CTRL,
- RCAR_USB3_DL_CTRL_FW_SUCCESS, true,
- 10, false);
+ ret = wait_for_bit_le32(regs + RCAR_USB3_DL_CTRL,
+ RCAR_USB3_DL_CTRL_FW_SUCCESS, true,
+ 10, false);
return ret;
}
diff --git a/drivers/usb/musb-new/Kconfig b/drivers/usb/musb-new/Kconfig
index caba42c..ea5bae2 100644
--- a/drivers/usb/musb-new/Kconfig
+++ b/drivers/usb/musb-new/Kconfig
@@ -23,6 +23,16 @@
speed USB controller based on the Mentor Graphics
silicon IP.
+config USB_MUSB_OMAP2PLUS
+ tristate "OMAP2430 and onwards"
+ depends on ARCH_OMAP2PLUS
+
+config USB_MUSB_AM35X
+ bool "AM35x"
+
+config USB_MUSB_DSPS
+ bool "TI DSPS platforms"
+
if USB_MUSB_HOST || USB_MUSB_GADGET
config USB_MUSB_PIC32
@@ -41,3 +51,10 @@
used on almost all sunxi boards.
endif
+
+config USB_MUSB_PIO_ONLY
+ bool "Disable DMA (always use PIO)"
+ default y if USB_MUSB_AM35X || USB_MUSB_PIC32 || USB_MUSB_OMAP2PLUS || USB_MUSB_DSPS || USB_MUSB_SUNXI
+ help
+ All data is copied between memory and FIFO by the CPU.
+ DMA controllers are ignored.
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
new file mode 100644
index 0000000..4e2be37
--- /dev/null
+++ b/drivers/usb/musb/Kconfig
@@ -0,0 +1,29 @@
+#
+# (C) Copyright 2017
+# Adam Ford, Logic PD, aford173@gmail.com
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+comment "Legacy MUSB Support"
+
+config USB_MUSB_HCD
+ bool "Legacy MUSB Host Controller"
+
+config USB_MUSB_UDC
+ bool "Legacy USB Device Controller"
+
+config USB_DAVINCI
+ bool "Legacy MUSB DaVinci"
+
+config USB_OMAP3
+ bool "Legacy MUSB OMAP3 / OMAP4"
+ depends on ARCH_OMAP2PLUS
+
+config USB_DA8XX
+ bool "Legacy MUSB DA8xx/OMAP-L1x"
+ depends on ARCH_DAVINCI
+
+config USB_AM35X
+ bool"Legacy MUSB AM35x"
+ depends on ARCH_OMAP2PLUS && !USB_OMAP3
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
new file mode 100644
index 0000000..bcc67a0
--- /dev/null
+++ b/drivers/usb/phy/Kconfig
@@ -0,0 +1,17 @@
+#
+# (C) Copyright 2017
+# Adam Ford, Logic PD, aford173@gmail.com
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+comment "USB Phy"
+
+config TWL4030_USB
+ bool "TWL4030 PHY"
+
+config OMAP_USB_PHY
+ bool "OMAP PHY"
+
+config ROCKCHIP_USB2_PHY
+ bool "Rockchip USB2 PHY"
diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c
index f77da2e..c0dd689 100644
--- a/drivers/video/atmel_hlcdfb.c
+++ b/drivers/video/atmel_hlcdfb.c
@@ -70,26 +70,26 @@
/* Disable DISP signal */
writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
+ false, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
/* Disable synchronization */
writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
+ false, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
/* Disable pixel clock */
writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
+ false, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
/* Disable PWM */
writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
+ false, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
@@ -215,26 +215,26 @@
/* Enable LCD */
value = readl(®s->lcdc_lcden);
writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
- true, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
+ true, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
value = readl(®s->lcdc_lcden);
writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
- true, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
+ true, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
value = readl(®s->lcdc_lcden);
writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
- true, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
+ true, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
value = readl(®s->lcdc_lcden);
writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
- true, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
+ true, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
@@ -299,26 +299,26 @@
/* Disable DISP signal */
writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
+ false, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
/* Disable synchronization */
writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
+ false, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
/* Disable pixel clock */
writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
+ false, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
/* Disable PWM */
writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
- false, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
+ false, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
@@ -451,26 +451,26 @@
/* Enable LCD */
value = readl(®s->lcdc_lcden);
writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
- true, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
+ true, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
value = readl(®s->lcdc_lcden);
writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
- true, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
+ true, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
value = readl(®s->lcdc_lcden);
writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
- true, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
+ true, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
value = readl(®s->lcdc_lcden);
writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden);
- ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
- true, 1000, false);
+ ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
+ true, 1000, false);
if (ret)
printf("%s: %d: Timeout!\n", __func__, __LINE__);
}
diff --git a/env/Kconfig b/env/Kconfig
index 692f863..a243707 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -74,13 +74,11 @@
config ENV_IS_IN_FAT
bool "Environment is in a FAT filesystem"
depends on !CHAIN_OF_TRUST
+ select FS_FAT
select FAT_WRITE
help
Define this if you want to use the FAT file system for the environment.
- - CONFIG_FAT_WRITE:
- This must be enabled. Otherwise it cannot save the environment file.
-
config ENV_IS_IN_EXT4
bool "Environment is in a EXT4 filesystem"
depends on !CHAIN_OF_TRUST
diff --git a/examples/api/Makefile b/examples/api/Makefile
index 8995272..9068727 100644
--- a/examples/api/Makefile
+++ b/examples/api/Makefile
@@ -4,6 +4,9 @@
# SPDX-License-Identifier: GPL-2.0+
#
+# Provide symbol API_BUILD to signal that the API example is being built.
+KBUILD_CPPFLAGS += -DAPI_BUILD
+
ifeq ($(ARCH),powerpc)
LOAD_ADDR = 0x40000
endif
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index e69de29..1a913d2 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -0,0 +1,13 @@
+config FS_EXT4
+ bool "Enable ext4 filesystem support"
+ help
+ This provides support for reading images from the ext4 filesystem.
+ ext4 is a widely used general-purpose filesystem for Linux.
+ You can also enable CMD_EXT4 to get access to ext4 commands.
+
+config EXT4_WRITE
+ bool "Enable ext4 filesystem write support"
+ depends on FS_EXT4
+ help
+ This provides support for creating and writing new files to an
+ existing ext4 filesystem partition.
diff --git a/fs/fat/Kconfig b/fs/fat/Kconfig
index e7978aa..9bb11ea 100644
--- a/fs/fat/Kconfig
+++ b/fs/fat/Kconfig
@@ -14,7 +14,7 @@
existing FAT filesystem partition.
config FS_FAT_MAX_CLUSTSIZE
- int "Set maximum possible clusersize"
+ int "Set maximum possible clustersize"
default 65536
depends on FS_FAT
help
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 1283818..dd7888c 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -22,12 +22,6 @@
#include <linux/compiler.h>
#include <linux/ctype.h>
-#ifdef CONFIG_SUPPORT_VFAT
-static const int vfat_enabled = 1;
-#else
-static const int vfat_enabled = 0;
-#endif
-
/*
* Convert a string to lowercase. Converts at most 'len' characters,
* 'len' may be larger than the length of 'str' if 'str' is NULL
@@ -605,9 +599,6 @@
return -1;
}
- if (vfat_enabled)
- debug("VFAT Support enabled\n");
-
debug("FAT%d, fat_sect: %d, fatlength: %d\n",
mydata->fatsize, mydata->fat_sect, mydata->fatlength);
debug("Rootdir begins at cluster: %d, sector: %d, offset: %x\n"
@@ -857,8 +848,7 @@
continue;
if (dent->attr & ATTR_VOLUME) {
- if (vfat_enabled &&
- (dent->attr & ATTR_VFAT) == ATTR_VFAT &&
+ if ((dent->attr & ATTR_VFAT) == ATTR_VFAT &&
(dent->name[0] & LAST_LONG_ENTRY_MASK)) {
dent = extract_vfat_name(itr);
if (!dent)
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index cd65192..2b753df 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -819,8 +819,7 @@
continue;
}
if ((dentptr->attr & ATTR_VOLUME)) {
- if (vfat_enabled &&
- (dentptr->attr & ATTR_VFAT) &&
+ if ((dentptr->attr & ATTR_VFAT) &&
(dentptr->name[0] & LAST_LONG_ENTRY_MASK)) {
get_long_file_name(mydata, curclust,
get_dentfromdir_block,
diff --git a/include/blk.h b/include/blk.h
index 41b4d7e..69b5a98 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -34,6 +34,7 @@
IF_TYPE_HOST,
IF_TYPE_SYSTEMACE,
IF_TYPE_NVME,
+ IF_TYPE_EFI,
IF_TYPE_COUNT, /* Number of interface types */
};
diff --git a/include/common.h b/include/common.h
index 4362000..0fe9439 100644
--- a/include/common.h
+++ b/include/common.h
@@ -364,6 +364,9 @@
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);
diff --git a/include/config_fallbacks.h b/include/config_fallbacks.h
index 2c4d43d..9695ee7 100644
--- a/include/config_fallbacks.h
+++ b/include/config_fallbacks.h
@@ -29,19 +29,6 @@
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
#endif
-#if defined(CONFIG_ENV_IS_IN_FAT) && !defined(CONFIG_FS_FAT)
-#define CONFIG_FS_FAT
-#endif
-
-#if (defined(CONFIG_CMD_EXT4) || defined(CONFIG_CMD_EXT2)) && \
- !defined(CONFIG_FS_EXT4)
-#define CONFIG_FS_EXT4
-#endif
-
-#if defined(CONFIG_CMD_EXT4_WRITE) && !defined(CONFIG_EXT4_WRITE)
-#define CONFIG_EXT4_WRITE
-#endif
-
/* Rather than repeat this expression each time, add a define for it */
#if defined(CONFIG_IDE) || \
defined(CONFIG_SATA) || \
@@ -52,6 +39,7 @@
defined(CONFIG_MMC) || \
defined(CONFIG_NVME) || \
defined(CONFIG_SYSTEMACE) || \
+ (defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)) || \
defined(CONFIG_SANDBOX)
#define HAVE_BLOCK_DEVICE
#endif
diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h
index c88aa95..e2807a6 100644
--- a/include/configs/MPC8349ITX.h
+++ b/include/configs/MPC8349ITX.h
@@ -470,14 +470,6 @@
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_HOSTNAME
-#if defined(CONFIG_COMPACT_FLASH) || defined(CONFIG_SATA_SIL3114) \
- || defined(CONFIG_USB_STORAGE)
- #define CONFIG_SUPPORT_VFAT
-#endif
-
-#if defined(CONFIG_SATA_SIL3114) || defined(CONFIG_USB_STORAGE)
-#endif
-
/* Watchdog */
#undef CONFIG_WATCHDOG /* watchdog disabled */
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index 856c546..31ab503 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -228,8 +228,6 @@
* add mass storage support and for gadget we add both RNDIS ethernet
* and DFU.
*/
-#define CONFIG_USB_MUSB_DSPS
-#define CONFIG_USB_MUSB_PIO_ONLY
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_PERIPHERAL
diff --git a/include/configs/am335x_shc.h b/include/configs/am335x_shc.h
index 32439f5..e2d329a 100644
--- a/include/configs/am335x_shc.h
+++ b/include/configs/am335x_shc.h
@@ -17,8 +17,6 @@
/* settings we don;t want on this board */
#undef CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC
-#undef CONFIG_CMD_EXT4
-#undef CONFIG_CMD_EXT4_WRITE
#undef CONFIG_CMD_SPI
#define CONFIG_CMD_CACHE
diff --git a/include/configs/am3517_crane.h b/include/configs/am3517_crane.h
index 400a06e..16212ef 100644
--- a/include/configs/am3517_crane.h
+++ b/include/configs/am3517_crane.h
@@ -72,8 +72,6 @@
* Enable CONFIG_USB_MUSB_HCD for Host functionalities MSC, keyboard
* Enable CONFIG_USB_MUSB_UDC for Device functionalities.
*/
-#define CONFIG_USB_AM35X 1
-#define CONFIG_USB_MUSB_HCD 1
#ifdef CONFIG_USB_AM35X
diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h
index 33ed85e..ac5070d 100644
--- a/include/configs/am3517_evm.h
+++ b/include/configs/am3517_evm.h
@@ -42,8 +42,6 @@
* Enable CONFIG_USB_MUSB_HOST for Host functionalities MSC, keyboard
* Enable CONFIG_USB_MUSB_GADGET for Device functionalities.
*/
-#define CONFIG_USB_MUSB_AM35X
-#define CONFIG_USB_MUSB_PIO_ONLY
#ifdef CONFIG_USB_MUSB_AM35X
diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h
index 302181b..77f8e76 100644
--- a/include/configs/am43xx_evm.h
+++ b/include/configs/am43xx_evm.h
@@ -77,7 +77,6 @@
#define CONFIG_SYS_USB_FAT_BOOT_PARTITION 1
#define CONFIG_USB_XHCI_OMAP
-#define CONFIG_OMAP_USB_PHY
#define CONFIG_AM437X_USB2PHY2_HOST
#endif
diff --git a/include/configs/am57xx_evm.h b/include/configs/am57xx_evm.h
index 28618a5..7546b3f 100644
--- a/include/configs/am57xx_evm.h
+++ b/include/configs/am57xx_evm.h
@@ -92,7 +92,6 @@
/* USB xHCI HOST */
#define CONFIG_USB_XHCI_OMAP
-#define CONFIG_OMAP_USB_PHY
#define CONFIG_OMAP_USB3PHY1_HOST
/* SATA */
diff --git a/include/configs/apf27.h b/include/configs/apf27.h
index 8294101..24afc84 100644
--- a/include/configs/apf27.h
+++ b/include/configs/apf27.h
@@ -204,7 +204,6 @@
*/
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
-#define CONFIG_SUPPORT_VFAT
/*
* Ethernet (on SOC imx FEC)
diff --git a/include/configs/baltos.h b/include/configs/baltos.h
index 3fc9e2f..939ee3b 100644
--- a/include/configs/baltos.h
+++ b/include/configs/baltos.h
@@ -272,8 +272,6 @@
* add mass storage support and for gadget we add both RNDIS ethernet
* and DFU.
*/
-#define CONFIG_USB_MUSB_DSPS
-#define CONFIG_USB_MUSB_PIO_ONLY
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_HOST
diff --git a/include/configs/bav335x.h b/include/configs/bav335x.h
index 8917bbe..d084af8 100644
--- a/include/configs/bav335x.h
+++ b/include/configs/bav335x.h
@@ -394,8 +394,6 @@
* add mass storage support and for gadget we add both RNDIS ethernet
* and DFU.
*/
-#define CONFIG_USB_MUSB_DSPS
-#define CONFIG_USB_MUSB_PIO_ONLY
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_PERIPHERAL
diff --git a/include/configs/bmips_bcm6318.h b/include/configs/bmips_bcm6318.h
new file mode 100644
index 0000000..454a7b7
--- /dev/null
+++ b/include/configs/bmips_bcm6318.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_BMIPS_BCM6318_H
+#define __CONFIG_BMIPS_BCM6318_H
+
+/* CPU */
+#define CONFIG_SYS_MIPS_TIMER_FREQ 166500000
+
+/* RAM */
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_SYS_SDRAM_BASE 0x80000000
+
+/* U-Boot */
+#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
+
+#if defined(CONFIG_BMIPS_BOOT_RAM)
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
+#endif
+
+#endif /* __CONFIG_BMIPS_BCM6318_H */
diff --git a/include/configs/bmips_bcm6368.h b/include/configs/bmips_bcm6368.h
new file mode 100644
index 0000000..ce35fae
--- /dev/null
+++ b/include/configs/bmips_bcm6368.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_BMIPS_BCM6368_H
+#define __CONFIG_BMIPS_BCM6368_H
+
+/* CPU */
+#define CONFIG_SYS_MIPS_TIMER_FREQ 200000000
+
+/* RAM */
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_SYS_SDRAM_BASE 0x80000000
+
+/* U-Boot */
+#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
+
+#if defined(CONFIG_BMIPS_BOOT_RAM)
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
+#endif
+
+#define CONFIG_SYS_FLASH_BASE 0xb8000000
+#define CONFIG_SYS_FLASH_EMPTY_INFO
+#define CONFIG_SYS_FLASH_PROTECTION
+#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 1
+
+#endif /* __CONFIG_BMIPS_BCM6368_H */
diff --git a/include/configs/brppt1.h b/include/configs/brppt1.h
index 2dadcae..a8022b8 100644
--- a/include/configs/brppt1.h
+++ b/include/configs/brppt1.h
@@ -210,8 +210,6 @@
#endif /* CONFIG_NAND */
/* USB configuration */
-#define CONFIG_USB_MUSB_DSPS
-#define CONFIG_USB_MUSB_PIO_ONLY
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_HOST
@@ -245,13 +243,5 @@
#else
#error "no storage for Environment defined!"
#endif
-/*
- * Common filesystems support. When we have removable storage we
- * enabled a number of useful commands and support.
- */
-#if defined(CONFIG_MMC) || defined(CONFIG_USB_STORAGE)
-#define CONFIG_FS_EXT4
-#define CONFIG_EXT4_WRITE
-#endif /* CONFIG_MMC, ... */
#endif /* ! __CONFIG_BRPPT1_H__ */
diff --git a/include/configs/brxre1.h b/include/configs/brxre1.h
index 8f92d7a..09042d4 100644
--- a/include/configs/brxre1.h
+++ b/include/configs/brxre1.h
@@ -80,8 +80,6 @@
#define CONFIG_INITRD_TAG
/* USB configuration */
-#define CONFIG_USB_MUSB_DSPS
-#define CONFIG_USB_MUSB_PIO_ONLY
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_HOST
diff --git a/include/configs/calimain.h b/include/configs/calimain.h
index 7686592..7dfc1fa 100644
--- a/include/configs/calimain.h
+++ b/include/configs/calimain.h
@@ -21,15 +21,12 @@
/*
* SoC Configuration
*/
-#define CONFIG_SOC_DA8XX /* TI DA8xx SoC */
-#define CONFIG_SOC_DA850 /* TI DA850 SoC */
#define CONFIG_SYS_EXCEPTION_VECTORS_HIGH
#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID)
#define CONFIG_SYS_OSCIN_FREQ calimain_get_osc_freq()
#define CONFIG_SYS_TIMERBASE DAVINCI_TIMER0_BASE
#define CONFIG_SYS_HZ_CLOCK clk_get(DAVINCI_AUXCLK_CLKID)
#define CONFIG_SYS_TEXT_BASE 0x60000000
-#define CONFIG_DA850_LOWLEVEL
#define CONFIG_ARCH_CPU_INIT
#define CONFIG_DA8XX_GPIO
#define CONFIG_HW_WATCHDOG
diff --git a/include/configs/chiliboard.h b/include/configs/chiliboard.h
index 92fd235..89740ba 100644
--- a/include/configs/chiliboard.h
+++ b/include/configs/chiliboard.h
@@ -152,9 +152,7 @@
/* NAND: SPL related configs */
/* USB configuration */
-#define CONFIG_USB_MUSB_DSPS
#define CONFIG_ARCH_MISC_INIT
-#define CONFIG_USB_MUSB_PIO_ONLY
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB1
#define CONFIG_AM335X_USB1_MODE MUSB_HOST
diff --git a/include/configs/cl-som-am57x.h b/include/configs/cl-som-am57x.h
index 6935b06..4f64672 100644
--- a/include/configs/cl-som-am57x.h
+++ b/include/configs/cl-som-am57x.h
@@ -77,7 +77,6 @@
/* USB xHCI HOST */
#define CONFIG_USB_XHCI_OMAP
-#define CONFIG_OMAP_USB_PHY
#define CONFIG_OMAP_USB3PHY1_HOST
/* USB Networking options */
diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h
index bf87bac..512c463 100644
--- a/include/configs/clearfog.h
+++ b/include/configs/clearfog.h
@@ -40,11 +40,6 @@
*/
#define CONFIG_SYS_MMC_BASE MVEBU_SDIO_BASE
-/* Partition support */
-
-/* Additional FS support/configuration */
-#define CONFIG_SUPPORT_VFAT
-
/* USB/EHCI configuration */
#define CONFIG_EHCI_IS_TDI
diff --git a/include/configs/cm_t35.h b/include/configs/cm_t35.h
index dc1b6b5..3c64cb5 100644
--- a/include/configs/cm_t35.h
+++ b/include/configs/cm_t35.h
@@ -71,11 +71,6 @@
#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
115200}
-/* USB */
-#define CONFIG_USB_OMAP3
-#define CONFIG_USB_MUSB_UDC
-#define CONFIG_TWL4030_USB
-
/* USB device configuration */
#define CONFIG_USB_DEVICE
#define CONFIG_USB_TTY
diff --git a/include/configs/cm_t3517.h b/include/configs/cm_t3517.h
index a472b9f..fe8b39a 100644
--- a/include/configs/cm_t3517.h
+++ b/include/configs/cm_t3517.h
@@ -78,14 +78,10 @@
115200}
/* USB */
-#define CONFIG_USB_MUSB_AM35X
#ifndef CONFIG_USB_MUSB_AM35X
-#define CONFIG_USB_OMAP3
#define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 146
#define CONFIG_OMAP_EHCI_PHY2_RESET_GPIO 147
-#else /* !CONFIG_USB_MUSB_AM35X */
-#define CONFIG_USB_MUSB_PIO_ONLY
#endif /* CONFIG_USB_MUSB_AM35X */
/* commands to include */
diff --git a/include/configs/cm_t43.h b/include/configs/cm_t43.h
index a222491..a564b86 100644
--- a/include/configs/cm_t43.h
+++ b/include/configs/cm_t43.h
@@ -55,7 +55,6 @@
/* USB support */
#define CONFIG_USB_XHCI_OMAP
-#define CONFIG_OMAP_USB_PHY
#define CONFIG_AM437X_USB2PHY2_HOST
/* SPI Flash support */
diff --git a/include/configs/comtrend_ar5315u.h b/include/configs/comtrend_ar5315u.h
new file mode 100644
index 0000000..3fda2d9
--- /dev/null
+++ b/include/configs/comtrend_ar5315u.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <configs/bmips_common.h>
+#include <configs/bmips_bcm6318.h>
+
+#define CONFIG_REMAKE_ELF
+
+#define CONFIG_ENV_SIZE (8 * 1024)
+
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_LONGHELP
diff --git a/include/configs/comtrend_wap5813n.h b/include/configs/comtrend_wap5813n.h
new file mode 100644
index 0000000..2eafb81
--- /dev/null
+++ b/include/configs/comtrend_wap5813n.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <configs/bmips_common.h>
+#include <configs/bmips_bcm6368.h>
+
+#define CONFIG_REMAKE_ELF
+
+#define CONFIG_ENV_SIZE (8 * 1024)
+
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_LONGHELP
+
+#define CONFIG_SYS_FLASH_CFI 1
+#define CONFIG_FLASH_CFI_DRIVER 1
diff --git a/include/configs/controlcenterdc.h b/include/configs/controlcenterdc.h
index a882fa6..bf324bb 100644
--- a/include/configs/controlcenterdc.h
+++ b/include/configs/controlcenterdc.h
@@ -54,9 +54,6 @@
#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
-/* Additional FS support/configuration */
-#define CONFIG_SUPPORT_VFAT
-
/* USB/EHCI configuration */
#define CONFIG_EHCI_IS_TDI
diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h
index 3ca5965..2a6916b 100644
--- a/include/configs/da850evm.h
+++ b/include/configs/da850evm.h
@@ -33,9 +33,6 @@
/*
* SoC Configuration
*/
-#define CONFIG_MACH_DAVINCI_DA850_EVM
-#define CONFIG_SOC_DA8XX /* TI DA8xx SoC */
-#define CONFIG_SOC_DA850 /* TI DA850 SoC */
#define CONFIG_SYS_EXCEPTION_VECTORS_HIGH
#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID)
#define CONFIG_SYS_OSCIN_FREQ 24000000
@@ -47,7 +44,6 @@
#define CONFIG_DA8XX_GPIO
#define CONFIG_SYS_TEXT_BASE 0x60000000
#define CONFIG_SYS_DV_NOR_BOOT_CFG (0x11)
-#define CONFIG_DA850_LOWLEVEL
#else
#define CONFIG_SYS_TEXT_BASE 0xc1080000
#endif
@@ -150,7 +146,6 @@
#define CONFIG_CONS_INDEX 1 /* use UART0 for console */
#define CONFIG_SPI
-#define CONFIG_DAVINCI_SPI
#define CONFIG_SYS_SPI_CLK clk_get(DAVINCI_SPI1_CLKID)
#ifdef CONFIG_SPL_BUILD
#define CONFIG_SYS_SPI_BASE DAVINCI_SPI1_BASE
diff --git a/include/configs/db-88f6720.h b/include/configs/db-88f6720.h
index cdaaced..67943ba 100644
--- a/include/configs/db-88f6720.h
+++ b/include/configs/db-88f6720.h
@@ -49,9 +49,6 @@
#define CONFIG_SYS_ALT_MEMTEST
-/* Additional FS support/configuration */
-#define CONFIG_SUPPORT_VFAT
-
/*
* mv-common.h should be defined after CMD configs since it used them
* to enable certain macros
diff --git a/include/configs/db-88f6820-amc.h b/include/configs/db-88f6820-amc.h
index b0e988d..69ec662 100644
--- a/include/configs/db-88f6820-amc.h
+++ b/include/configs/db-88f6820-amc.h
@@ -30,11 +30,6 @@
#define CONFIG_SF_DEFAULT_SPEED 1000000
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_3
-/* Partition support */
-
-/* Additional FS support/configuration */
-#define CONFIG_SUPPORT_VFAT
-
/* USB/EHCI configuration */
#define CONFIG_EHCI_IS_TDI
diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h
index 32f93f2..a3ab6ef 100644
--- a/include/configs/db-88f6820-gp.h
+++ b/include/configs/db-88f6820-gp.h
@@ -50,11 +50,6 @@
#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
-/* Partition support */
-
-/* Additional FS support/configuration */
-#define CONFIG_SUPPORT_VFAT
-
/* USB/EHCI configuration */
#define CONFIG_EHCI_IS_TDI
diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h
index 3dcc287..524a1ca 100644
--- a/include/configs/db-mv784mp-gp.h
+++ b/include/configs/db-mv784mp-gp.h
@@ -51,9 +51,6 @@
#define CONFIG_SYS_SATA_MAX_DEVICE 2
#define CONFIG_LBA48
-/* Additional FS support/configuration */
-#define CONFIG_SUPPORT_VFAT
-
/* PCIe support */
#ifndef CONFIG_SPL_BUILD
#define CONFIG_PCI_MVEBU
diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h
index f777d57..ff90b6d 100644
--- a/include/configs/dra7xx_evm.h
+++ b/include/configs/dra7xx_evm.h
@@ -144,7 +144,6 @@
/* USB xHCI HOST */
#define CONFIG_USB_XHCI_OMAP
-#define CONFIG_OMAP_USB_PHY
#define CONFIG_OMAP_USB2PHY2_HOST
/* SATA */
diff --git a/include/configs/dragonboard820c.h b/include/configs/dragonboard820c.h
index 010bc44..e28a956 100644
--- a/include/configs/dragonboard820c.h
+++ b/include/configs/dragonboard820c.h
@@ -60,7 +60,6 @@
"pxefile_addr_r=0x90100000\0"\
BOOTENV
-#define CONFIG_EXT4_WRITE
#define CONFIG_ENV_SIZE 0x4000
#define CONFIG_ENV_VARS_UBOOT_CONFIG
diff --git a/include/configs/ds414.h b/include/configs/ds414.h
index c201dbf..c840c93 100644
--- a/include/configs/ds414.h
+++ b/include/configs/ds414.h
@@ -68,7 +68,6 @@
#endif
/* why is this only defined in mv-common.h if CONFIG_DM is undefined? */
-#define CONFIG_SUPPORT_VFAT
#define CONFIG_SYS_MVFS
/*
diff --git a/include/configs/ea20.h b/include/configs/ea20.h
index c5e6e9e..efc72b3 100644
--- a/include/configs/ea20.h
+++ b/include/configs/ea20.h
@@ -24,9 +24,6 @@
/*
* SoC Configuration
*/
-#define CONFIG_MACH_DAVINCI_DA850_EVM
-#define CONFIG_SOC_DA8XX /* TI DA8xx SoC */
-#define CONFIG_SOC_DA850 /* TI DA850 SoC */
#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID)
#define CONFIG_SYS_OSCIN_FREQ 24000000
#define CONFIG_SYS_TIMERBASE DAVINCI_TIMER0_BASE
@@ -61,7 +58,6 @@
#define CONFIG_CONS_INDEX 1 /* use UART0 for console */
#define CONFIG_SPI
-#define CONFIG_DAVINCI_SPI
#define CONFIG_SYS_SPI_BASE DAVINCI_SPI1_BASE
#define CONFIG_SYS_SPI_CLK clk_get(DAVINCI_SPI1_CLKID)
#define CONFIG_SF_DEFAULT_SPEED 30000000
diff --git a/include/configs/eco5pk.h b/include/configs/eco5pk.h
index 9dbd7a2..a75932f 100644
--- a/include/configs/eco5pk.h
+++ b/include/configs/eco5pk.h
@@ -15,8 +15,6 @@
#include "tam3517-common.h"
-#undef CONFIG_USB_OMAP3
-
/* Our console port is port3 */
#undef CONFIG_CONS_INDEX
#undef CONFIG_SYS_NS16550_COM1
diff --git a/include/configs/edminiv2.h b/include/configs/edminiv2.h
index b77cfc5..167fcf2 100644
--- a/include/configs/edminiv2.h
+++ b/include/configs/edminiv2.h
@@ -165,7 +165,6 @@
*/
#ifdef CONFIG_CMD_USB
#define ORION5X_USB20_HOST_PORT_BASE ORION5X_USB20_PORT0_BASE
-#define CONFIG_SUPPORT_VFAT
#endif /* CONFIG_CMD_USB */
/*
diff --git a/include/configs/gplugd.h b/include/configs/gplugd.h
index dddd300..67f0672 100644
--- a/include/configs/gplugd.h
+++ b/include/configs/gplugd.h
@@ -85,6 +85,4 @@
#define CONFIG_EHCI_IS_TDI
#endif /* CONFIG_CMD_USB */
-#define CONFIG_SUPPORT_VFAT
-
#endif /* __CONFIG_GPLUGD_H */
diff --git a/include/configs/hikey.h b/include/configs/hikey.h
index 7eaa6e4..130c769 100644
--- a/include/configs/hikey.h
+++ b/include/configs/hikey.h
@@ -66,8 +66,6 @@
/* SD/MMC configuration */
#define CONFIG_BOUNCE_BUFFER
-#define CONFIG_FS_EXT4
-
/* Command line configuration */
#define CONFIG_MTD_PARTITIONS
diff --git a/include/configs/ipam390.h b/include/configs/ipam390.h
index 1683855..618bf72 100644
--- a/include/configs/ipam390.h
+++ b/include/configs/ipam390.h
@@ -24,9 +24,6 @@
/*
* SoC Configuration
*/
-#define CONFIG_MACH_DAVINCI_DA850_EVM
-#define CONFIG_SOC_DA8XX /* TI DA8xx SoC */
-#define CONFIG_SOC_DA850 /* TI DA850 SoC */
#define CONFIG_SYS_EXCEPTION_VECTORS_HIGH
#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID)
#define CONFIG_SYS_OSCIN_FREQ 24000000
diff --git a/include/configs/k2g_evm.h b/include/configs/k2g_evm.h
index 4e43104..f00ca1c 100644
--- a/include/configs/k2g_evm.h
+++ b/include/configs/k2g_evm.h
@@ -95,8 +95,6 @@
#ifndef CONFIG_SPL_BUILD
#define CONFIG_CADENCE_QSPI
#define CONFIG_CQSPI_REF_CLK 384000000
-#define CONFIG_CQSPI_DECODER 0x0
-#define CONFIG_BOUNCE_BUFFER
#endif
#define SPI_MTD_PARTS KEYSTONE_SPI1_MTD_PARTS
diff --git a/include/configs/kc1.h b/include/configs/kc1.h
index 8d8dc26..94c3d0a 100644
--- a/include/configs/kc1.h
+++ b/include/configs/kc1.h
@@ -115,9 +115,6 @@
* USB gadget
*/
-#define CONFIG_USB_MUSB_PIO_ONLY
-#define CONFIG_USB_MUSB_OMAP2PLUS
-
/*
* Environment
*/
diff --git a/include/configs/legoev3.h b/include/configs/legoev3.h
index c27373c..3439cbe 100644
--- a/include/configs/legoev3.h
+++ b/include/configs/legoev3.h
@@ -18,9 +18,6 @@
/*
* SoC Configuration
*/
-#define CONFIG_MACH_DAVINCI_DA850_EVM
-#define CONFIG_SOC_DA8XX /* TI DA8xx SoC */
-#define CONFIG_SOC_DA850 /* TI DA850 SoC */
#define CONFIG_SYS_EXCEPTION_VECTORS_HIGH
#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID)
#define CONFIG_SYS_OSCIN_FREQ 24000000
@@ -124,7 +121,6 @@
#define CONFIG_CONS_INDEX 1 /* use UART0 for console */
#define CONFIG_SPI
-#define CONFIG_DAVINCI_SPI
#define CONFIG_SYS_SPI_BASE DAVINCI_SPI0_BASE
#define CONFIG_SYS_SPI_CLK clk_get(DAVINCI_SPI0_CLKID)
#define CONFIG_SF_DEFAULT_SPEED 50000000
diff --git a/include/configs/ls1088aqds.h b/include/configs/ls1088aqds.h
index 8fbf890..5674a5d 100644
--- a/include/configs/ls1088aqds.h
+++ b/include/configs/ls1088aqds.h
@@ -170,9 +170,13 @@
#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 @@
#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
*/
diff --git a/include/configs/ls1088ardb.h b/include/configs/ls1088ardb.h
index d0066e3..a6271f5 100644
--- a/include/configs/ls1088ardb.h
+++ b/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
*/
diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index 7c2bab2..1721fef 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -116,13 +116,6 @@
#endif
/*
- * Common USB/EHCI configuration
- */
-#if defined(CONFIG_CMD_USB) && !defined(CONFIG_DM)
-#define CONFIG_SUPPORT_VFAT
-#endif /* CONFIG_CMD_USB */
-
-/*
* File system
*/
#ifdef CONFIG_SYS_MVFS
diff --git a/include/configs/mvebu_armada-37xx.h b/include/configs/mvebu_armada-37xx.h
index 9f2db09..5c53dd3 100644
--- a/include/configs/mvebu_armada-37xx.h
+++ b/include/configs/mvebu_armada-37xx.h
@@ -102,8 +102,6 @@
#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
-#define CONFIG_SUPPORT_VFAT
-
#include <config_distro_defaults.h>
#define BOOT_TARGET_DEVICES(func) \
diff --git a/include/configs/mvebu_armada-8k.h b/include/configs/mvebu_armada-8k.h
index 7f14316..86e0d43 100644
--- a/include/configs/mvebu_armada-8k.h
+++ b/include/configs/mvebu_armada-8k.h
@@ -105,8 +105,6 @@
#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
-#define CONFIG_SUPPORT_VFAT
-
/*
* PCI configuration
*/
diff --git a/include/configs/mx25pdk.h b/include/configs/mx25pdk.h
index 8e8946a..f82c4cc 100644
--- a/include/configs/mx25pdk.h
+++ b/include/configs/mx25pdk.h
@@ -65,11 +65,6 @@
#define CONFIG_CMDLINE_EDITING
#define CONFIG_SYS_LONGHELP
-/* U-Boot commands */
-
-/* Filesystem support */
-#define CONFIG_FS_EXT4
-
/* Ethernet */
#define CONFIG_FEC_MXC
#define CONFIG_FEC_MXC_PHYADDR 0x1f
diff --git a/include/configs/nas220.h b/include/configs/nas220.h
index 089263f..90be7bd 100644
--- a/include/configs/nas220.h
+++ b/include/configs/nas220.h
@@ -91,7 +91,6 @@
#ifdef CONFIG_CMD_USB
#define CONFIG_USB_EHCI_KIRKWOOD /* on Kirkwood platform */
#define CONFIG_EHCI_IS_TDI
-#define CONFIG_SUPPORT_VFAT
#endif /* CONFIG_CMD_USB */
/*
diff --git a/include/configs/nokia_rx51.h b/include/configs/nokia_rx51.h
index b7fe734..00509e8 100644
--- a/include/configs/nokia_rx51.h
+++ b/include/configs/nokia_rx51.h
@@ -82,12 +82,6 @@
#define CONFIG_ENV_OVERWRITE
#define CONFIG_SYS_BAUDRATE_TABLE { 4800, 9600, 19200, 38400, 57600, 115200 }
-/* USB */
-#define CONFIG_USB_MUSB_UDC
-#define CONFIG_USB_MUSB_HCD
-#define CONFIG_USB_OMAP3
-#define CONFIG_TWL4030_USB
-
/* USB device configuration */
#define CONFIG_USB_DEVICE
#define CONFIG_USBD_VENDORID 0x0421
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index 843e345..d3dfe60 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -62,9 +62,6 @@
/* MUSB */
#define CONFIG_USB_OMAP3
-#define CONFIG_USB_MUSB_OMAP2PLUS
-#define CONFIG_USB_MUSB_PIO_ONLY
-#define CONFIG_TWL4030_USB
/* USB EHCI */
#define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 147
diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h
index 3ecfdbb..ba67e33 100644
--- a/include/configs/omap3_evm.h
+++ b/include/configs/omap3_evm.h
@@ -74,9 +74,6 @@
#endif /* CONFIG_NAND */
/* MUSB */
-#define CONFIG_USB_OMAP3
-#define CONFIG_USB_MUSB_OMAP2PLUS
-#define CONFIG_USB_MUSB_PIO_ONLY
/* USB EHCI */
#define CONFIG_SYS_USB_FAT_BOOT_PARTITION 1
diff --git a/include/configs/omap3_igep00x0.h b/include/configs/omap3_igep00x0.h
index 91b3a23..76d8e13 100644
--- a/include/configs/omap3_igep00x0.h
+++ b/include/configs/omap3_igep00x0.h
@@ -41,11 +41,6 @@
#define GPIO_IGEP00X0_BOARD_DETECTION 28
#define GPIO_IGEP00X0_REVISION_DETECTION 129
-/* USB */
-#define CONFIG_USB_MUSB_UDC 1
-#define CONFIG_USB_OMAP3 1
-#define CONFIG_TWL4030_USB 1
-
/* USB device configuration */
#define CONFIG_USB_DEVICE 1
#define CONFIG_USB_TTY 1
diff --git a/include/configs/omap3_logic.h b/include/configs/omap3_logic.h
index b095814..70745a8 100644
--- a/include/configs/omap3_logic.h
+++ b/include/configs/omap3_logic.h
@@ -49,18 +49,9 @@
/* Hardware drivers */
-#define CONFIG_USB_OMAP3
-
/* I2C */
#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* EEPROM AT24C64 */
-/* USB */
-#define CONFIG_USB_MUSB_OMAP2PLUS
-#define CONFIG_USB_MUSB_PIO_ONLY
-
-/* TWL4030 */
-#define CONFIG_TWL4030_USB
-
/* Board NAND Info. */
#ifdef CONFIG_NAND
#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */
diff --git a/include/configs/omap3_zoom1.h b/include/configs/omap3_zoom1.h
index d1ff48d..cc7c2fd 100644
--- a/include/configs/omap3_zoom1.h
+++ b/include/configs/omap3_zoom1.h
@@ -34,11 +34,6 @@
* Hardware drivers
*/
-/* USB */
-#define CONFIG_USB_MUSB_UDC 1
-#define CONFIG_USB_OMAP3 1
-#define CONFIG_TWL4030_USB 1
-
/* USB device configuration */
#define CONFIG_USB_DEVICE 1
#define CONFIG_USB_TTY 1
diff --git a/include/configs/omapl138_lcdk.h b/include/configs/omapl138_lcdk.h
index 5dba7d2..2cb9911 100644
--- a/include/configs/omapl138_lcdk.h
+++ b/include/configs/omapl138_lcdk.h
@@ -24,7 +24,6 @@
*/
#define CONFIG_MACH_OMAPL138_LCDK
#define CONFIG_ARM926EJS /* arm926ejs CPU core */
-#define CONFIG_SOC_DA8XX /* TI DA8xx SoC */
#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID)
#define CONFIG_SYS_OSCIN_FREQ 24000000
#define CONFIG_SYS_TIMERBASE DAVINCI_TIMER0_BASE
@@ -129,7 +128,6 @@
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
#define CONFIG_SPI
-#define CONFIG_DAVINCI_SPI
#define CONFIG_SYS_SPI_BASE DAVINCI_SPI1_BASE
#define CONFIG_SYS_SPI_CLK clk_get(DAVINCI_SPI1_CLKID)
#define CONFIG_SF_DEFAULT_SPEED 30000000
diff --git a/include/configs/pcm051.h b/include/configs/pcm051.h
index 79f3f48..c6ff1e1 100644
--- a/include/configs/pcm051.h
+++ b/include/configs/pcm051.h
@@ -126,8 +126,6 @@
/*
* USB configuration
*/
-#define CONFIG_USB_MUSB_DSPS
-#define CONFIG_USB_MUSB_PIO_ONLY
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_PERIPHERAL
#define CONFIG_AM335X_USB1
diff --git a/include/configs/pengwyn.h b/include/configs/pengwyn.h
index 8afd64e..d9a50ca 100644
--- a/include/configs/pengwyn.h
+++ b/include/configs/pengwyn.h
@@ -162,8 +162,6 @@
* board schematic and physical port wired to each. Then for host we
* add mass storage support.
*/
-#define CONFIG_USB_MUSB_DSPS
-#define CONFIG_USB_MUSB_PIO_ONLY
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_PERIPHERAL
diff --git a/include/configs/pic32mzdask.h b/include/configs/pic32mzdask.h
index 97636fe..7a959c4 100644
--- a/include/configs/pic32mzdask.h
+++ b/include/configs/pic32mzdask.h
@@ -80,16 +80,6 @@
/*--------------------------------------------------
* USB Configuration
*/
-#define CONFIG_USB_MUSB_PIO_ONLY
-
-/*-----------------------------------------------------------------------
- * File System Configuration
- */
-/* FAT FS */
-#define CONFIG_SUPPORT_VFAT
-
-/* EXT4 FS */
-#define CONFIG_FS_EXT4
/* -------------------------------------------------
* Environment
diff --git a/include/configs/poplar.h b/include/configs/poplar.h
index 8a12b52..acdce29 100644
--- a/include/configs/poplar.h
+++ b/include/configs/poplar.h
@@ -66,7 +66,6 @@
#define CONFIG_SYS_MMC_ENV_DEV 0
#define CONFIG_ENV_OFFSET (0x780 * 512) /* env_mmc_blknum */
#define CONFIG_ENV_SIZE 0x10000 /* env_mmc_nblks bytes */
-#define CONFIG_FAT_WRITE
#define CONFIG_ENV_VARS_UBOOT_CONFIG
/* Monitor Command Prompt */
diff --git a/include/configs/rcar-gen2-common.h b/include/configs/rcar-gen2-common.h
index 2c10e61..d779297 100644
--- a/include/configs/rcar-gen2-common.h
+++ b/include/configs/rcar-gen2-common.h
@@ -11,11 +11,6 @@
#include <asm/arch/rmobile.h>
-/* Support File sytems */
-#define CONFIG_SUPPORT_VFAT
-#define CONFIG_FS_EXT4
-#define CONFIG_EXT4_WRITE
-
#define CONFIG_CMDLINE_TAG
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
index 30a98b8..e9e5fec 100644
--- a/include/configs/rcar-gen3-common.h
+++ b/include/configs/rcar-gen3-common.h
@@ -17,11 +17,6 @@
/* boot option */
#define CONFIG_SUPPORT_RAW_INITRD
-/* Support File sytems */
-#define CONFIG_SUPPORT_VFAT
-#define CONFIG_FS_EXT4
-#define CONFIG_EXT4_WRITE
-
#define CONFIG_CMDLINE_TAG
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
diff --git a/include/configs/rk3128_common.h b/include/configs/rk3128_common.h
index e915a56..8889046 100644
--- a/include/configs/rk3128_common.h
+++ b/include/configs/rk3128_common.h
@@ -30,9 +30,6 @@
/* MMC/SD IP block */
#define CONFIG_BOUNCE_BUFFER
-#define CONFIG_SUPPORT_VFAT
-#define CONFIG_FS_EXT4
-
/* RAW SD card / eMMC locations. */
#define CONFIG_SYS_SPI_U_BOOT_OFFS (128 << 10)
diff --git a/include/configs/rk3188_common.h b/include/configs/rk3188_common.h
index 0cb0762..9ab5502 100644
--- a/include/configs/rk3188_common.h
+++ b/include/configs/rk3188_common.h
@@ -58,7 +58,6 @@
#ifndef CONFIG_SPL_BUILD
/* usb otg */
-#define CONFIG_ROCKCHIP_USB2_PHY
/* usb host support */
#define ENV_MEM_LAYOUT_SETTINGS \
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index e2f070f..c2bd378 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -58,7 +58,6 @@
#ifndef CONFIG_SPL_BUILD
/* usb otg */
-#define CONFIG_ROCKCHIP_USB2_PHY
/* usb mass storage */
#define CONFIG_USB_FUNCTION_MASS_STORAGE
diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h
index af55632..eba5a22 100644
--- a/include/configs/rk3328_common.h
+++ b/include/configs/rk3328_common.h
@@ -24,9 +24,6 @@
/* MMC/SD IP block */
#define CONFIG_BOUNCE_BUFFER
-#define CONFIG_SUPPORT_VFAT
-#define CONFIG_FS_EXT4
-
/* RAW SD card / eMMC locations. */
#define CONFIG_SYS_SPI_U_BOOT_OFFS (128 << 10)
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index 561bfa7..95f544e 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -38,9 +38,6 @@
#define CONFIG_BOUNCE_BUFFER
#define CONFIG_ROCKCHIP_SDHCI_MAX_FREQ 200000000
-#define CONFIG_SUPPORT_VFAT
-#define CONFIG_FS_EXT4
-
/* RAW SD card / eMMC locations. */
#define CONFIG_SYS_SPI_U_BOOT_OFFS (128 << 10)
diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h
index 1aa1671..c31896d 100644
--- a/include/configs/s5p_goni.h
+++ b/include/configs/s5p_goni.h
@@ -187,11 +187,6 @@
#define CONFIG_SAMSUNG_ONENAND 1
#define CONFIG_SYS_ONENAND_BASE 0xB0000000
-/* write support for filesystems */
-#define CONFIG_EXT4_WRITE
-
-/* GPT */
-
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000)
#define CONFIG_USB_GADGET_DWC2_OTG_PHY
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index f042656..cfb3e7a 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -25,8 +25,6 @@
#define CONFIG_LMB
-#define CONFIG_FS_EXT4
-#define CONFIG_EXT4_WRITE
#define CONFIG_HOST_MAX_DEVICES 4
/*
diff --git a/include/configs/siemens-am33x-common.h b/include/configs/siemens-am33x-common.h
index 78708a2..85b6412 100644
--- a/include/configs/siemens-am33x-common.h
+++ b/include/configs/siemens-am33x-common.h
@@ -168,8 +168,6 @@
/*
* USB configuration
*/
-#define CONFIG_USB_MUSB_DSPS
-#define CONFIG_USB_MUSB_PIO_ONLY
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
diff --git a/include/configs/sniper.h b/include/configs/sniper.h
index 5809942..0ed72cf 100644
--- a/include/configs/sniper.h
+++ b/include/configs/sniper.h
@@ -110,14 +110,6 @@
115200 }
/*
- * USB gadget
- */
-
-#define CONFIG_USB_MUSB_PIO_ONLY
-#define CONFIG_USB_MUSB_OMAP2PLUS
-#define CONFIG_TWL4030_USB
-
-/*
* Environment
*/
diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h
index 66e7c4f..f6607b1 100644
--- a/include/configs/socfpga_common.h
+++ b/include/configs/socfpga_common.h
@@ -184,8 +184,6 @@
unsigned int cm_get_qspi_controller_clk_hz(void);
#define CONFIG_CQSPI_REF_CLK cm_get_qspi_controller_clk_hz()
#endif
-#define CONFIG_CQSPI_DECODER 0
-#define CONFIG_BOUNCE_BUFFER
/*
* Designware SPI support
diff --git a/include/configs/stv0991.h b/include/configs/stv0991.h
index c99fb67..beb8f1a 100644
--- a/include/configs/stv0991.h
+++ b/include/configs/stv0991.h
@@ -63,9 +63,7 @@
+ * QSPI support
+ */
#ifdef CONFIG_OF_CONTROL /* QSPI is controlled via DT */
-#define CONFIG_CQSPI_DECODER 0
#define CONFIG_CQSPI_REF_CLK ((30/4)/2)*1000*1000
-#define CONFIG_BOUNCE_BUFFER
#endif
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 6236e12..9b3944a 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -312,10 +312,6 @@
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1
#endif
-#ifdef CONFIG_USB_MUSB_SUNXI
-#define CONFIG_USB_MUSB_PIO_ONLY
-#endif
-
#ifdef CONFIG_USB_MUSB_GADGET
#define CONFIG_USB_FUNCTION_MASS_STORAGE
#endif
diff --git a/include/configs/tegra-common-post.h b/include/configs/tegra-common-post.h
index 743be6b..aea8f1f 100644
--- a/include/configs/tegra-common-post.h
+++ b/include/configs/tegra-common-post.h
@@ -113,11 +113,6 @@
#ifdef CONFIG_CMD_I2C
#endif
-/* remove partitions/filesystems */
-#ifdef CONFIG_FS_EXT4
-#undef CONFIG_FS_EXT4
-#endif
-
/* remove USB */
#ifdef CONFIG_USB_EHCI_TEGRA
#undef CONFIG_USB_EHCI_TEGRA
diff --git a/include/configs/theadorable.h b/include/configs/theadorable.h
index 6e95aa1..438abf1 100644
--- a/include/configs/theadorable.h
+++ b/include/configs/theadorable.h
@@ -67,9 +67,6 @@
#define CONFIG_SYS_SATA_MAX_DEVICE 1
#define CONFIG_LBA48
-/* Additional FS support/configuration */
-#define CONFIG_SUPPORT_VFAT
-
/* PCIe support */
#ifdef CONFIG_CMD_PCI
#ifndef CONFIG_SPL_BUILD
diff --git a/include/configs/ti_armv7_keystone2.h b/include/configs/ti_armv7_keystone2.h
index 7fb3aaf..bbed17a 100644
--- a/include/configs/ti_armv7_keystone2.h
+++ b/include/configs/ti_armv7_keystone2.h
@@ -78,7 +78,6 @@
#endif
/* SPI Configuration */
-#define CONFIG_DAVINCI_SPI
#define CONFIG_SYS_SPI_CLK ks_clk_get_rate(KS2_CLK1_6)
#define CONFIG_SF_DEFAULT_SPEED 30000000
#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
diff --git a/include/configs/ti_omap4_common.h b/include/configs/ti_omap4_common.h
index 91b2132..844a9e5 100644
--- a/include/configs/ti_omap4_common.h
+++ b/include/configs/ti_omap4_common.h
@@ -61,8 +61,6 @@
#endif
/* USB */
-#define CONFIG_USB_MUSB_UDC 1
-#define CONFIG_USB_OMAP3 1
/* USB device configuration */
#define CONFIG_USB_DEVICE 1
diff --git a/include/configs/turris_omnia.h b/include/configs/turris_omnia.h
index 3dbd2ca..40d94a2 100644
--- a/include/configs/turris_omnia.h
+++ b/include/configs/turris_omnia.h
@@ -59,9 +59,6 @@
#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
-/* Additional FS support/configuration */
-#define CONFIG_SUPPORT_VFAT
-
/* USB/EHCI configuration */
#define CONFIG_EHCI_IS_TDI
diff --git a/include/configs/vct.h b/include/configs/vct.h
index 00ad134..a5b5aaf 100644
--- a/include/configs/vct.h
+++ b/include/configs/vct.h
@@ -72,7 +72,6 @@
* Commands
*/
#if defined(CONFIG_CMD_USB)
-#define CONFIG_SUPPORT_VFAT
/*
* USB/EHCI
diff --git a/include/configs/x600.h b/include/configs/x600.h
index 7363057..4aa5a2a 100644
--- a/include/configs/x600.h
+++ b/include/configs/x600.h
@@ -96,10 +96,6 @@
#define CONFIG_USB_EHCI_SPEAR
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
-/* Filesystem support (for USB key) */
-#define CONFIG_SUPPORT_VFAT
-
-
/*
* U-Boot Environment placing definitions.
*/
diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h
index 064c546..994214e 100644
--- a/include/configs/x86-common.h
+++ b/include/configs/x86-common.h
@@ -58,8 +58,6 @@
#define CONFIG_CMDLINE_EDITING
#define CONFIG_AUTO_COMPLETE
-#define CONFIG_SUPPORT_VFAT
-
/*-----------------------------------------------------------------------
* Command line configuration.
*/
diff --git a/include/configs/zmx25.h b/include/configs/zmx25.h
index 1ae1ca4..f9783a2 100644
--- a/include/configs/zmx25.h
+++ b/include/configs/zmx25.h
@@ -82,7 +82,6 @@
#define CONFIG_MXC_USB_PORTSC MXC_EHCI_MODE_SERIAL
#define CONFIG_MXC_USB_FLAGS (MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN)
#define CONFIG_EHCI_IS_TDI
-#define CONFIG_SUPPORT_VFAT
#endif /* CONFIG_CMD_USB */
/* SDRAM */
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h
index b10cb3f..28cee15 100644
--- a/include/configs/zynq-common.h
+++ b/include/configs/zynq-common.h
@@ -124,10 +124,6 @@
# define DFU_ALT_INFO
#endif
-#if defined(CONFIG_MMC_SDHCI_ZYNQ) || defined(CONFIG_ZYNQ_USB)
-# define CONFIG_SUPPORT_VFAT
-#endif
-
#if defined(CONFIG_ZYNQ_I2C0) || defined(CONFIG_ZYNQ_I2C1)
#define CONFIG_SYS_I2C_ZYNQ
#endif
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 8b9932a..c359a60 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -652,4 +652,17 @@
ofnode_valid(node); \
node = ofnode_next_subnode(node))
+/**
+ * ofnode_translate_address() - Tranlate a device-tree address
+ *
+ * Translate an address from the device-tree into a CPU physical address. This
+ * function walks up the tree and applies the various bus mappings along the
+ * way.
+ *
+ * @ofnode: Device tree node giving the context in which to translate the
+ * address
+ * @in_addr: pointer to the address to translate
+ * @return the translated address; OF_BAD_ADDR on error
+ */
+u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr);
#endif
diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h
index 0eb4b92..c6c8f61 100644
--- a/include/dm/pinctrl.h
+++ b/include/dm/pinctrl.h
@@ -137,6 +137,12 @@
/**
* Generic pin configuration paramters
*
+ * enum pin_config_param - possible pin configuration parameters
+ * @PIN_CONFIG_BIAS_BUS_HOLD: the pin will be set to weakly latch so that it
+ * weakly drives the last value on a tristate bus, also known as a "bus
+ * holder", "bus keeper" or "repeater". This allows another device on the
+ * bus to change the value by driving the bus high or low and switching to
+ * tristate. The argument is ignored.
* @PIN_CONFIG_BIAS_DISABLE: disable any pin bias on the pin, a
* transition from say pull-up to pull-down implies that you disable
* pull-up in the process, this setting disables all biasing.
@@ -146,14 +152,6 @@
* if for example some other pin is going to drive the signal connected
* to it for a while. Pins used for input are usually always high
* impedance.
- * @PIN_CONFIG_BIAS_BUS_HOLD: the pin will be set to weakly latch so that it
- * weakly drives the last value on a tristate bus, also known as a "bus
- * holder", "bus keeper" or "repeater". This allows another device on the
- * bus to change the value by driving the bus high or low and switching to
- * tristate. The argument is ignored.
- * @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high
- * impedance to VDD). If the argument is != 0 pull-up is enabled,
- * if it is 0, pull-up is total, i.e. the pin is connected to VDD.
* @PIN_CONFIG_BIAS_PULL_DOWN: the pin will be pulled down (usually with high
* impedance to GROUND). If the argument is != 0 pull-down is enabled,
* if it is 0, pull-down is total, i.e. the pin is connected to GROUND.
@@ -165,10 +163,9 @@
* If the argument is != 0 pull up/down is enabled, if it is 0, the
* configuration is ignored. The proper way to disable it is to use
* @PIN_CONFIG_BIAS_DISABLE.
- * @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and
- * low, this is the most typical case and is typically achieved with two
- * active transistors on the output. Setting this config will enable
- * push-pull mode, the argument is ignored.
+ * @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high
+ * impedance to VDD). If the argument is != 0 pull-up is enabled,
+ * if it is 0, pull-up is total, i.e. the pin is connected to VDD.
* @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open
* collector) which means it is usually wired with other output ports
* which are then pulled up with an external resistor. Setting this
@@ -176,59 +173,82 @@
* @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source
* (open emitter). Setting this config will enable open source mode, the
* argument is ignored.
+ * @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and
+ * low, this is the most typical case and is typically achieved with two
+ * active transistors on the output. Setting this config will enable
+ * push-pull mode, the argument is ignored.
* @PIN_CONFIG_DRIVE_STRENGTH: the pin will sink or source at most the current
* passed as argument. The argument is in mA.
- * @PIN_CONFIG_INPUT_ENABLE: enable the pin's input. Note that this does not
- * affect the pin's ability to drive output. 1 enables input, 0 disables
- * input.
- * @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin.
- * If the argument != 0, schmitt-trigger mode is enabled. If it's 0,
- * schmitt-trigger mode is disabled.
- * @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in
- * schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis,
- * the threshold value is given on a custom format as argument when
- * setting pins to this mode.
* @PIN_CONFIG_INPUT_DEBOUNCE: this will configure the pin to debounce mode,
* which means it will wait for signals to settle when reading inputs. The
* argument gives the debounce time in usecs. Setting the
* argument to zero turns debouncing off.
- * @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power
- * supplies, the argument to this parameter (on a custom format) tells
- * the driver which alternative power source to use.
- * @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to
- * this parameter (on a custom format) tells the driver which alternative
- * slew rate to use.
+ * @PIN_CONFIG_INPUT_ENABLE: enable the pin's input. Note that this does not
+ * affect the pin's ability to drive output. 1 enables input, 0 disables
+ * input.
+ * @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in
+ * schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis,
+ * the threshold value is given on a custom format as argument when
+ * setting pins to this mode.
+ * @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin.
+ * If the argument != 0, schmitt-trigger mode is enabled. If it's 0,
+ * schmitt-trigger mode is disabled.
* @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power
* operation, if several modes of operation are supported these can be
* passed in the argument on a custom form, else just use argument 1
* to indicate low power mode, argument 0 turns low power mode off.
- * @PIN_CONFIG_OUTPUT: this will configure the pin as an output. Use argument
- * 1 to indicate high level, argument 0 to indicate low level. (Please
- * see Documentation/pinctrl.txt, section "GPIO mode pitfalls" for a
- * discussion around this parameter.)
+ * @PIN_CONFIG_OUTPUT_ENABLE: this will enable the pin's output mode
+ * without driving a value there. For most platforms this reduces to
+ * enable the output buffers and then let the pin controller current
+ * configuration (eg. the currently selected mux function) drive values on
+ * the line. Use argument 1 to enable output mode, argument 0 to disable
+ * it.
+ * @PIN_CONFIG_OUTPUT: this will configure the pin as an output and drive a
+ * value on the line. Use argument 1 to indicate high level, argument 0 to
+ * indicate low level. (Please see Documentation/driver-api/pinctl.rst,
+ * section "GPIO mode pitfalls" for a discussion around this parameter.)
+ * @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power
+ * supplies, the argument to this parameter (on a custom format) tells
+ * the driver which alternative power source to use.
+ * @PIN_CONFIG_SLEEP_HARDWARE_STATE: indicate this is sleep related state.
+ * @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to
+ * this parameter (on a custom format) tells the driver which alternative
+ * slew rate to use.
+ * @PIN_CONFIG_SKEW_DELAY: if the pin has programmable skew rate (on inputs)
+ * or latch delay (on outputs) this parameter (in a custom format)
+ * specifies the clock skew or latch delay. It typically controls how
+ * many double inverters are put in front of the line.
* @PIN_CONFIG_END: this is the last enumerator for pin configurations, if
* you need to pass in custom configurations to the pin controller, use
* PIN_CONFIG_END+1 as the base offset.
+ * @PIN_CONFIG_MAX: this is the maximum configuration value that can be
+ * presented using the packed format.
*/
-#define PIN_CONFIG_BIAS_DISABLE 0
-#define PIN_CONFIG_BIAS_HIGH_IMPEDANCE 1
-#define PIN_CONFIG_BIAS_BUS_HOLD 2
-#define PIN_CONFIG_BIAS_PULL_UP 3
-#define PIN_CONFIG_BIAS_PULL_DOWN 4
-#define PIN_CONFIG_BIAS_PULL_PIN_DEFAULT 5
-#define PIN_CONFIG_DRIVE_PUSH_PULL 6
-#define PIN_CONFIG_DRIVE_OPEN_DRAIN 7
-#define PIN_CONFIG_DRIVE_OPEN_SOURCE 8
-#define PIN_CONFIG_DRIVE_STRENGTH 9
-#define PIN_CONFIG_INPUT_ENABLE 10
-#define PIN_CONFIG_INPUT_SCHMITT_ENABLE 11
-#define PIN_CONFIG_INPUT_SCHMITT 12
-#define PIN_CONFIG_INPUT_DEBOUNCE 13
-#define PIN_CONFIG_POWER_SOURCE 14
-#define PIN_CONFIG_SLEW_RATE 15
-#define PIN_CONFIG_LOW_POWER_MODE 16
-#define PIN_CONFIG_OUTPUT 17
-#define PIN_CONFIG_END 0x7FFF
+enum pin_config_param {
+ PIN_CONFIG_BIAS_BUS_HOLD,
+ PIN_CONFIG_BIAS_DISABLE,
+ PIN_CONFIG_BIAS_HIGH_IMPEDANCE,
+ PIN_CONFIG_BIAS_PULL_DOWN,
+ PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
+ PIN_CONFIG_BIAS_PULL_UP,
+ PIN_CONFIG_DRIVE_OPEN_DRAIN,
+ PIN_CONFIG_DRIVE_OPEN_SOURCE,
+ PIN_CONFIG_DRIVE_PUSH_PULL,
+ PIN_CONFIG_DRIVE_STRENGTH,
+ PIN_CONFIG_INPUT_DEBOUNCE,
+ PIN_CONFIG_INPUT_ENABLE,
+ PIN_CONFIG_INPUT_SCHMITT,
+ PIN_CONFIG_INPUT_SCHMITT_ENABLE,
+ PIN_CONFIG_LOW_POWER_MODE,
+ PIN_CONFIG_OUTPUT_ENABLE,
+ PIN_CONFIG_OUTPUT,
+ PIN_CONFIG_POWER_SOURCE,
+ PIN_CONFIG_SLEEP_HARDWARE_STATE,
+ PIN_CONFIG_SLEW_RATE,
+ PIN_CONFIG_SKEW_DELAY,
+ PIN_CONFIG_END = 0x7F,
+ PIN_CONFIG_MAX = 0xFF,
+};
#if CONFIG_IS_ENABLED(PINCTRL_GENERIC)
/**
diff --git a/include/dm/read.h b/include/dm/read.h
index 8114037..f1f0dfd 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -46,6 +46,16 @@
#ifndef CONFIG_DM_DEV_READ_INLINE
/**
+ * dev_read_u32() - read a 32-bit integer from a device's DT property
+ *
+ * @dev: device to read DT property from
+ * @propname: name of the property to read from
+ * @outp: place to put value (if found)
+ * @return 0 if OK, -ve on error
+ */
+int dev_read_u32(struct udevice *dev, const char *propname, u32 *outp);
+
+/**
* dev_read_u32_default() - read a 32-bit integer from a device's DT property
*
* @dev: device to read DT property from
@@ -410,8 +420,26 @@
int dev_read_resource_byname(struct udevice *dev, const char *name,
struct resource *res);
+/**
+ * dev_translate_address() - Tranlate a device-tree address
+ *
+ * Translate an address from the device-tree into a CPU physical address. This
+ * function walks up the tree and applies the various bus mappings along the
+ * way.
+ *
+ * @dev: device giving the context in which to translate the address
+ * @in_addr: pointer to the address to translate
+ * @return the translated address; OF_BAD_ADDR on error
+ */
+u64 dev_translate_address(struct udevice *dev, const fdt32_t *in_addr);
#else /* CONFIG_DM_DEV_READ_INLINE is enabled */
+static inline int dev_read_u32(struct udevice *dev,
+ const char *propname, u32 *outp)
+{
+ return ofnode_read_u32(dev_ofnode(dev), propname, outp);
+}
+
static inline int dev_read_u32_default(struct udevice *dev,
const char *propname, int def)
{
@@ -582,6 +610,11 @@
return ofnode_read_resource_byname(dev_ofnode(dev), name, res);
}
+static inline u64 dev_translate_address(struct udevice *dev, const fdt32_t *in_addr)
+{
+ return ofnode_translate_address(dev_ofnode(dev), in_addr);
+}
+
#endif /* CONFIG_DM_DEV_READ_INLINE */
/**
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 3fc2083..07fabc3 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -34,6 +34,7 @@
UCLASS_CROS_EC, /* Chrome OS EC */
UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */
UCLASS_DMA, /* Direct Memory Access */
+ UCLASS_EFI, /* EFI managed devices */
UCLASS_ETH, /* Ethernet device */
UCLASS_GPIO, /* Bank of general-purpose I/O pins */
UCLASS_FIRMWARE, /* Firmware */
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index 1818849..709f661 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -72,11 +72,11 @@
* then this will be automatically allocated.
* @per_child_auto_alloc_size: Each child device (of a parent in this
* uclass) can hold parent data for the device/uclass. This value is only
- * used as a falback if this member is 0 in the driver.
+ * used as a fallback if this member is 0 in the driver.
* @per_child_platdata_auto_alloc_size: A bus likes to store information about
* its children. If non-zero this is the size of this data, to be allocated
* in the child device's parent_platdata pointer. This value is only used as
- * a falback if this member is 0 in the driver.
+ * a fallback if this member is 0 in the driver.
* @ops: Uclass operations, providing the consistent interface to devices
* within the uclass.
* @flags: Flags for this uclass (DM_UC_...)
diff --git a/include/dt-bindings/clock/bcm6318-clock.h b/include/dt-bindings/clock/bcm6318-clock.h
new file mode 100644
index 0000000..1e3dc16
--- /dev/null
+++ b/include/dt-bindings/clock/bcm6318-clock.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM6318_H
+#define __DT_BINDINGS_CLOCK_BCM6318_H
+
+#define BCM6318_CLK_ADSL_ASB 0
+#define BCM6318_CLK_USB_ASB 1
+#define BCM6318_CLK_MIPS_ASB 2
+#define BCM6318_CLK_PCIE_ASB 3
+#define BCM6318_CLK_PHYMIPS_ASB 4
+#define BCM6318_CLK_ROBOSW_ASB 5
+#define BCM6318_CLK_SAR_ASB 6
+#define BCM6318_CLK_SDR_ASB 7
+#define BCM6318_CLK_SWREG_ASB 8
+#define BCM6318_CLK_PERIPH_ASB 9
+#define BCM6318_CLK_CPUBUS160 10
+#define BCM6318_CLK_ADSL 11
+#define BCM6318_CLK_SAR125 12
+#define BCM6318_CLK_MIPS 13
+#define BCM6318_CLK_PCIE 14
+#define BCM6318_CLK_ROBOSW250 16
+#define BCM6318_CLK_ROBOSW025 17
+#define BCM6318_CLK_SDR 19
+#define BCM6318_CLK_USB 20
+#define BCM6318_CLK_HSSPI 25
+#define BCM6318_CLK_PCIE25 27
+#define BCM6318_CLK_PHYMIPS 28
+#define BCM6318_CLK_AFE 29
+#define BCM6318_CLK_QPROC 30
+
+#endif /* __DT_BINDINGS_CLOCK_BCM6318_H */
diff --git a/include/dt-bindings/clock/bcm6368-clock.h b/include/dt-bindings/clock/bcm6368-clock.h
new file mode 100644
index 0000000..9d41c0f
--- /dev/null
+++ b/include/dt-bindings/clock/bcm6368-clock.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM6368_H
+#define __DT_BINDINGS_CLOCK_BCM6368_H
+
+#define BCM6368_CLK_VDSL_QPROC 2
+#define BCM6368_CLK_VDSL_AFE 3
+#define BCM6368_CLK_VDSL_BONDING 4
+#define BCM6368_CLK_VDSL 5
+#define BCM6368_CLK_PHYMIPS 6
+#define BCM6368_CLK_SWPKT_USB 7
+#define BCM6368_CLK_SWPKT_SAR 8
+#define BCM6368_CLK_SPI 9
+#define BCM6368_CLK_USBD 10
+#define BCM6368_CLK_SAR 11
+#define BCM6368_CLK_ROBOSW 12
+#define BCM6368_CLK_UTOPIA 13
+#define BCM6368_CLK_PCM 14
+#define BCM6368_CLK_USBH 15
+#define BCM6368_CLK_GLESS 16
+#define BCM6368_CLK_NAND 17
+#define BCM6368_CLK_IPSEC 18
+#define BCM6368_CLK_USBH_IDDQ 19
+
+#endif /* __DT_BINDINGS_CLOCK_BCM6368_H */
diff --git a/include/dt-bindings/power-domain/bcm6318-power-domain.h b/include/dt-bindings/power-domain/bcm6318-power-domain.h
new file mode 100644
index 0000000..fb075d2
--- /dev/null
+++ b/include/dt-bindings/power-domain/bcm6318-power-domain.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_POWER_DOMAIN_BCM6318_H
+#define __DT_BINDINGS_POWER_DOMAIN_BCM6318_H
+
+#define BCM6318_PWR_PCIE 0
+#define BCM6318_PWR_USB 1
+
+#endif /* __DT_BINDINGS_POWER_DOMAIN_BCM6318_H */
diff --git a/include/dt-bindings/reset/bcm6318-reset.h b/include/dt-bindings/reset/bcm6318-reset.h
new file mode 100644
index 0000000..781d7fb
--- /dev/null
+++ b/include/dt-bindings/reset/bcm6318-reset.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_RESET_BCM6318_H
+#define __DT_BINDINGS_RESET_BCM6318_H
+
+#define BCM6318_RST_SPI 0
+#define BCM6318_RST_EPHY 1
+#define BCM6318_RST_SAR 2
+#define BCM6318_RST_ENETSW 3
+#define BCM6318_RST_USBD 4
+#define BCM6318_RST_USBH 5
+#define BCM6318_RST_PCIE_CORE 6
+#define BCM6318_RST_PCIE 7
+#define BCM6318_RST_PCIE_EXT 8
+#define BCM6318_RST_PCIE_HARD 9
+#define BCM6318_RST_ADSL 10
+#define BCM6318_RST_PHYMIPS 11
+#define BCM6318_RST_HOSTMIPS 11
+
+#endif /* __DT_BINDINGS_RESET_BCM6318_H */
diff --git a/include/dt-bindings/reset/bcm6368-reset.h b/include/dt-bindings/reset/bcm6368-reset.h
new file mode 100644
index 0000000..afa6a81
--- /dev/null
+++ b/include/dt-bindings/reset/bcm6368-reset.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_RESET_BCM6368_H
+#define __DT_BINDINGS_RESET_BCM6368_H
+
+#define BCM6368_RST_SPI 0
+#define BCM6368_RST_MPI 3
+#define BCM6368_RST_IPSEC 4
+#define BCM6368_RST_EPHY 6
+#define BCM6368_RST_SAR 7
+#define BCM6368_RST_SWITCH 10
+#define BCM6368_RST_USBD 11
+#define BCM6368_RST_USBH 12
+#define BCM6368_RST_PCM 13
+
+#endif /* __DT_BINDINGS_RESET_BCM6368_H */
diff --git a/include/efi_api.h b/include/efi_api.h
index 584016d..205f8f1 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -84,11 +84,12 @@
efi_status_t (EFIAPI *reinstall_protocol_interface)(
void *handle, const efi_guid_t *protocol,
void *old_interface, void *new_interface);
- efi_status_t (EFIAPI *uninstall_protocol_interface)(void *handle,
- const efi_guid_t *protocol, void *protocol_interface);
- efi_status_t (EFIAPI *handle_protocol)(efi_handle_t,
- const efi_guid_t *protocol,
- void **protocol_interface);
+ efi_status_t (EFIAPI *uninstall_protocol_interface)(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ void *protocol_interface);
+ efi_status_t (EFIAPI *handle_protocol)(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ void **protocol_interface);
void *reserved;
efi_status_t (EFIAPI *register_protocol_notify)(
const efi_guid_t *protocol, struct efi_event *event,
@@ -113,7 +114,7 @@
efi_status_t (EFIAPI *exit)(efi_handle_t handle,
efi_status_t exit_status,
unsigned long exitdata_size, s16 *exitdata);
- efi_status_t (EFIAPI *unload_image)(void *image_handle);
+ efi_status_t (EFIAPI *unload_image)(efi_handle_t image_handle);
efi_status_t (EFIAPI *exit_boot_services)(efi_handle_t, unsigned long);
efi_status_t (EFIAPI *get_next_monotonic_count)(u64 *count);
@@ -125,8 +126,10 @@
efi_handle_t *driver_image_handle,
struct efi_device_path *remaining_device_path,
bool recursive);
- efi_status_t (EFIAPI *disconnect_controller)(void *controller_handle,
- void *driver_image_handle, void *child_handle);
+ efi_status_t (EFIAPI *disconnect_controller)(
+ efi_handle_t controller_handle,
+ efi_handle_t driver_image_handle,
+ efi_handle_t child_handle);
#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
@@ -137,9 +140,10 @@
const efi_guid_t *protocol, void **interface,
efi_handle_t agent_handle,
efi_handle_t controller_handle, u32 attributes);
- efi_status_t (EFIAPI *close_protocol)(void *handle,
- const efi_guid_t *protocol, void *agent_handle,
- void *controller_handle);
+ efi_status_t (EFIAPI *close_protocol)(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ efi_handle_t agent_handle,
+ efi_handle_t controller_handle);
efi_status_t(EFIAPI *open_protocol_information)(efi_handle_t handle,
const efi_guid_t *protocol,
struct efi_open_protocol_info_entry **entry_buffer,
@@ -243,11 +247,11 @@
struct efi_table_hdr hdr;
unsigned long fw_vendor; /* physical addr of wchar_t vendor string */
u32 fw_revision;
- unsigned long con_in_handle;
+ efi_handle_t con_in_handle;
struct efi_simple_input_interface *con_in;
- unsigned long con_out_handle;
+ efi_handle_t con_out_handle;
struct efi_simple_text_output_protocol *con_out;
- unsigned long stderr_handle;
+ efi_handle_t stderr_handle;
struct efi_simple_text_output_protocol *std_err;
struct efi_runtime_services *runtime;
struct efi_boot_services *boottime;
@@ -329,12 +333,27 @@
} __packed;
#define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03
+# define DEVICE_PATH_SUB_TYPE_MSG_ATAPI 0x01
+# define DEVICE_PATH_SUB_TYPE_MSG_SCSI 0x02
# define DEVICE_PATH_SUB_TYPE_MSG_USB 0x05
# define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b
# define DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS 0x0f
# define DEVICE_PATH_SUB_TYPE_MSG_SD 0x1a
# define DEVICE_PATH_SUB_TYPE_MSG_MMC 0x1d
+struct efi_device_path_atapi {
+ struct efi_device_path dp;
+ u8 primary_secondary;
+ u8 slave_master;
+ u16 logical_unit_number;
+} __packed;
+
+struct efi_device_path_scsi {
+ struct efi_device_path dp;
+ u16 target_id;
+ u16 logical_unit_number;
+} __packed;
+
struct efi_device_path_usb {
struct efi_device_path dp;
u8 parent_port_number;
@@ -405,18 +424,26 @@
u32 io_align;
u8 pad2[4];
u64 last_block;
+ /* Added in revision 2 of the protocol */
+ u64 lowest_aligned_lba;
+ u32 logical_blocks_per_physical_block;
+ /* Added in revision 3 of the protocol */
+ u32 optimal_transfer_length_granualarity;
};
+#define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001
+#define EFI_BLOCK_IO_PROTOCOL_REVISION3 0x0002001f
+
struct efi_block_io {
u64 revision;
struct efi_block_io_media *media;
efi_status_t (EFIAPI *reset)(struct efi_block_io *this,
char extended_verification);
efi_status_t (EFIAPI *read_blocks)(struct efi_block_io *this,
- u32 media_id, u64 lba, unsigned long buffer_size,
+ u32 media_id, u64 lba, efi_uintn_t buffer_size,
void *buffer);
efi_status_t (EFIAPI *write_blocks)(struct efi_block_io *this,
- u32 media_id, u64 lba, unsigned long buffer_size,
+ u32 media_id, u64 lba, efi_uintn_t buffer_size,
void *buffer);
efi_status_t (EFIAPI *flush_blocks)(struct efi_block_io *this);
};
@@ -790,4 +817,26 @@
s16 file_name[0];
};
+#define EFI_DRIVER_BINDING_PROTOCOL_GUID \
+ EFI_GUID(0x18a031ab, 0xb443, 0x4d1a,\
+ 0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71)
+struct efi_driver_binding_protocol {
+ efi_status_t (EFIAPI * supported)(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path);
+ efi_status_t (EFIAPI * start)(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path);
+ efi_status_t (EFIAPI * stop)(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ efi_uintn_t number_of_children,
+ efi_handle_t *child_handle_buffer);
+ u32 version;
+ efi_handle_t image_handle;
+ efi_handle_t driver_binding_handle;
+};
+
#endif
diff --git a/include/efi_driver.h b/include/efi_driver.h
new file mode 100644
index 0000000..2bbe26c
--- /dev/null
+++ b/include/efi_driver.h
@@ -0,0 +1,30 @@
+/*
+ * EFI application loader
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _EFI_DRIVER_H
+#define _EFI_DRIVER_H 1
+
+#include <common.h>
+#include <dm.h>
+#include <efi_loader.h>
+
+struct efi_driver_ops {
+ const efi_guid_t *protocol;
+ const efi_guid_t *child_protocol;
+ int (*bind)(efi_handle_t handle, void *interface);
+};
+
+/*
+ * This structure adds internal fields to the driver binding protocol.
+ */
+struct efi_driver_binding_extended_protocol {
+ struct efi_driver_binding_protocol bp;
+ const struct efi_driver_ops *ops;
+};
+
+#endif /* _EFI_DRIVER_H */
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 6185055..21c03c5 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -69,10 +69,11 @@
} while(0)
/*
- * Write GUID
+ * Write an indented message with EFI prefix
*/
-#define EFI_PRINT_GUID(txt, guid) ({ \
- debug("%sEFI: %s %pUl\n", __efi_nesting(), txt, guid); \
+#define EFI_PRINT(format, ...) ({ \
+ debug("%sEFI: " format, __efi_nesting(), \
+ ##__VA_ARGS__); \
})
extern struct efi_runtime_services efi_runtime_services;
@@ -85,9 +86,13 @@
uint16_t *efi_dp_str(struct efi_device_path *dp);
+/* GUID of the EFI_BLOCK_IO_PROTOCOL */
+extern const efi_guid_t efi_block_io_guid;
extern const efi_guid_t efi_global_variable_guid;
extern const efi_guid_t efi_guid_console_control;
extern const efi_guid_t efi_guid_device_path;
+/* GUID of the EFI_DRIVER_BINDING_PROTOCOL */
+extern const efi_guid_t efi_guid_driver_binding_protocol;
extern const efi_guid_t efi_guid_loaded_image;
extern const efi_guid_t efi_guid_device_path_to_text_protocol;
extern const efi_guid_t efi_simple_file_system_protocol_guid;
@@ -97,14 +102,27 @@
extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
/*
+ * When a protocol is opened a open protocol info entry is created.
+ * These are maintained in a list.
+ */
+struct efi_open_protocol_info_item {
+ /* Link to the list of open protocol info entries of a protocol */
+ struct list_head link;
+ struct efi_open_protocol_info_entry info;
+};
+
+/*
* When the UEFI payload wants to open a protocol on an object to get its
* interface (usually a struct with callback functions), this struct maps the
- * protocol GUID to the respective protocol interface */
+ * protocol GUID to the respective protocol interface
+ */
struct efi_handler {
/* Link to the list of protocols of a handle */
struct list_head link;
const efi_guid_t *guid;
void *protocol_interface;
+ /* Link to the list of open protocol info items */
+ struct list_head open_infos;
};
/*
@@ -156,6 +174,10 @@
int efi_console_register(void);
/* Called by bootefi to make all disk storage accessible as EFI objects */
int efi_disk_register(void);
+/* Create handles and protocols for the partitions of a block device */
+int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
+ const char *if_typename, int diskid,
+ const char *pdevname);
/* Called by bootefi to make GOP (graphical) interface available */
int efi_gop_register(void);
/* Called by bootefi to make the network interface available */
@@ -189,23 +211,25 @@
/* Add a new object to the object list. */
void efi_add_handle(struct efi_object *obj);
/* Create handle */
-efi_status_t efi_create_handle(void **handle);
+efi_status_t efi_create_handle(efi_handle_t *handle);
/* Delete handle */
void efi_delete_handle(struct efi_object *obj);
/* Call this to validate a handle and find the EFI object for it */
-struct efi_object *efi_search_obj(const void *handle);
+struct efi_object *efi_search_obj(const efi_handle_t handle);
/* Find a protocol on a handle */
-efi_status_t efi_search_protocol(const void *handle,
+efi_status_t efi_search_protocol(const efi_handle_t handle,
const efi_guid_t *protocol_guid,
struct efi_handler **handler);
/* Install new protocol on a handle */
-efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol,
+efi_status_t efi_add_protocol(const efi_handle_t handle,
+ const efi_guid_t *protocol,
void *protocol_interface);
/* Delete protocol from a handle */
-efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol,
+efi_status_t efi_remove_protocol(const efi_handle_t handle,
+ const efi_guid_t *protocol,
void *protocol_interface);
/* Delete all protocols from a handle */
-efi_status_t efi_remove_all_protocols(const void *handle);
+efi_status_t efi_remove_all_protocols(const efi_handle_t handle);
/* Call this to create an event */
efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
void (EFIAPI *notify_function) (
@@ -216,7 +240,7 @@
efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
uint64_t trigger_time);
/* Call this to signal an event */
-void efi_signal_event(struct efi_event *event);
+void efi_signal_event(struct efi_event *event, bool check_tpl);
/* open file system: */
struct efi_simple_file_system_protocol *efi_simple_file_system(
@@ -247,6 +271,8 @@
/* Adds a range into the EFI memory map */
uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
bool overlap_only_ram);
+/* Called by board init to initialize the EFI drivers */
+int efi_driver_init(void);
/* Called by board init to initialize the EFI memory map */
int efi_memory_init(void);
/* Adds new or overrides configuration table entry to the system table */
@@ -280,15 +306,20 @@
struct efi_device_path *efi_dp_from_dev(struct udevice *dev);
struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
+/* Create a device node for a block device partition. */
+struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
const char *path);
struct efi_device_path *efi_dp_from_eth(void);
struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
uint64_t start_address,
uint64_t end_address);
-void efi_dp_split_file_path(struct efi_device_path *full_path,
- struct efi_device_path **device_path,
- struct efi_device_path **file_path);
+/* Determine the last device path node that is not the end node. */
+const struct efi_device_path *efi_dp_last_node(
+ const struct efi_device_path *dp);
+efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
+ struct efi_device_path **device_path,
+ struct efi_device_path **file_path);
#define EFI_DP_TYPE(_dp, _type, _subtype) \
(((_dp)->type == DEVICE_PATH_TYPE_##_type) && \
diff --git a/include/efi_selftest.h b/include/efi_selftest.h
index be5ba4b..08dd8e4 100644
--- a/include/efi_selftest.h
+++ b/include/efi_selftest.h
@@ -19,13 +19,19 @@
#define EFI_ST_FAILURE 1
/*
+ * Prints a message.
+ */
+#define efi_st_printf(...) \
+ (efi_st_printc(-1, __VA_ARGS__))
+
+/*
* Prints an error message.
*
* @... format string followed by fields to print
*/
#define efi_st_error(...) \
- (efi_st_printf("%s(%u):\nERROR: ", __FILE__, __LINE__), \
- efi_st_printf(__VA_ARGS__)) \
+ (efi_st_printc(EFI_LIGHTRED, "%s(%u):\nERROR: ", __FILE__, __LINE__), \
+ efi_st_printc(EFI_LIGHTRED, __VA_ARGS__))
/*
* Prints a TODO message.
@@ -33,8 +39,8 @@
* @... format string followed by fields to print
*/
#define efi_st_todo(...) \
- (efi_st_printf("%s(%u):\nTODO: ", __FILE__, __LINE__), \
- efi_st_printf(__VA_ARGS__)) \
+ (efi_st_printc(EFI_YELLOW, "%s(%u):\nTODO: ", __FILE__, __LINE__), \
+ efi_st_printc(EFI_YELLOW, __VA_ARGS__)) \
/*
* A test may be setup and executed at boottime,
@@ -61,14 +67,15 @@
void efi_st_exit_boot_services(void);
/*
- * Print a pointer to an u16 string
+ * Print a colored message
*
- * @pointer: pointer
- * @buf: pointer to buffer address
- * on return position of terminating zero word
+ * @color color, see constants in efi_api.h, use -1 for no color
+ * @fmt printf format
+ * @... arguments to be printed
+ * on return position of terminating zero word
*/
-void efi_st_printf(const char *fmt, ...)
- __attribute__ ((format (__printf__, 1, 2)));
+void efi_st_printc(int color, const char *fmt, ...)
+ __attribute__ ((format (__printf__, 2, 3)));
/*
* Compare memory.
diff --git a/include/fat.h b/include/fat.h
index bdeda95..fa95644 100644
--- a/include/fat.h
+++ b/include/fat.h
@@ -13,7 +13,6 @@
#include <asm/byteorder.h>
#include <fs.h>
-#define CONFIG_SUPPORT_VFAT
/* Maximum Long File Name length supported here is 128 UTF-16 code units */
#define VFAT_MAXLEN_BYTES 256 /* Maximum LFN buffer in bytes */
#define VFAT_MAXSEQ 9 /* Up to 9 of 13 2-byte UTF-16 entries */
diff --git a/include/power/s2mps11.h b/include/power/s2mps11.h
index 5da4719..22b38ff 100644
--- a/include/power/s2mps11.h
+++ b/include/power/s2mps11.h
@@ -106,4 +106,59 @@
#define S2MPS11_LDO26_ENABLE 0xec
+#define S2MPS11_LDO_NUM 26
+#define S2MPS11_BUCK_NUM 10
+
+/* Driver name */
+#define S2MPS11_BUCK_DRIVER "s2mps11_buck"
+#define S2MPS11_OF_BUCK_PREFIX "BUCK"
+#define S2MPS11_LDO_DRIVER "s2mps11_ldo"
+#define S2MPS11_OF_LDO_PREFIX "LDO"
+
+/* BUCK */
+#define S2MPS11_BUCK_VOLT_MASK 0xff
+#define S2MPS11_BUCK9_VOLT_MASK 0x1f
+
+#define S2MPS11_BUCK_LSTEP 6250
+#define S2MPS11_BUCK_HSTEP 12500
+#define S2MPS11_BUCK9_STEP 25000
+
+#define S2MPS11_BUCK_UV_MIN 600000
+#define S2MPS11_BUCK_UV_HMIN 750000
+#define S2MPS11_BUCK9_UV_MIN 1400000
+
+#define S2MPS11_BUCK_VOLT_MAX_HEX 0xA0
+#define S2MPS11_BUCK5_VOLT_MAX_HEX 0xDF
+#define S2MPS11_BUCK7_8_10_VOLT_MAX_HEX 0xDC
+#define S2MPS11_BUCK9_VOLT_MAX_HEX 0x5F
+
+#define S2MPS11_BUCK_MODE_SHIFT 6
+#define S2MPS11_BUCK_MODE_MASK (0x3)
+#define S2MPS11_BUCK_MODE_OFF (0x0 << 6)
+#define S2MPS11_BUCK_MODE_STANDBY (0x1 << 6)
+#define S2MPS11_BUCK_MODE_ON (0x3 << 6)
+
+/* LDO */
+#define S2MPS11_LDO_VOLT_MASK 0x3F
+#define S2MPS11_LDO_VOLT_MAX_HEX 0x3F
+
+#define S2MPS11_LDO_STEP 25000
+#define S2MPS11_LDO_UV_MIN 800000
+
+#define S2MPS11_LDO_MODE_MASK 0x3
+#define S2MPS11_LDO_MODE_SHIFT 6
+
+#define S2MPS11_LDO_MODE_OFF (0x0 << 6)
+#define S2MPS11_LDO_MODE_STANDBY (0x1 << 6)
+#define S2MPS11_LDO_MODE_STANDBY_LPM (0x2 << 6)
+#define S2MPS11_LDO_MODE_ON (0x3 << 6)
+
+enum {
+ OP_OFF = 0,
+ OP_LPM,
+ OP_STANDBY,
+ OP_STANDBY_LPM,
+ OP_ON,
+};
+
#endif
diff --git a/include/spi.h b/include/spi.h
index 08c7480..f5bac8d 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -86,8 +86,10 @@
* @cs: ID of the chip select connected to the slave.
* @mode: SPI mode to use for this slave (see SPI mode flags)
* @wordlen: Size of SPI word in number of bits
+ * @max_read_size: If non-zero, the maximum number of bytes which can
+ * be read at once.
* @max_write_size: If non-zero, the maximum number of bytes which can
- * be written at once, excluding command bytes.
+ * be written at once.
* @memory_map: Address of read-only SPI flash access.
* @flags: Indication of SPI flags.
*/
@@ -102,6 +104,7 @@
#endif
uint mode;
unsigned int wordlen;
+ unsigned int max_read_size;
unsigned int max_write_size;
void *memory_map;
@@ -314,33 +317,6 @@
return ret < 0 ? ret : din[1];
}
-/**
- * Set up a SPI slave for a particular device tree node
- *
- * This calls spi_setup_slave() with the correct bus number. Call
- * spi_free_slave() to free it later.
- *
- * @param blob: Device tree blob
- * @param slave_node: Slave node to use
- * @param spi_node: SPI peripheral node to use
- * @return pointer to new spi_slave structure
- */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
- int spi_node);
-
-/**
- * spi_base_setup_slave_fdt() - helper function to set up a SPI slace
- *
- * This decodes SPI properties from the slave node to determine the
- * chip select and SPI parameters.
- *
- * @blob: Device tree blob
- * @busnum: Bus number to use
- * @node: Device tree node for the SPI bus
- */
-struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
- int node);
-
#ifdef CONFIG_DM_SPI
/**
diff --git a/include/spi_flash.h b/include/spi_flash.h
index be2fe3f..f3c4e83 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -194,18 +194,6 @@
struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int spi_mode);
-/**
- * Set up a new SPI flash from an fdt node
- *
- * @param blob Device tree blob
- * @param slave_node Pointer to this SPI slave node in the device tree
- * @param spi_node Cached pointer to the SPI interface this node belongs
- * to
- * @return 0 if ok, -1 on error
- */
-struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
- int spi_node);
-
void spi_flash_free(struct spi_flash *flash);
static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
diff --git a/include/wait_bit.h b/include/wait_bit.h
index 06ad43a..bd021ba 100644
--- a/include/wait_bit.h
+++ b/include/wait_bit.h
@@ -16,7 +16,7 @@
#include <asm/io.h>
/**
- * wait_for_bit() waits for bit set/cleared in register
+ * wait_for_bit_x() waits for bit set/cleared in register
*
* Function polls register waiting for specific bit(s) change
* (either 0->1 or 1->0). It can fail under two conditions:
@@ -25,49 +25,60 @@
* Function succeeds only if all bits of masked register are set/cleared
* (depending on set option).
*
- * @param prefix Prefix added to timeout messagge (message visible only
- * with debug enabled)
- * @param reg Register that will be read (using readl())
+ * @param reg Register that will be read (using read_x())
* @param mask Bit(s) of register that must be active
* @param set Selects wait condition (bit set or clear)
- * @param timeout_ms Timeout (in miliseconds)
+ * @param timeout_ms Timeout (in milliseconds)
* @param breakable Enables CTRL-C interruption
* @return 0 on success, -ETIMEDOUT or -EINTR on failure
*/
-static inline int wait_for_bit(const char *prefix, const u32 *reg,
- const u32 mask, const bool set,
- const unsigned int timeout_ms,
- const bool breakable)
-{
- u32 val;
- unsigned long start = get_timer(0);
- while (1) {
- val = readl(reg);
-
- if (!set)
- val = ~val;
-
- if ((val & mask) == mask)
- return 0;
-
- if (get_timer(start) > timeout_ms)
- break;
-
- if (breakable && ctrlc()) {
- puts("Abort\n");
- return -EINTR;
- }
-
- udelay(1);
- WATCHDOG_RESET();
- }
-
- debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n", prefix, reg, mask,
- set);
-
- return -ETIMEDOUT;
+#define BUILD_WAIT_FOR_BIT(sfx, type, read) \
+ \
+static inline int wait_for_bit_##sfx(const void *reg, \
+ const type mask, \
+ const bool set, \
+ const unsigned int timeout_ms, \
+ const bool breakable) \
+{ \
+ type val; \
+ unsigned long start = get_timer(0); \
+ \
+ while (1) { \
+ val = read(reg); \
+ \
+ if (!set) \
+ val = ~val; \
+ \
+ if ((val & mask) == mask) \
+ return 0; \
+ \
+ if (get_timer(start) > timeout_ms) \
+ break; \
+ \
+ if (breakable && ctrlc()) { \
+ puts("Abort\n"); \
+ return -EINTR; \
+ } \
+ \
+ udelay(1); \
+ WATCHDOG_RESET(); \
+ } \
+ \
+ debug("%s: Timeout (reg=%p mask=%x wait_set=%i)\n", __func__, \
+ reg, mask, set); \
+ \
+ return -ETIMEDOUT; \
}
+BUILD_WAIT_FOR_BIT(8, u8, readb)
+BUILD_WAIT_FOR_BIT(le16, u16, readw)
+#ifdef readw_be
+BUILD_WAIT_FOR_BIT(be16, u16, readw_be)
+#endif
+BUILD_WAIT_FOR_BIT(le32, u32, readl)
+#ifdef readl_be
+BUILD_WAIT_FOR_BIT(be32, u32, readl_be)
+#endif
#endif
diff --git a/lib/Makefile b/lib/Makefile
index 8cd779f..0db41c1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -8,6 +8,7 @@
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_EFI) += efi/
+obj-$(CONFIG_EFI_LOADER) += efi_driver/
obj-$(CONFIG_EFI_LOADER) += efi_loader/
obj-$(CONFIG_EFI_LOADER) += efi_selftest/
obj-$(CONFIG_LZMA) += lzma/
diff --git a/lib/efi_driver/Makefile b/lib/efi_driver/Makefile
new file mode 100644
index 0000000..e35529a
--- /dev/null
+++ b/lib/efi_driver/Makefile
@@ -0,0 +1,13 @@
+#
+# (C) Copyright 2017 Heinrich Schuchardt
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+# This file only gets included with CONFIG_EFI_LOADER set, so all
+# object inclusion implicitly depends on it
+
+obj-y += efi_uclass.o
+ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy)
+obj-y += efi_block_device.o
+endif
diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c
new file mode 100644
index 0000000..d9d2b14
--- /dev/null
+++ b/lib/efi_driver/efi_block_device.c
@@ -0,0 +1,210 @@
+/*
+ * EFI block driver
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * The EFI uclass creates a handle for this driver and installs the
+ * driver binding protocol on it.
+ *
+ * The EFI block driver binds to controllers implementing the block io
+ * protocol.
+ *
+ * When the bind function of the EFI block driver is called it creates a
+ * new U-Boot block device. It installs child handles for all partitions and
+ * installs the simple file protocol on these.
+ *
+ * The read and write functions of the EFI block driver delegate calls to the
+ * controller that it is bound to.
+ *
+ * A usage example is as following:
+ *
+ * U-Boot loads the iPXE snp.efi executable. iPXE connects an iSCSI drive and
+ * exposes a handle with the block IO protocol. It calls ConnectController.
+ *
+ * Now the EFI block driver installs the partitions with the simple file
+ * protocol.
+ *
+ * iPXE uses the simple file protocol to load Grub or the Linux Kernel.
+ */
+
+#include <efi_driver.h>
+#include <dm/device-internal.h>
+#include <dm/root.h>
+
+/*
+ * EFI attributes of the udevice handled by this driver.
+ *
+ * handle handle of the controller on which this driver is installed
+ * io block io protocol proxied by this driver
+ */
+struct efi_blk_priv {
+ efi_handle_t handle;
+ struct efi_block_io *io;
+};
+
+/*
+ * Read from block device
+ *
+ * @dev device
+ * @blknr first block to be read
+ * @blkcnt number of blocks to read
+ * @buffer output buffer
+ * @return number of blocks transferred
+ */
+static ulong efi_bl_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+ void *buffer)
+{
+ struct efi_blk_priv *priv = dev->priv;
+ struct efi_block_io *io = priv->io;
+ efi_status_t ret;
+
+ EFI_PRINT("%s: read '%s', from block " LBAFU ", " LBAFU " blocks\n",
+ __func__, dev->name, blknr, blkcnt);
+ ret = EFI_CALL(io->read_blocks(
+ io, io->media->media_id, (u64)blknr,
+ (efi_uintn_t)blkcnt *
+ (efi_uintn_t)io->media->block_size, buffer));
+ EFI_PRINT("%s: r = %u\n", __func__,
+ (unsigned int)(ret & ~EFI_ERROR_MASK));
+ if (ret != EFI_SUCCESS)
+ return 0;
+ return blkcnt;
+}
+
+/*
+ * Write to block device
+ *
+ * @dev device
+ * @blknr first block to be write
+ * @blkcnt number of blocks to write
+ * @buffer input buffer
+ * @return number of blocks transferred
+ */
+static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+ const void *buffer)
+{
+ struct efi_blk_priv *priv = dev->priv;
+ struct efi_block_io *io = priv->io;
+ efi_status_t ret;
+
+ EFI_PRINT("%s: write '%s', from block " LBAFU ", " LBAFU " blocks\n",
+ __func__, dev->name, blknr, blkcnt);
+ ret = EFI_CALL(io->write_blocks(
+ io, io->media->media_id, (u64)blknr,
+ (efi_uintn_t)blkcnt *
+ (efi_uintn_t)io->media->block_size,
+ (void *)buffer));
+ EFI_PRINT("%s: r = %u\n", __func__,
+ (unsigned int)(ret & ~EFI_ERROR_MASK));
+ if (ret != EFI_SUCCESS)
+ return 0;
+ return blkcnt;
+}
+
+/*
+ * Create partions for the block device.
+ *
+ * @handle EFI handle of the block device
+ * @dev udevice of the block device
+ */
+static int efi_bl_bind_partitions(efi_handle_t handle, struct udevice *dev)
+{
+ struct blk_desc *desc;
+ const char *if_typename;
+
+ desc = dev_get_uclass_platdata(dev);
+ if_typename = blk_get_if_type_name(desc->if_type);
+
+ return efi_disk_create_partitions(handle, desc, if_typename,
+ desc->devnum, dev->name);
+}
+
+/*
+ * Create a block device for a handle
+ *
+ * @handle handle
+ * @interface block io protocol
+ * @return 0 = success
+ */
+static int efi_bl_bind(efi_handle_t handle, void *interface)
+{
+ struct udevice *bdev, *parent = dm_root();
+ int ret, devnum;
+ char *name;
+ struct efi_object *obj = efi_search_obj(handle);
+ struct efi_block_io *io = interface;
+ int disks;
+ struct efi_blk_priv *priv;
+
+ EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io);
+
+ if (!obj)
+ return -ENOENT;
+
+ devnum = blk_find_max_devnum(IF_TYPE_EFI);
+ if (devnum == -ENODEV)
+ devnum = 0;
+ else if (devnum < 0)
+ return devnum;
+
+ name = calloc(1, 18); /* strlen("efiblk#2147483648") + 1 */
+ if (!name)
+ return -ENOMEM;
+ sprintf(name, "efiblk#%d", devnum);
+
+ /* Create driver model udevice for the EFI block io device */
+ ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI, devnum,
+ io->media->block_size,
+ (lbaint_t)io->media->last_block, &bdev);
+ if (ret)
+ return ret;
+ if (!bdev)
+ return -ENOENT;
+ /* Allocate priv */
+ ret = device_probe(bdev);
+ if (ret)
+ return ret;
+ EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name);
+
+ priv = bdev->priv;
+ priv->handle = handle;
+ priv->io = interface;
+
+ ret = blk_prepare_device(bdev);
+
+ /* Create handles for the partions of the block device */
+ disks = efi_bl_bind_partitions(handle, bdev);
+ EFI_PRINT("Found %d partitions\n", disks);
+
+ return 0;
+}
+
+/* Block device driver operators */
+static const struct blk_ops efi_blk_ops = {
+ .read = efi_bl_read,
+ .write = efi_bl_write,
+};
+
+/* Identify as block device driver */
+U_BOOT_DRIVER(efi_blk) = {
+ .name = "efi_blk",
+ .id = UCLASS_BLK,
+ .ops = &efi_blk_ops,
+ .priv_auto_alloc_size = sizeof(struct efi_blk_priv),
+};
+
+/* EFI driver operators */
+static const struct efi_driver_ops driver_ops = {
+ .protocol = &efi_block_io_guid,
+ .child_protocol = &efi_block_io_guid,
+ .bind = efi_bl_bind,
+};
+
+/* Identify as EFI driver */
+U_BOOT_DRIVER(efi_block) = {
+ .name = "EFI block driver",
+ .id = UCLASS_EFI,
+ .ops = &driver_ops,
+};
diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c
new file mode 100644
index 0000000..90797f9
--- /dev/null
+++ b/lib/efi_driver/efi_uclass.c
@@ -0,0 +1,330 @@
+/*
+ * Uclass for EFI drivers
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * For each EFI driver the uclass
+ * - creates a handle
+ * - installs the driver binding protocol
+ *
+ * The uclass provides the bind, start, and stop entry points for the driver
+ * binding protocol.
+ *
+ * In bind() and stop() it checks if the controller implements the protocol
+ * supported by the EFI driver. In the start() function it calls the bind()
+ * function of the EFI driver. In the stop() function it destroys the child
+ * controllers.
+ */
+
+#include <efi_driver.h>
+
+/*
+ * Check node type. We do not support partitions as controller handles.
+ *
+ * @handle handle to be checked
+ * @return status code
+ */
+static efi_status_t check_node_type(efi_handle_t handle)
+{
+ efi_status_t r, ret = EFI_SUCCESS;
+ const struct efi_device_path *dp;
+
+ /* Open the device path protocol */
+ r = EFI_CALL(systab.boottime->open_protocol(
+ handle, &efi_guid_device_path, (void **)&dp,
+ NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL));
+ if (r == EFI_SUCCESS && dp) {
+ /* Get the last node */
+ const struct efi_device_path *node = efi_dp_last_node(dp);
+ /* We do not support partitions as controller */
+ if (!node || node->type == DEVICE_PATH_TYPE_MEDIA_DEVICE)
+ ret = EFI_UNSUPPORTED;
+ }
+ return ret;
+}
+
+/*
+ * Check if the driver supports the controller.
+ *
+ * @this driver binding protocol
+ * @controller_handle handle of the controller
+ * @remaining_device_path path specifying the child controller
+ * @return status code
+ */
+static efi_status_t EFIAPI efi_uc_supported(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path)
+{
+ efi_status_t r, ret;
+ void *interface;
+ struct efi_driver_binding_extended_protocol *bp =
+ (struct efi_driver_binding_extended_protocol *)this;
+
+ EFI_ENTRY("%p, %p, %ls", this, controller_handle,
+ efi_dp_str(remaining_device_path));
+
+ ret = EFI_CALL(systab.boottime->open_protocol(
+ controller_handle, bp->ops->protocol,
+ &interface, this->driver_binding_handle,
+ controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER));
+ switch (ret) {
+ case EFI_ACCESS_DENIED:
+ case EFI_ALREADY_STARTED:
+ goto out;
+ case EFI_SUCCESS:
+ break;
+ default:
+ ret = EFI_UNSUPPORTED;
+ goto out;
+ }
+
+ ret = check_node_type(controller_handle);
+
+ r = EFI_CALL(systab.boottime->close_protocol(
+ controller_handle, bp->ops->protocol,
+ this->driver_binding_handle,
+ controller_handle));
+ if (r != EFI_SUCCESS)
+ ret = EFI_UNSUPPORTED;
+out:
+ return EFI_EXIT(ret);
+}
+
+/*
+ * Create child controllers and attach driver.
+ *
+ * @this driver binding protocol
+ * @controller_handle handle of the controller
+ * @remaining_device_path path specifying the child controller
+ * @return status code
+ */
+static efi_status_t EFIAPI efi_uc_start(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path)
+{
+ efi_status_t r, ret;
+ void *interface = NULL;
+ struct efi_driver_binding_extended_protocol *bp =
+ (struct efi_driver_binding_extended_protocol *)this;
+
+ EFI_ENTRY("%p, %pUl, %ls", this, controller_handle,
+ efi_dp_str(remaining_device_path));
+
+ /* Attach driver to controller */
+ ret = EFI_CALL(systab.boottime->open_protocol(
+ controller_handle, bp->ops->protocol,
+ &interface, this->driver_binding_handle,
+ controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER));
+ switch (ret) {
+ case EFI_ACCESS_DENIED:
+ case EFI_ALREADY_STARTED:
+ goto out;
+ case EFI_SUCCESS:
+ break;
+ default:
+ ret = EFI_UNSUPPORTED;
+ goto out;
+ }
+ ret = check_node_type(controller_handle);
+ if (ret != EFI_SUCCESS) {
+ r = EFI_CALL(systab.boottime->close_protocol(
+ controller_handle, bp->ops->protocol,
+ this->driver_binding_handle,
+ controller_handle));
+ if (r != EFI_SUCCESS)
+ EFI_PRINT("Failure to close handle\n");
+ goto out;
+ }
+
+ /* TODO: driver specific stuff */
+ bp->ops->bind(controller_handle, interface);
+
+out:
+ return EFI_EXIT(ret);
+}
+
+/*
+ * Remove a single child controller from the parent controller.
+ *
+ * @controller_handle parent controller
+ * @child_handle child controller
+ * @return status code
+ */
+static efi_status_t disconnect_child(efi_handle_t controller_handle,
+ efi_handle_t child_handle)
+{
+ efi_status_t ret;
+ efi_guid_t *guid_controller = NULL;
+ efi_guid_t *guid_child_controller = NULL;
+
+ ret = EFI_CALL(systab.boottime->close_protocol(
+ controller_handle, guid_controller,
+ child_handle, child_handle));
+ if (ret != EFI_SUCCESS) {
+ EFI_PRINT("Cannot close protocol\n");
+ return ret;
+ }
+ ret = EFI_CALL(systab.boottime->uninstall_protocol_interface(
+ child_handle, guid_child_controller, NULL));
+ if (ret != EFI_SUCCESS) {
+ EFI_PRINT("Cannot uninstall protocol interface\n");
+ return ret;
+ }
+ return ret;
+}
+
+/*
+ * Remove child controllers and disconnect the controller.
+ *
+ * @this driver binding protocol
+ * @controller_handle handle of the controller
+ * @number_of_children number of child controllers to remove
+ * @child_handle_buffer handles of the child controllers to remove
+ * @return status code
+ */
+static efi_status_t EFIAPI efi_uc_stop(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ size_t number_of_children,
+ efi_handle_t *child_handle_buffer)
+{
+ efi_status_t ret;
+ efi_uintn_t count;
+ struct efi_open_protocol_info_entry *entry_buffer;
+ efi_guid_t *guid_controller = NULL;
+
+ EFI_ENTRY("%p, %pUl, %zu, %p", this, controller_handle,
+ number_of_children, child_handle_buffer);
+
+ /* Destroy provided child controllers */
+ if (number_of_children) {
+ efi_uintn_t i;
+
+ for (i = 0; i < number_of_children; ++i) {
+ ret = disconnect_child(controller_handle,
+ child_handle_buffer[i]);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ }
+ return EFI_SUCCESS;
+ }
+
+ /* Destroy all children */
+ ret = EFI_CALL(systab.boottime->open_protocol_information(
+ controller_handle, guid_controller,
+ &entry_buffer, &count));
+ if (ret != EFI_SUCCESS)
+ goto out;
+ while (count) {
+ if (entry_buffer[--count].attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+ ret = disconnect_child(
+ controller_handle,
+ entry_buffer[count].agent_handle);
+ if (ret != EFI_SUCCESS)
+ goto out;
+ }
+ }
+ ret = EFI_CALL(systab.boottime->free_pool(entry_buffer));
+ if (ret != EFI_SUCCESS)
+ printf("%s(%u) %s: ERROR: Cannot free pool\n",
+ __FILE__, __LINE__, __func__);
+
+ /* Detach driver from controller */
+ ret = EFI_CALL(systab.boottime->close_protocol(
+ controller_handle, guid_controller,
+ this->driver_binding_handle, controller_handle));
+out:
+ return EFI_EXIT(ret);
+}
+
+static efi_status_t efi_add_driver(struct driver *drv)
+{
+ efi_status_t ret;
+ const struct efi_driver_ops *ops = drv->ops;
+ struct efi_driver_binding_extended_protocol *bp;
+
+ debug("EFI: Adding driver '%s'\n", drv->name);
+ if (!ops->protocol) {
+ printf("EFI: ERROR: protocol GUID missing for driver '%s'\n",
+ drv->name);
+ return EFI_INVALID_PARAMETER;
+ }
+ bp = calloc(1, sizeof(struct efi_driver_binding_extended_protocol));
+ if (!bp)
+ return EFI_OUT_OF_RESOURCES;
+
+ bp->bp.supported = efi_uc_supported;
+ bp->bp.start = efi_uc_start;
+ bp->bp.stop = efi_uc_stop;
+ bp->bp.version = 0xffffffff;
+ bp->ops = drv->ops;
+
+ ret = efi_create_handle(&bp->bp.driver_binding_handle);
+ if (ret != EFI_SUCCESS) {
+ free(bp);
+ goto out;
+ }
+ bp->bp.image_handle = bp->bp.driver_binding_handle;
+ ret = efi_add_protocol(bp->bp.driver_binding_handle,
+ &efi_guid_driver_binding_protocol, bp);
+ if (ret != EFI_SUCCESS) {
+ efi_delete_handle(bp->bp.driver_binding_handle);
+ free(bp);
+ goto out;
+ }
+out:
+ return ret;
+}
+
+/*
+ * Initialize the EFI drivers.
+ * Called by board_init_r().
+ *
+ * @return 0 = success, any other value will stop further execution
+ */
+int efi_driver_init(void)
+{
+ struct driver *drv;
+ int ret = 0;
+
+ /* Save 'gd' pointer */
+ efi_save_gd();
+
+ debug("EFI: Initializing EFI driver framework\n");
+ for (drv = ll_entry_start(struct driver, driver);
+ drv < ll_entry_end(struct driver, driver); ++drv) {
+ if (drv->id == UCLASS_EFI) {
+ ret = efi_add_driver(drv);
+ if (ret) {
+ printf("EFI: ERROR: failed to add driver %s\n",
+ drv->name);
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+static int efi_uc_init(struct uclass *class)
+{
+ printf("EFI: Initializing UCLASS_EFI\n");
+ return 0;
+}
+
+static int efi_uc_destroy(struct uclass *class)
+{
+ printf("Destroying UCLASS_EFI\n");
+ return 0;
+}
+
+UCLASS_DRIVER(efi) = {
+ .name = "efi",
+ .id = UCLASS_EFI,
+ .init = efi_uc_init,
+ .destroy = efi_uc_destroy,
+};
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index b90bd0b..39d8511 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -56,6 +56,14 @@
static int entry_count;
static int nesting_level;
+/* GUID of the EFI_DRIVER_BINDING_PROTOCOL */
+const efi_guid_t efi_guid_driver_binding_protocol =
+ EFI_DRIVER_BINDING_PROTOCOL_GUID;
+
+static efi_status_t EFIAPI efi_disconnect_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t driver_image_handle,
+ efi_handle_t child_handle);
/* Called on every callback entry */
int __efi_entry_check(void)
@@ -141,13 +149,14 @@
* For the SignalEvent service see efi_signal_event_ext.
*
* @event event to signal
+ * @check_tpl check the TPL level
*/
-void efi_signal_event(struct efi_event *event)
+void efi_signal_event(struct efi_event *event, bool check_tpl)
{
if (event->notify_function) {
event->is_queued = true;
/* Check TPL */
- if (efi_tpl >= event->notify_tpl)
+ if (check_tpl && efi_tpl >= event->notify_tpl)
return;
EFI_CALL_VOID(event->notify_function(event,
event->notify_context));
@@ -344,7 +353,7 @@
* @handle new handle
* @return status code
*/
-efi_status_t efi_create_handle(void **handle)
+efi_status_t efi_create_handle(efi_handle_t *handle)
{
struct efi_object *obj;
efi_status_t r;
@@ -367,7 +376,7 @@
* @handler reference to the protocol
* @return status code
*/
-efi_status_t efi_search_protocol(const void *handle,
+efi_status_t efi_search_protocol(const efi_handle_t handle,
const efi_guid_t *protocol_guid,
struct efi_handler **handler)
{
@@ -400,7 +409,8 @@
* @protocol_interface interface of the protocol implementation
* @return status code
*/
-efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol,
+efi_status_t efi_remove_protocol(const efi_handle_t handle,
+ const efi_guid_t *protocol,
void *protocol_interface)
{
struct efi_handler *handler;
@@ -422,21 +432,18 @@
* @handle handle from which the protocols shall be deleted
* @return status code
*/
-efi_status_t efi_remove_all_protocols(const void *handle)
+efi_status_t efi_remove_all_protocols(const efi_handle_t handle)
{
struct efi_object *efiobj;
- struct list_head *lhandle;
- struct list_head *pos;
+ struct efi_handler *protocol;
+ struct efi_handler *pos;
efiobj = efi_search_obj(handle);
if (!efiobj)
return EFI_INVALID_PARAMETER;
- list_for_each_safe(lhandle, pos, &efiobj->protocols) {
- struct efi_handler *protocol;
+ list_for_each_entry_safe(protocol, pos, &efiobj->protocols, link) {
efi_status_t ret;
- protocol = list_entry(lhandle, struct efi_handler, link);
-
ret = efi_remove_protocol(handle, protocol->guid,
protocol->protocol_interface);
if (ret != EFI_SUCCESS)
@@ -559,7 +566,7 @@
if (!efi_events[i].type)
continue;
if (efi_events[i].is_queued)
- efi_signal_event(&efi_events[i]);
+ efi_signal_event(&efi_events[i], true);
if (!(efi_events[i].type & EVT_TIMER) ||
now < efi_events[i].trigger_next)
continue;
@@ -575,7 +582,7 @@
continue;
}
efi_events[i].is_signaled = true;
- efi_signal_event(&efi_events[i]);
+ efi_signal_event(&efi_events[i], true);
}
WATCHDOG_RESET();
}
@@ -684,7 +691,7 @@
if (!event[i]->type || event[i]->type & EVT_NOTIFY_SIGNAL)
return EFI_EXIT(EFI_INVALID_PARAMETER);
if (!event[i]->is_signaled)
- efi_signal_event(event[i]);
+ efi_signal_event(event[i], true);
}
/* Wait for signal */
@@ -734,7 +741,7 @@
break;
event->is_signaled = true;
if (event->type & EVT_NOTIFY_SIGNAL)
- efi_signal_event(event);
+ efi_signal_event(event, true);
break;
}
return EFI_EXIT(EFI_SUCCESS);
@@ -791,7 +798,7 @@
if (!event->type || event->type & EVT_NOTIFY_SIGNAL)
break;
if (!event->is_signaled)
- efi_signal_event(event);
+ efi_signal_event(event, true);
if (event->is_signaled)
return EFI_EXIT(EFI_SUCCESS);
return EFI_EXIT(EFI_NOT_READY);
@@ -805,7 +812,7 @@
* @handle handle to find
* @return EFI object
*/
-struct efi_object *efi_search_obj(const void *handle)
+struct efi_object *efi_search_obj(const efi_handle_t handle)
{
struct efi_object *efiobj;
@@ -818,6 +825,40 @@
}
/*
+ * Create open protocol info entry and add it to a protocol.
+ *
+ * @handler handler of a protocol
+ * @return open protocol info entry
+ */
+static struct efi_open_protocol_info_entry *efi_create_open_info(
+ struct efi_handler *handler)
+{
+ struct efi_open_protocol_info_item *item;
+
+ item = calloc(1, sizeof(struct efi_open_protocol_info_item));
+ if (!item)
+ return NULL;
+ /* Append the item to the open protocol info list. */
+ list_add_tail(&item->link, &handler->open_infos);
+
+ return &item->info;
+}
+
+/*
+ * Remove an open protocol info entry from a protocol.
+ *
+ * @handler handler of a protocol
+ * @return status code
+ */
+static efi_status_t efi_delete_open_info(
+ struct efi_open_protocol_info_item *item)
+{
+ list_del(&item->link);
+ free(item);
+ return EFI_SUCCESS;
+}
+
+/*
* Install new protocol on a handle.
*
* @handle handle on which the protocol shall be installed
@@ -825,7 +866,8 @@
* @protocol_interface interface of the protocol implementation
* @return status code
*/
-efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol,
+efi_status_t efi_add_protocol(const efi_handle_t handle,
+ const efi_guid_t *protocol,
void *protocol_interface)
{
struct efi_object *efiobj;
@@ -843,7 +885,10 @@
return EFI_OUT_OF_RESOURCES;
handler->guid = protocol;
handler->protocol_interface = protocol_interface;
+ INIT_LIST_HEAD(&handler->open_infos);
list_add_tail(&handler->link, &efiobj->protocols);
+ if (!guidcmp(&efi_guid_device_path, protocol))
+ EFI_PRINT("installed device path '%pD'\n", protocol_interface);
return EFI_SUCCESS;
}
@@ -907,9 +952,9 @@
* @new_interface interface to be installed
* @return status code
*/
-static efi_status_t EFIAPI efi_reinstall_protocol_interface(void *handle,
- const efi_guid_t *protocol, void *old_interface,
- void *new_interface)
+static efi_status_t EFIAPI efi_reinstall_protocol_interface(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ void *old_interface, void *new_interface)
{
EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, old_interface,
new_interface);
@@ -917,6 +962,109 @@
}
/*
+ * Get all drivers associated to a controller.
+ * The allocated buffer has to be freed with free().
+ *
+ * @efiobj handle of the controller
+ * @protocol protocol guid (optional)
+ * @number_of_drivers number of child controllers
+ * @driver_handle_buffer handles of the the drivers
+ * @return status code
+ */
+static efi_status_t efi_get_drivers(struct efi_object *efiobj,
+ const efi_guid_t *protocol,
+ efi_uintn_t *number_of_drivers,
+ efi_handle_t **driver_handle_buffer)
+{
+ struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+ efi_uintn_t count = 0, i;
+ bool duplicate;
+
+ /* Count all driver associations */
+ list_for_each_entry(handler, &efiobj->protocols, link) {
+ if (protocol && guidcmp(handler->guid, protocol))
+ continue;
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.attributes &
+ EFI_OPEN_PROTOCOL_BY_DRIVER)
+ ++count;
+ }
+ }
+ /*
+ * Create buffer. In case of duplicate driver assignments the buffer
+ * will be too large. But that does not harm.
+ */
+ *number_of_drivers = 0;
+ *driver_handle_buffer = calloc(count, sizeof(efi_handle_t));
+ if (!*driver_handle_buffer)
+ return EFI_OUT_OF_RESOURCES;
+ /* Collect unique driver handles */
+ list_for_each_entry(handler, &efiobj->protocols, link) {
+ if (protocol && guidcmp(handler->guid, protocol))
+ continue;
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.attributes &
+ EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ /* Check this is a new driver */
+ duplicate = false;
+ for (i = 0; i < *number_of_drivers; ++i) {
+ if ((*driver_handle_buffer)[i] ==
+ item->info.agent_handle)
+ duplicate = true;
+ }
+ /* Copy handle to buffer */
+ if (!duplicate) {
+ i = (*number_of_drivers)++;
+ (*driver_handle_buffer)[i] =
+ item->info.agent_handle;
+ }
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/*
+ * Disconnect all drivers from a controller.
+ *
+ * This function implements the DisconnectController service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @efiobj handle of the controller
+ * @protocol protocol guid (optional)
+ * @child_handle handle of the child to destroy
+ * @return status code
+ */
+static efi_status_t efi_disconnect_all_drivers(
+ struct efi_object *efiobj,
+ const efi_guid_t *protocol,
+ efi_handle_t child_handle)
+{
+ efi_uintn_t number_of_drivers;
+ efi_handle_t *driver_handle_buffer;
+ efi_status_t r, ret;
+
+ ret = efi_get_drivers(efiobj, protocol, &number_of_drivers,
+ &driver_handle_buffer);
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ ret = EFI_NOT_FOUND;
+ while (number_of_drivers) {
+ r = EFI_CALL(efi_disconnect_controller(
+ efiobj->handle,
+ driver_handle_buffer[--number_of_drivers],
+ child_handle));
+ if (r == EFI_SUCCESS)
+ ret = r;
+ }
+ free(driver_handle_buffer);
+ return ret;
+}
+
+/*
* Uninstall protocol interface.
*
* This function implements the UninstallProtocolInterface service.
@@ -929,29 +1077,46 @@
* @return status code
*/
static efi_status_t EFIAPI efi_uninstall_protocol_interface(
- void *handle, const efi_guid_t *protocol,
+ efi_handle_t handle, const efi_guid_t *protocol,
void *protocol_interface)
{
+ struct efi_object *efiobj;
struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+ struct efi_open_protocol_info_item *pos;
efi_status_t r;
EFI_ENTRY("%p, %pUl, %p", handle, protocol, protocol_interface);
- if (!handle || !protocol) {
+ /* Check handle */
+ efiobj = efi_search_obj(handle);
+ if (!efiobj) {
r = EFI_INVALID_PARAMETER;
goto out;
}
-
/* Find the protocol on the handle */
r = efi_search_protocol(handle, protocol, &handler);
if (r != EFI_SUCCESS)
goto out;
- if (handler->protocol_interface) {
- /* TODO disconnect controllers */
+ /* Disconnect controllers */
+ efi_disconnect_all_drivers(efiobj, protocol, NULL);
+ if (!list_empty(&handler->open_infos)) {
r = EFI_ACCESS_DENIED;
- } else {
- r = efi_remove_protocol(handle, protocol, protocol_interface);
+ goto out;
}
+ /* Close protocol */
+ list_for_each_entry_safe(item, pos, &handler->open_infos, link) {
+ if (item->info.attributes ==
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL ||
+ item->info.attributes == EFI_OPEN_PROTOCOL_GET_PROTOCOL ||
+ item->info.attributes == EFI_OPEN_PROTOCOL_TEST_PROTOCOL)
+ list_del(&item->link);
+ }
+ if (!list_empty(&handler->open_infos)) {
+ r = EFI_ACCESS_DENIED;
+ goto out;
+ }
+ r = efi_remove_protocol(handle, protocol, protocol_interface);
out:
return EFI_EXIT(r);
}
@@ -1310,7 +1475,7 @@
struct efi_object *obj;
efi_status_t ret;
- EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image,
+ EFI_ENTRY("%d, %p, %pD, %p, %ld, %p", boot_policy, parent_image,
file_path, source_buffer, source_size, image_handle);
info = calloc(1, sizeof(*info));
@@ -1369,8 +1534,10 @@
unsigned long *exit_data_size,
s16 **exit_data)
{
- ulong (*entry)(void *image_handle, struct efi_system_table *st);
+ asmlinkage ulong (*entry)(efi_handle_t image_handle,
+ struct efi_system_table *st);
struct efi_loaded_image *info = image_handle;
+ efi_status_t ret;
EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
entry = info->reserved;
@@ -1379,18 +1546,37 @@
/* call the image! */
if (setjmp(&info->exit_jmp)) {
- /* We returned from the child image */
+ /*
+ * We called the entry point of the child image with EFI_CALL
+ * in the lines below. The child image called the Exit() boot
+ * service efi_exit() which executed the long jump that brought
+ * us to the current line. This implies that the second half
+ * of the EFI_CALL macro has not been executed.
+ */
+#ifdef CONFIG_ARM
+ /*
+ * efi_exit() called efi_restore_gd(). We have to undo this
+ * otherwise __efi_entry_check() will put the wrong value into
+ * app_gd.
+ */
+ gd = app_gd;
+#endif
+ /*
+ * To get ready to call EFI_EXIT below we have to execute the
+ * missed out steps of EFI_CALL.
+ */
+ assert(__efi_entry_check());
+ debug("%sEFI: %lu returned by started image\n",
+ __efi_nesting_dec(),
+ (unsigned long)((uintptr_t)info->exit_status &
+ ~EFI_ERROR_MASK));
return EFI_EXIT(info->exit_status);
}
- __efi_nesting_dec();
- __efi_exit_check();
- entry(image_handle, &systab);
- __efi_entry_check();
- __efi_nesting_inc();
+ ret = EFI_CALL(entry(image_handle, &systab));
/* Should usually never get here */
- return EFI_EXIT(EFI_SUCCESS);
+ return EFI_EXIT(ret);
}
/*
@@ -1427,7 +1613,7 @@
exit_data_size, exit_data);
/* Make sure entry/exit counts for EFI world cross-overs match */
- __efi_exit_check();
+ EFI_EXIT(exit_status);
/*
* But longjmp out with the U-Boot gd, not the application's, as
@@ -1451,7 +1637,7 @@
* @image_handle handle of the image to be unloaded
* @return status code
*/
-static efi_status_t EFIAPI efi_unload_image(void *image_handle)
+static efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle)
{
struct efi_object *efiobj;
@@ -1479,33 +1665,43 @@
}
/*
- * Stop boot services.
+ * Stop all boot services.
*
* This function implements the ExitBootServices service.
* See the Unified Extensible Firmware Interface (UEFI) specification
* for details.
*
+ * All timer events are disabled.
+ * For exit boot services events the notification function is called.
+ * The boot services are disabled in the system table.
+ *
* @image_handle handle of the loaded image
* @map_key key of the memory map
* @return status code
*/
-static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle,
+static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
unsigned long map_key)
{
int i;
EFI_ENTRY("%p, %ld", image_handle, map_key);
+ /* Make sure that notification functions are not called anymore */
+ efi_tpl = TPL_HIGH_LEVEL;
+
+ /* Check if ExitBootServices has already been called */
+ if (!systab.boottime)
+ return EFI_EXIT(EFI_SUCCESS);
+
/* Notify that ExitBootServices is invoked. */
for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
if (efi_events[i].type != EVT_SIGNAL_EXIT_BOOT_SERVICES)
continue;
- efi_signal_event(&efi_events[i]);
+ efi_events[i].is_signaled = true;
+ efi_signal_event(&efi_events[i], false);
}
- /* Make sure that notification functions are not called anymore */
- efi_tpl = TPL_HIGH_LEVEL;
- /* XXX Should persist EFI variables here */
+ /* TODO Should persist EFI variables here */
board_quiesce_devices();
@@ -1515,6 +1711,20 @@
/* This stops all lingering devices */
bootm_disable_interrupts();
+ /* Disable boottime services */
+ systab.con_in_handle = NULL;
+ systab.con_in = NULL;
+ systab.con_out_handle = NULL;
+ systab.con_out = NULL;
+ systab.stderr_handle = NULL;
+ systab.std_err = NULL;
+ systab.boottime = NULL;
+
+ /* Recalculate CRC32 */
+ systab.hdr.crc32 = 0;
+ systab.hdr.crc32 = crc32(0, (const unsigned char *)&systab,
+ sizeof(struct efi_system_table));
+
/* Give the payload some time to boot */
efi_set_watchdog(0);
WATCHDOG_RESET();
@@ -1581,51 +1791,6 @@
}
/*
- * Connect a controller to a driver.
- *
- * This function implements the ConnectController service.
- * See the Unified Extensible Firmware Interface (UEFI) specification
- * for details.
- *
- * @controller_handle handle of the controller
- * @driver_image_handle handle of the driver
- * @remain_device_path device path of a child controller
- * @recursive true to connect all child controllers
- * @return status code
- */
-static efi_status_t EFIAPI efi_connect_controller(
- efi_handle_t controller_handle,
- efi_handle_t *driver_image_handle,
- struct efi_device_path *remain_device_path,
- bool recursive)
-{
- EFI_ENTRY("%p, %p, %p, %d", controller_handle, driver_image_handle,
- remain_device_path, recursive);
- return EFI_EXIT(EFI_NOT_FOUND);
-}
-
-/*
- * Disconnect a controller from a driver.
- *
- * This function implements the DisconnectController service.
- * See the Unified Extensible Firmware Interface (UEFI) specification
- * for details.
- *
- * @controller_handle handle of the controller
- * @driver_image_handle handle of the driver
- * @child_handle handle of the child to destroy
- * @return status code
- */
-static efi_status_t EFIAPI efi_disconnect_controller(void *controller_handle,
- void *driver_image_handle,
- void *child_handle)
-{
- EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
- child_handle);
- return EFI_EXIT(EFI_INVALID_PARAMETER);
-}
-
-/*
* Close a protocol.
*
* This function implements the CloseProtocol service.
@@ -1638,14 +1803,38 @@
* @controller_handle handle of the controller
* @return status code
*/
-static efi_status_t EFIAPI efi_close_protocol(void *handle,
+static efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
const efi_guid_t *protocol,
- void *agent_handle,
- void *controller_handle)
+ efi_handle_t agent_handle,
+ efi_handle_t controller_handle)
{
+ struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+ struct efi_open_protocol_info_item *pos;
+ efi_status_t r;
+
EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, agent_handle,
controller_handle);
- return EFI_EXIT(EFI_NOT_FOUND);
+
+ if (!agent_handle) {
+ r = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ r = efi_search_protocol(handle, protocol, &handler);
+ if (r != EFI_SUCCESS)
+ goto out;
+
+ r = EFI_NOT_FOUND;
+ list_for_each_entry_safe(item, pos, &handler->open_infos, link) {
+ if (item->info.agent_handle == agent_handle &&
+ item->info.controller_handle == controller_handle) {
+ efi_delete_open_info(item);
+ r = EFI_SUCCESS;
+ break;
+ }
+ }
+out:
+ return EFI_EXIT(r);
}
/*
@@ -1666,9 +1855,49 @@
struct efi_open_protocol_info_entry **entry_buffer,
efi_uintn_t *entry_count)
{
+ unsigned long buffer_size;
+ unsigned long count;
+ struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+ efi_status_t r;
+
EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, entry_buffer,
entry_count);
- return EFI_EXIT(EFI_NOT_FOUND);
+
+ /* Check parameters */
+ if (!entry_buffer) {
+ r = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ r = efi_search_protocol(handle, protocol, &handler);
+ if (r != EFI_SUCCESS)
+ goto out;
+
+ /* Count entries */
+ count = 0;
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.open_count)
+ ++count;
+ }
+ *entry_count = count;
+ *entry_buffer = NULL;
+ if (!count) {
+ r = EFI_SUCCESS;
+ goto out;
+ }
+
+ /* Copy entries */
+ buffer_size = count * sizeof(struct efi_open_protocol_info_entry);
+ r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, buffer_size,
+ (void **)entry_buffer);
+ if (r != EFI_SUCCESS)
+ goto out;
+ list_for_each_entry_reverse(item, &handler->open_infos, link) {
+ if (item->info.open_count)
+ (*entry_buffer)[--count] = item->info;
+ }
+out:
+ return EFI_EXIT(r);
}
/*
@@ -1683,8 +1912,8 @@
* @protocol_buffer_count number of entries in the buffer
* @return status code
*/
-static efi_status_t EFIAPI efi_protocols_per_handle(void *handle,
- efi_guid_t ***protocol_buffer,
+static efi_status_t EFIAPI efi_protocols_per_handle(
+ efi_handle_t handle, efi_guid_t ***protocol_buffer,
efi_uintn_t *protocol_buffer_count)
{
unsigned long buffer_size;
@@ -1774,7 +2003,7 @@
r = efi_locate_handle(search_type, protocol, search_key, &buffer_size,
*buffer);
if (r == EFI_SUCCESS)
- *no_handles = buffer_size / sizeof(void *);
+ *no_handles = buffer_size / sizeof(efi_handle_t);
out:
return EFI_EXIT(r);
}
@@ -2071,6 +2300,101 @@
/*
* Open protocol interface on a handle.
*
+ * @handler handler of a protocol
+ * @protocol_interface interface implementing the protocol
+ * @agent_handle handle of the driver
+ * @controller_handle handle of the controller
+ * @attributes attributes indicating how to open the protocol
+ * @return status code
+ */
+static efi_status_t efi_protocol_open(
+ struct efi_handler *handler,
+ void **protocol_interface, void *agent_handle,
+ void *controller_handle, uint32_t attributes)
+{
+ struct efi_open_protocol_info_item *item;
+ struct efi_open_protocol_info_entry *match = NULL;
+ bool opened_by_driver = false;
+ bool opened_exclusive = false;
+
+ /* If there is no agent, only return the interface */
+ if (!agent_handle)
+ goto out;
+
+ /* For TEST_PROTOCOL ignore interface attribute */
+ if (attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL)
+ *protocol_interface = NULL;
+
+ /*
+ * Check if the protocol is already opened by a driver with the same
+ * attributes or opened exclusively
+ */
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.agent_handle == agent_handle) {
+ if ((attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) &&
+ (item->info.attributes == attributes))
+ return EFI_ALREADY_STARTED;
+ }
+ if (item->info.attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE)
+ opened_exclusive = true;
+ }
+
+ /* Only one controller can open the protocol exclusively */
+ if (opened_exclusive && attributes &
+ (EFI_OPEN_PROTOCOL_EXCLUSIVE | EFI_OPEN_PROTOCOL_BY_DRIVER))
+ return EFI_ACCESS_DENIED;
+
+ /* Prepare exclusive opening */
+ if (attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) {
+ /* Try to disconnect controllers */
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.attributes ==
+ EFI_OPEN_PROTOCOL_BY_DRIVER)
+ EFI_CALL(efi_disconnect_controller(
+ item->info.controller_handle,
+ item->info.agent_handle,
+ NULL));
+ }
+ opened_by_driver = false;
+ /* Check if all controllers are disconnected */
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.attributes & EFI_OPEN_PROTOCOL_BY_DRIVER)
+ opened_by_driver = true;
+ }
+ /* Only one controller can be conncected */
+ if (opened_by_driver)
+ return EFI_ACCESS_DENIED;
+ }
+
+ /* Find existing entry */
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.agent_handle == agent_handle &&
+ item->info.controller_handle == controller_handle)
+ match = &item->info;
+ }
+ /* None found, create one */
+ if (!match) {
+ match = efi_create_open_info(handler);
+ if (!match)
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ match->agent_handle = agent_handle;
+ match->controller_handle = controller_handle;
+ match->attributes = attributes;
+ match->open_count++;
+
+out:
+ /* For TEST_PROTOCOL ignore interface attribute. */
+ if (attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL)
+ *protocol_interface = handler->protocol_interface;
+
+ return EFI_SUCCESS;
+}
+
+/*
+ * Open protocol interface on a handle.
+ *
* This function implements the OpenProtocol interface.
* See the Unified Extensible Firmware Interface (UEFI) specification
* for details.
@@ -2109,12 +2433,16 @@
case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
if (controller_handle == handle)
goto out;
+ /* fall-through */
case EFI_OPEN_PROTOCOL_BY_DRIVER:
case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
- if (controller_handle == NULL)
+ /* Check that the controller handle is valid */
+ if (!efi_search_obj(controller_handle))
goto out;
+ /* fall-through */
case EFI_OPEN_PROTOCOL_EXCLUSIVE:
- if (agent_handle == NULL)
+ /* Check that the agent handle is valid */
+ if (!efi_search_obj(agent_handle))
goto out;
break;
default:
@@ -2125,8 +2453,8 @@
if (r != EFI_SUCCESS)
goto out;
- if (attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL)
- *protocol_interface = handler->protocol_interface;
+ r = efi_protocol_open(handler, protocol_interface, agent_handle,
+ controller_handle, attributes);
out:
return EFI_EXIT(r);
}
@@ -2143,7 +2471,7 @@
* @protocol_interface interface implementing the protocol
* @return status code
*/
-static efi_status_t EFIAPI efi_handle_protocol(void *handle,
+static efi_status_t EFIAPI efi_handle_protocol(efi_handle_t handle,
const efi_guid_t *protocol,
void **protocol_interface)
{
@@ -2151,6 +2479,321 @@
NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
}
+static efi_status_t efi_bind_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t driver_image_handle,
+ struct efi_device_path *remain_device_path)
+{
+ struct efi_driver_binding_protocol *binding_protocol;
+ efi_status_t r;
+
+ r = EFI_CALL(efi_open_protocol(driver_image_handle,
+ &efi_guid_driver_binding_protocol,
+ (void **)&binding_protocol,
+ driver_image_handle, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL));
+ if (r != EFI_SUCCESS)
+ return r;
+ r = EFI_CALL(binding_protocol->supported(binding_protocol,
+ controller_handle,
+ remain_device_path));
+ if (r == EFI_SUCCESS)
+ r = EFI_CALL(binding_protocol->start(binding_protocol,
+ controller_handle,
+ remain_device_path));
+ EFI_CALL(efi_close_protocol(driver_image_handle,
+ &efi_guid_driver_binding_protocol,
+ driver_image_handle, NULL));
+ return r;
+}
+
+static efi_status_t efi_connect_single_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t *driver_image_handle,
+ struct efi_device_path *remain_device_path)
+{
+ efi_handle_t *buffer;
+ size_t count;
+ size_t i;
+ efi_status_t r;
+ size_t connected = 0;
+
+ /* Get buffer with all handles with driver binding protocol */
+ r = EFI_CALL(efi_locate_handle_buffer(BY_PROTOCOL,
+ &efi_guid_driver_binding_protocol,
+ NULL, &count, &buffer));
+ if (r != EFI_SUCCESS)
+ return r;
+
+ /* Context Override */
+ if (driver_image_handle) {
+ for (; *driver_image_handle; ++driver_image_handle) {
+ for (i = 0; i < count; ++i) {
+ if (buffer[i] == *driver_image_handle) {
+ buffer[i] = NULL;
+ r = efi_bind_controller(
+ controller_handle,
+ *driver_image_handle,
+ remain_device_path);
+ /*
+ * For drivers that do not support the
+ * controller or are already connected
+ * we receive an error code here.
+ */
+ if (r == EFI_SUCCESS)
+ ++connected;
+ }
+ }
+ }
+ }
+
+ /*
+ * TODO: Some overrides are not yet implemented:
+ * - Platform Driver Override
+ * - Driver Family Override Search
+ * - Bus Specific Driver Override
+ */
+
+ /* Driver Binding Search */
+ for (i = 0; i < count; ++i) {
+ if (buffer[i]) {
+ r = efi_bind_controller(controller_handle,
+ buffer[i],
+ remain_device_path);
+ if (r == EFI_SUCCESS)
+ ++connected;
+ }
+ }
+
+ efi_free_pool(buffer);
+ if (!connected)
+ return EFI_NOT_FOUND;
+ return EFI_SUCCESS;
+}
+
+/*
+ * Connect a controller to a driver.
+ *
+ * This function implements the ConnectController service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * First all driver binding protocol handles are tried for binding drivers.
+ * Afterwards all handles that have openened a protocol of the controller
+ * with EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER are connected to drivers.
+ *
+ * @controller_handle handle of the controller
+ * @driver_image_handle handle of the driver
+ * @remain_device_path device path of a child controller
+ * @recursive true to connect all child controllers
+ * @return status code
+ */
+static efi_status_t EFIAPI efi_connect_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t *driver_image_handle,
+ struct efi_device_path *remain_device_path,
+ bool recursive)
+{
+ efi_status_t r;
+ efi_status_t ret = EFI_NOT_FOUND;
+ struct efi_object *efiobj;
+
+ EFI_ENTRY("%p, %p, %p, %d", controller_handle, driver_image_handle,
+ remain_device_path, recursive);
+
+ efiobj = efi_search_obj(controller_handle);
+ if (!efiobj) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ r = efi_connect_single_controller(controller_handle,
+ driver_image_handle,
+ remain_device_path);
+ if (r == EFI_SUCCESS)
+ ret = EFI_SUCCESS;
+ if (recursive) {
+ struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+
+ list_for_each_entry(handler, &efiobj->protocols, link) {
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+ r = EFI_CALL(efi_connect_controller(
+ item->info.controller_handle,
+ driver_image_handle,
+ remain_device_path,
+ recursive));
+ if (r == EFI_SUCCESS)
+ ret = EFI_SUCCESS;
+ }
+ }
+ }
+ }
+ /* Check for child controller specified by end node */
+ if (ret != EFI_SUCCESS && remain_device_path &&
+ remain_device_path->type == DEVICE_PATH_TYPE_END)
+ ret = EFI_SUCCESS;
+out:
+ return EFI_EXIT(ret);
+}
+
+/*
+ * Get all child controllers associated to a driver.
+ * The allocated buffer has to be freed with free().
+ *
+ * @efiobj handle of the controller
+ * @driver_handle handle of the driver
+ * @number_of_children number of child controllers
+ * @child_handle_buffer handles of the the child controllers
+ */
+static efi_status_t efi_get_child_controllers(
+ struct efi_object *efiobj,
+ efi_handle_t driver_handle,
+ efi_uintn_t *number_of_children,
+ efi_handle_t **child_handle_buffer)
+{
+ struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+ efi_uintn_t count = 0, i;
+ bool duplicate;
+
+ /* Count all child controller associations */
+ list_for_each_entry(handler, &efiobj->protocols, link) {
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.agent_handle == driver_handle &&
+ item->info.attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
+ ++count;
+ }
+ }
+ /*
+ * Create buffer. In case of duplicate child controller assignments
+ * the buffer will be too large. But that does not harm.
+ */
+ *number_of_children = 0;
+ *child_handle_buffer = calloc(count, sizeof(efi_handle_t));
+ if (!*child_handle_buffer)
+ return EFI_OUT_OF_RESOURCES;
+ /* Copy unique child handles */
+ list_for_each_entry(handler, &efiobj->protocols, link) {
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.agent_handle == driver_handle &&
+ item->info.attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+ /* Check this is a new child controller */
+ duplicate = false;
+ for (i = 0; i < *number_of_children; ++i) {
+ if ((*child_handle_buffer)[i] ==
+ item->info.controller_handle)
+ duplicate = true;
+ }
+ /* Copy handle to buffer */
+ if (!duplicate) {
+ i = (*number_of_children)++;
+ (*child_handle_buffer)[i] =
+ item->info.controller_handle;
+ }
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/*
+ * Disconnect a controller from a driver.
+ *
+ * This function implements the DisconnectController service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @controller_handle handle of the controller
+ * @driver_image_handle handle of the driver
+ * @child_handle handle of the child to destroy
+ * @return status code
+ */
+static efi_status_t EFIAPI efi_disconnect_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t driver_image_handle,
+ efi_handle_t child_handle)
+{
+ struct efi_driver_binding_protocol *binding_protocol;
+ efi_handle_t *child_handle_buffer = NULL;
+ size_t number_of_children = 0;
+ efi_status_t r;
+ size_t stop_count = 0;
+ struct efi_object *efiobj;
+
+ EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
+ child_handle);
+
+ efiobj = efi_search_obj(controller_handle);
+ if (!efiobj) {
+ r = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ if (child_handle && !efi_search_obj(child_handle)) {
+ r = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ /* If no driver handle is supplied, disconnect all drivers */
+ if (!driver_image_handle) {
+ r = efi_disconnect_all_drivers(efiobj, NULL, child_handle);
+ goto out;
+ }
+
+ /* Create list of child handles */
+ if (child_handle) {
+ number_of_children = 1;
+ child_handle_buffer = &child_handle;
+ } else {
+ efi_get_child_controllers(efiobj,
+ driver_image_handle,
+ &number_of_children,
+ &child_handle_buffer);
+ }
+
+ /* Get the driver binding protocol */
+ r = EFI_CALL(efi_open_protocol(driver_image_handle,
+ &efi_guid_driver_binding_protocol,
+ (void **)&binding_protocol,
+ driver_image_handle, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL));
+ if (r != EFI_SUCCESS)
+ goto out;
+ /* Remove the children */
+ if (number_of_children) {
+ r = EFI_CALL(binding_protocol->stop(binding_protocol,
+ controller_handle,
+ number_of_children,
+ child_handle_buffer));
+ if (r == EFI_SUCCESS)
+ ++stop_count;
+ }
+ /* Remove the driver */
+ if (!child_handle)
+ r = EFI_CALL(binding_protocol->stop(binding_protocol,
+ controller_handle,
+ 0, NULL));
+ if (r == EFI_SUCCESS)
+ ++stop_count;
+ EFI_CALL(efi_close_protocol(driver_image_handle,
+ &efi_guid_driver_binding_protocol,
+ driver_image_handle, NULL));
+
+ if (stop_count)
+ r = EFI_SUCCESS;
+ else
+ r = EFI_NOT_FOUND;
+out:
+ if (!child_handle)
+ free(child_handle_buffer);
+ return EFI_EXIT(r);
+}
+
static const struct efi_boot_services efi_boot_services = {
.hdr = {
.headersize = sizeof(struct efi_table_hdr),
@@ -2201,8 +2844,7 @@
};
-static uint16_t __efi_runtime_data firmware_vendor[] =
- { 'D','a','s',' ','U','-','b','o','o','t',0 };
+static uint16_t __efi_runtime_data firmware_vendor[] = L"Das U-Boot";
struct efi_system_table __efi_runtime_data systab = {
.hdr = {
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 98497db..28d6363 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -482,18 +482,26 @@
{
}
+/*
+ * Notification function of the console timer event.
+ *
+ * event: console timer event
+ * context: not used
+ */
static void EFIAPI efi_console_timer_notify(struct efi_event *event,
void *context)
{
EFI_ENTRY("%p, %p", event, context);
+
+ /* Check if input is available */
if (tstc()) {
+ /* Queue the wait for key event */
efi_con_in.wait_for_key->is_signaled = true;
- efi_signal_event(efi_con_in.wait_for_key);
- }
+ efi_signal_event(efi_con_in.wait_for_key, true);
+ }
EFI_EXIT(EFI_SUCCESS);
}
-
/* This gets called from do_bootefi_exec(). */
int efi_console_register(void)
{
@@ -503,21 +511,21 @@
struct efi_object *efi_console_input_obj;
/* Create handles */
- r = efi_create_handle((void **)&efi_console_control_obj);
+ r = efi_create_handle((efi_handle_t *)&efi_console_control_obj);
if (r != EFI_SUCCESS)
goto out_of_memory;
r = efi_add_protocol(efi_console_control_obj->handle,
&efi_guid_console_control, &efi_console_control);
if (r != EFI_SUCCESS)
goto out_of_memory;
- r = efi_create_handle((void **)&efi_console_output_obj);
+ r = efi_create_handle((efi_handle_t *)&efi_console_output_obj);
if (r != EFI_SUCCESS)
goto out_of_memory;
r = efi_add_protocol(efi_console_output_obj->handle,
&efi_guid_text_output_protocol, &efi_con_out);
if (r != EFI_SUCCESS)
goto out_of_memory;
- r = efi_create_handle((void **)&efi_console_input_obj);
+ r = efi_create_handle((efi_handle_t *)&efi_console_input_obj);
if (r != EFI_SUCCESS)
goto out_of_memory;
r = efi_add_protocol(efi_console_input_obj->handle,
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index ccb5933..ecc4eda 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -6,6 +6,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#define LOG_CATEGORY LOGL_ERR
+
#include <common.h>
#include <blk.h>
#include <dm.h>
@@ -58,8 +60,11 @@
{
void *buf;
- if (efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, sz, &buf) != EFI_SUCCESS)
+ if (efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, sz, &buf) !=
+ EFI_SUCCESS) {
+ debug("EFI: ERROR: out of memory in %s\n", __func__);
return NULL;
+ }
return buf;
}
@@ -108,7 +113,6 @@
}
}
-
/*
* See UEFI spec (section 3.1.2, about short-form device-paths..
* tl;dr: we can have a device-path that starts with a USB WWID
@@ -181,7 +185,6 @@
return NULL;
}
-
/*
* Find an efiobj from device-path, if 'rem' is not NULL, returns the
* remaining part of the device path after the matched object.
@@ -205,6 +208,26 @@
return efiobj;
}
+/*
+ * Determine the last device path node that is not the end node.
+ *
+ * @dp device path
+ * @return last node before the end node if it exists
+ * otherwise NULL
+ */
+const struct efi_device_path *efi_dp_last_node(const struct efi_device_path *dp)
+{
+ struct efi_device_path *ret;
+
+ if (!dp || dp->type == DEVICE_PATH_TYPE_END)
+ return NULL;
+ while (dp) {
+ ret = (struct efi_device_path *)dp;
+ dp = efi_dp_next(dp);
+ }
+ return ret;
+}
+
/* return size not including End node: */
unsigned efi_dp_size(const struct efi_device_path *dp)
{
@@ -227,6 +250,8 @@
return NULL;
ndp = dp_alloc(sz);
+ if (!ndp)
+ return NULL;
memcpy(ndp, dp, sz);
return ndp;
@@ -246,6 +271,8 @@
unsigned sz1 = efi_dp_size(dp1);
unsigned sz2 = efi_dp_size(dp2);
void *p = dp_alloc(sz1 + sz2 + sizeof(END));
+ if (!p)
+ return NULL;
memcpy(p, dp1, sz1);
memcpy(p + sz1, dp2, sz2);
memcpy(p + sz1 + sz2, &END, sizeof(END));
@@ -267,6 +294,8 @@
} else if (!dp) {
unsigned sz = node->length;
void *p = dp_alloc(sz + sizeof(END));
+ if (!p)
+ return NULL;
memcpy(p, node, sz);
memcpy(p + sz, &END, sizeof(END));
ret = p;
@@ -274,6 +303,8 @@
/* both dp and node are non-null */
unsigned sz = efi_dp_size(dp);
void *p = dp_alloc(sz + node->length + sizeof(END));
+ if (!p)
+ return NULL;
memcpy(p, dp, sz);
memcpy(p + sz, node, node->length);
memcpy(p + sz + node->length, &END, sizeof(END));
@@ -297,9 +328,36 @@
case UCLASS_SIMPLE_BUS:
/* stop traversing parents at this point: */
return sizeof(ROOT);
+ case UCLASS_ETH:
+ return dp_size(dev->parent) +
+ sizeof(struct efi_device_path_mac_addr);
+#ifdef CONFIG_BLK
+ case UCLASS_BLK:
+ switch (dev->parent->uclass->uc_drv->id) {
+#ifdef CONFIG_IDE
+ case UCLASS_IDE:
+ return dp_size(dev->parent) +
+ sizeof(struct efi_device_path_atapi);
+#endif
+#if defined(CONFIG_SCSI) && defined(CONFIG_DM_SCSI)
+ case UCLASS_SCSI:
+ return dp_size(dev->parent) +
+ sizeof(struct efi_device_path_scsi);
+#endif
+#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
+ case UCLASS_MMC:
+ return dp_size(dev->parent) +
+ sizeof(struct efi_device_path_sd_mmc_path);
+#endif
+ default:
+ return dp_size(dev->parent);
+ }
+#endif
+#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
case UCLASS_MMC:
return dp_size(dev->parent) +
sizeof(struct efi_device_path_sd_mmc_path);
+#endif
case UCLASS_MASS_STORAGE:
case UCLASS_USB_HUB:
return dp_size(dev->parent) +
@@ -310,6 +368,13 @@
}
}
+/*
+ * Recursively build a device path.
+ *
+ * @buf pointer to the end of the device path
+ * @dev device
+ * @return pointer to the end of the device path
+ */
static void *dp_fill(void *buf, struct udevice *dev)
{
if (!dev || !dev->driver)
@@ -323,6 +388,79 @@
*vdp = ROOT;
return &vdp[1];
}
+#ifdef CONFIG_DM_ETH
+ case UCLASS_ETH: {
+ struct efi_device_path_mac_addr *dp =
+ dp_fill(buf, dev->parent);
+ struct eth_pdata *pdata = dev->platdata;
+
+ dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
+ dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR;
+ dp->dp.length = sizeof(*dp);
+ memset(&dp->mac, 0, sizeof(dp->mac));
+ /* We only support IPv4 */
+ memcpy(&dp->mac, &pdata->enetaddr, ARP_HLEN);
+ /* Ethernet */
+ dp->if_type = 1;
+ return &dp[1];
+ }
+#endif
+#ifdef CONFIG_BLK
+ case UCLASS_BLK:
+ switch (dev->parent->uclass->uc_drv->id) {
+#ifdef CONFIG_IDE
+ case UCLASS_IDE: {
+ struct efi_device_path_atapi *dp =
+ dp_fill(buf, dev->parent);
+ struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+ dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
+ dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_ATAPI;
+ dp->dp.length = sizeof(*dp);
+ dp->logical_unit_number = desc->devnum;
+ dp->primary_secondary = IDE_BUS(desc->devnum);
+ dp->slave_master = desc->devnum %
+ (CONFIG_SYS_IDE_MAXDEVICE /
+ CONFIG_SYS_IDE_MAXBUS);
+ return &dp[1];
+ }
+#endif
+#if defined(CONFIG_SCSI) && defined(CONFIG_DM_SCSI)
+ case UCLASS_SCSI: {
+ struct efi_device_path_scsi *dp =
+ dp_fill(buf, dev->parent);
+ struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+ dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
+ dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_SCSI;
+ dp->dp.length = sizeof(*dp);
+ dp->logical_unit_number = desc->lun;
+ dp->target_id = desc->target;
+ return &dp[1];
+ }
+#endif
+#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
+ case UCLASS_MMC: {
+ struct efi_device_path_sd_mmc_path *sddp =
+ dp_fill(buf, dev->parent);
+ struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+ sddp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
+ sddp->dp.sub_type = is_sd(desc) ?
+ DEVICE_PATH_SUB_TYPE_MSG_SD :
+ DEVICE_PATH_SUB_TYPE_MSG_MMC;
+ sddp->dp.length = sizeof(*sddp);
+ sddp->slot_number = dev->seq;
+ return &sddp[1];
+ }
+#endif
+ default:
+ debug("%s(%u) %s: unhandled parent class: %s (%u)\n",
+ __FILE__, __LINE__, __func__,
+ dev->name, dev->parent->uclass->uc_drv->id);
+ return dp_fill(buf, dev->parent);
+ }
+#endif
#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
case UCLASS_MMC: {
struct efi_device_path_sd_mmc_path *sddp =
@@ -359,7 +497,8 @@
return &udp[1];
}
default:
- debug("unhandled device class: %s (%u)\n",
+ debug("%s(%u) %s: unhandled device class: %s (%u)\n",
+ __FILE__, __LINE__, __func__,
dev->name, dev->driver->id);
return dp_fill(buf, dev->parent);
}
@@ -371,6 +510,8 @@
void *buf, *start;
start = buf = dp_alloc(dp_size(dev) + sizeof(END));
+ if (!buf)
+ return NULL;
buf = dp_fill(buf, dev);
*((struct efi_device_path *)buf) = END;
@@ -383,7 +524,14 @@
unsigned dpsize;
#ifdef CONFIG_BLK
- dpsize = dp_size(desc->bdev->parent);
+ {
+ struct udevice *dev;
+ int ret = blk_find_device(desc->if_type, desc->devnum, &dev);
+
+ if (ret)
+ dev = desc->bdev->parent;
+ dpsize = dp_size(dev);
+ }
#else
dpsize = sizeof(ROOT) + sizeof(struct efi_device_path_usb);
#endif
@@ -400,43 +548,16 @@
}
/*
- * Create a device path for a block device or one of its partitions.
+ * Create a device node for a block device partition.
*
* @buf buffer to which the device path is wirtten
* @desc block device descriptor
* @part partition number, 0 identifies a block device
*/
-static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
+static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
{
disk_partition_t info;
-#ifdef CONFIG_BLK
- buf = dp_fill(buf, desc->bdev->parent);
-#else
- /*
- * We *could* make a more accurate path, by looking at if_type
- * and handling all the different cases like we do for non-
- * legacy (ie CONFIG_BLK=y) case. But most important thing
- * is just to have a unique device-path for if_type+devnum.
- * So map things to a fictitious USB device.
- */
- struct efi_device_path_usb *udp;
-
- memcpy(buf, &ROOT, sizeof(ROOT));
- buf += sizeof(ROOT);
-
- udp = buf;
- udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
- udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB;
- udp->dp.length = sizeof(*udp);
- udp->parent_port_number = desc->if_type;
- udp->usb_interface = desc->devnum;
- buf = &udp[1];
-#endif
-
- if (part == 0) /* the actual disk, not a partition */
- return buf;
-
part_get_info(desc, part, &info);
if (desc->part_type == PART_TYPE_ISO) {
@@ -491,6 +612,51 @@
return buf;
}
+/*
+ * Create a device path for a block device or one of its partitions.
+ *
+ * @buf buffer to which the device path is wirtten
+ * @desc block device descriptor
+ * @part partition number, 0 identifies a block device
+ */
+static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
+{
+#ifdef CONFIG_BLK
+ {
+ struct udevice *dev;
+ int ret = blk_find_device(desc->if_type, desc->devnum, &dev);
+
+ if (ret)
+ dev = desc->bdev->parent;
+ buf = dp_fill(buf, dev);
+ }
+#else
+ /*
+ * We *could* make a more accurate path, by looking at if_type
+ * and handling all the different cases like we do for non-
+ * legacy (ie CONFIG_BLK=y) case. But most important thing
+ * is just to have a unique device-path for if_type+devnum.
+ * So map things to a fictitious USB device.
+ */
+ struct efi_device_path_usb *udp;
+
+ memcpy(buf, &ROOT, sizeof(ROOT));
+ buf += sizeof(ROOT);
+
+ udp = buf;
+ udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
+ udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB;
+ udp->dp.length = sizeof(*udp);
+ udp->parent_port_number = desc->if_type;
+ udp->usb_interface = desc->devnum;
+ buf = &udp[1];
+#endif
+
+ if (part == 0) /* the actual disk, not a partition */
+ return buf;
+
+ return dp_part_node(buf, desc, part);
+}
/* Construct a device-path from a partition on a blk device: */
struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part)
@@ -498,6 +664,8 @@
void *buf, *start;
start = buf = dp_alloc(dp_part_size(desc, part) + sizeof(END));
+ if (!buf)
+ return NULL;
buf = dp_part_fill(buf, desc, part);
@@ -506,6 +674,29 @@
return start;
}
+/*
+ * Create a device node for a block device partition.
+ *
+ * @buf buffer to which the device path is wirtten
+ * @desc block device descriptor
+ * @part partition number, 0 identifies a block device
+ */
+struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part)
+{
+ efi_uintn_t dpsize;
+ void *buf;
+
+ if (desc->part_type == PART_TYPE_ISO)
+ dpsize = sizeof(struct efi_device_path_cdrom_path);
+ else
+ dpsize = sizeof(struct efi_device_path_hard_drive_path);
+ buf = dp_alloc(dpsize);
+
+ dp_part_node(buf, desc, part);
+
+ return buf;
+}
+
/* convert path to an UEFI style path (ie. DOS style backslashes and utf16) */
static void path_to_uefi(u16 *uefi, const char *path)
{
@@ -536,6 +727,8 @@
dpsize += fpsize;
start = buf = dp_alloc(dpsize + sizeof(END));
+ if (!buf)
+ return NULL;
if (desc)
buf = dp_part_fill(buf, desc, part);
@@ -570,6 +763,8 @@
dpsize += sizeof(*ndp);
start = buf = dp_alloc(dpsize + sizeof(END));
+ if (!buf)
+ return NULL;
#ifdef CONFIG_DM_ETH
buf = dp_fill(buf, eth_get_dev());
@@ -600,6 +795,8 @@
void *buf, *start;
start = buf = dp_alloc(sizeof(*mdp) + sizeof(END));
+ if (!buf)
+ return NULL;
mdp = buf;
mdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
@@ -619,22 +816,31 @@
* Helper to split a full device path (containing both device and file
* parts) into it's constituent parts.
*/
-void efi_dp_split_file_path(struct efi_device_path *full_path,
- struct efi_device_path **device_path,
- struct efi_device_path **file_path)
+efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
+ struct efi_device_path **device_path,
+ struct efi_device_path **file_path)
{
struct efi_device_path *p, *dp, *fp;
+ *device_path = NULL;
+ *file_path = NULL;
dp = efi_dp_dup(full_path);
+ if (!dp)
+ return EFI_OUT_OF_RESOURCES;
p = dp;
- while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH))
+ while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH)) {
p = efi_dp_next(p);
+ if (!p)
+ return EFI_OUT_OF_RESOURCES;
+ }
fp = efi_dp_dup(p);
-
+ if (!fp)
+ return EFI_OUT_OF_RESOURCES;
p->type = DEVICE_PATH_TYPE_END;
p->sub_type = DEVICE_PATH_SUB_TYPE_END;
p->length = sizeof(*p);
*device_path = dp;
*file_path = fp;
+ return EFI_SUCCESS;
}
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index 50d9e91..a79e60a 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -87,6 +87,20 @@
static char *dp_msging(char *s, struct efi_device_path *dp)
{
switch (dp->sub_type) {
+ case DEVICE_PATH_SUB_TYPE_MSG_ATAPI: {
+ struct efi_device_path_atapi *ide =
+ (struct efi_device_path_atapi *)dp;
+ s += sprintf(s, "Ata(%d,%d,%d)", ide->primary_secondary,
+ ide->slave_master, ide->logical_unit_number);
+ break;
+ }
+ case DEVICE_PATH_SUB_TYPE_MSG_SCSI: {
+ struct efi_device_path_scsi *ide =
+ (struct efi_device_path_scsi *)dp;
+ s += sprintf(s, "Scsi(%u,%u)", ide->target_id,
+ ide->logical_unit_number);
+ break;
+ }
case DEVICE_PATH_SUB_TYPE_MSG_USB: {
struct efi_device_path_usb *udp =
(struct efi_device_path_usb *)dp;
@@ -231,6 +245,8 @@
case DEVICE_PATH_TYPE_MEDIA_DEVICE:
str = dp_media(str, dp);
break;
+ case DEVICE_PATH_TYPE_END:
+ break;
default:
str = dp_unknown(str, dp);
}
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index d299fc8..ac39a65 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -14,7 +14,7 @@
#include <part.h>
#include <malloc.h>
-static const efi_guid_t efi_block_io_guid = BLOCK_IO_GUID;
+const efi_guid_t efi_block_io_guid = BLOCK_IO_GUID;
struct efi_disk_obj {
/* Generic EFI object parent class data */
@@ -91,7 +91,7 @@
}
static efi_status_t EFIAPI efi_disk_read_blocks(struct efi_block_io *this,
- u32 media_id, u64 lba, unsigned long buffer_size,
+ u32 media_id, u64 lba, efi_uintn_t buffer_size,
void *buffer)
{
void *real_buffer = buffer;
@@ -112,7 +112,7 @@
real_buffer = efi_bounce_buffer;
#endif
- EFI_ENTRY("%p, %x, %"PRIx64", %lx, %p", this, media_id, lba,
+ EFI_ENTRY("%p, %x, %" PRIx64 ", %zx, %p", this, media_id, lba,
buffer_size, buffer);
r = efi_disk_rw_blocks(this, media_id, lba, buffer_size, real_buffer,
@@ -126,7 +126,7 @@
}
static efi_status_t EFIAPI efi_disk_write_blocks(struct efi_block_io *this,
- u32 media_id, u64 lba, unsigned long buffer_size,
+ u32 media_id, u64 lba, efi_uintn_t buffer_size,
void *buffer)
{
void *real_buffer = buffer;
@@ -147,7 +147,7 @@
real_buffer = efi_bounce_buffer;
#endif
- EFI_ENTRY("%p, %x, %"PRIx64", %lx, %p", this, media_id, lba,
+ EFI_ENTRY("%p, %x, %" PRIx64 ", %zx, %p", this, media_id, lba,
buffer_size, buffer);
/* Populate bounce buffer if necessary */
@@ -175,49 +175,72 @@
};
/*
- * Find filesystem from a device-path. The passed in path 'p' probably
- * contains one or more /File(name) nodes, so the comparison stops at
- * the first /File() node, and returns the pointer to that via 'rp'.
- * This is mostly intended to be a helper to map a device-path to an
- * efi_file_handle object.
+ * Get the simple file system protocol for a file device path.
+ *
+ * The full path provided is split into device part and into a file
+ * part. The device part is used to find the handle on which the
+ * simple file system protocol is installed.
+ *
+ * @full_path device path including device and file
+ * @return simple file system protocol
*/
struct efi_simple_file_system_protocol *
-efi_fs_from_path(struct efi_device_path *fp)
+efi_fs_from_path(struct efi_device_path *full_path)
{
struct efi_object *efiobj;
- struct efi_disk_obj *diskobj;
+ struct efi_handler *handler;
+ struct efi_device_path *device_path;
+ struct efi_device_path *file_path;
+ efi_status_t ret;
- efiobj = efi_dp_find_obj(fp, NULL);
+ /* Split the path into a device part and a file part */
+ ret = efi_dp_split_file_path(full_path, &device_path, &file_path);
+ if (ret != EFI_SUCCESS)
+ return NULL;
+ efi_free_pool(file_path);
+
+ /* Get the EFI object for the partition */
+ efiobj = efi_dp_find_obj(device_path, NULL);
+ efi_free_pool(device_path);
if (!efiobj)
return NULL;
- diskobj = container_of(efiobj, struct efi_disk_obj, parent);
+ /* Find the simple file system protocol */
+ ret = efi_search_protocol(efiobj, &efi_simple_file_system_protocol_guid,
+ &handler);
+ if (ret != EFI_SUCCESS)
+ return NULL;
- return diskobj->volume;
+ /* Return the simple file system protocol for the partition */
+ return handler->protocol_interface;
}
/*
- * Create a device for a disk
+ * Create a handle for a partition or disk
*
- * @name not used
+ * @parent parent handle
+ * @dp_parent parent device path
* @if_typename interface name for block device
* @desc internal block device
* @dev_index device index for block device
* @offset offset into disk for simple partitions
+ * @return disk object
*/
-static void efi_disk_add_dev(const char *name,
- const char *if_typename,
- struct blk_desc *desc,
- int dev_index,
- lbaint_t offset,
- unsigned int part)
+static struct efi_disk_obj *efi_disk_add_dev(
+ efi_handle_t parent,
+ struct efi_device_path *dp_parent,
+ const char *if_typename,
+ struct blk_desc *desc,
+ int dev_index,
+ lbaint_t offset,
+ unsigned int part)
{
struct efi_disk_obj *diskobj;
efi_status_t ret;
/* Don't add empty devices */
if (!desc->lba)
- return;
+ return NULL;
diskobj = calloc(1, sizeof(*diskobj));
if (!diskobj)
@@ -227,7 +250,14 @@
efi_add_handle(&diskobj->parent);
/* Fill in object data */
- diskobj->dp = efi_dp_from_part(desc, part);
+ if (part) {
+ struct efi_device_path *node = efi_dp_part_node(desc, part);
+
+ diskobj->dp = efi_dp_append_node(dp_parent, node);
+ efi_free_pool(node);
+ } else {
+ diskobj->dp = efi_dp_from_part(desc, part);
+ }
diskobj->part = part;
ret = efi_add_protocol(diskobj->parent.handle, &efi_block_io_guid,
&diskobj->ops);
@@ -242,7 +272,7 @@
diskobj->dp);
ret = efi_add_protocol(diskobj->parent.handle,
&efi_simple_file_system_protocol_guid,
- &diskobj->volume);
+ diskobj->volume);
if (ret != EFI_SUCCESS)
goto out_of_memory;
}
@@ -261,20 +291,38 @@
if (part != 0)
diskobj->media.logical_partition = 1;
diskobj->ops.media = &diskobj->media;
- return;
+ return diskobj;
out_of_memory:
printf("ERROR: Out of memory\n");
+ return NULL;
}
-static int efi_disk_create_partitions(struct blk_desc *desc,
- const char *if_typename,
- int diskid,
- const char *pdevname)
+/*
+ * Create handles and protocols for the partitions of a block device
+ *
+ * @parent handle of the parent disk
+ * @blk_desc block device
+ * @if_typename interface type
+ * @diskid device number
+ * @pdevname device name
+ * @return number of partitions created
+ */
+int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
+ const char *if_typename, int diskid,
+ const char *pdevname)
{
int disks = 0;
char devname[32] = { 0 }; /* dp->str is u16[32] long */
disk_partition_t info;
int part;
+ struct efi_device_path *dp = NULL;
+ efi_status_t ret;
+ struct efi_handler *handler;
+
+ /* Get the device path of the parent */
+ ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
+ if (ret == EFI_SUCCESS)
+ dp = handler->protocol_interface;
/* Add devices for each partition */
for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
@@ -282,7 +330,7 @@
continue;
snprintf(devname, sizeof(devname), "%s:%d", pdevname,
part);
- efi_disk_add_dev(devname, if_typename, desc, diskid,
+ efi_disk_add_dev(parent, dp, if_typename, desc, diskid,
info.start, part);
disks++;
}
@@ -303,6 +351,7 @@
*/
int efi_disk_register(void)
{
+ struct efi_disk_obj *disk;
int disks = 0;
#ifdef CONFIG_BLK
struct udevice *dev;
@@ -311,19 +360,21 @@
dev;
uclass_next_device_check(&dev)) {
struct blk_desc *desc = dev_get_uclass_platdata(dev);
- const char *if_typename = dev->driver->name;
+ const char *if_typename = blk_get_if_type_name(desc->if_type);
printf("Scanning disk %s...\n", dev->name);
/* Add block device for the full device */
- efi_disk_add_dev(dev->name, if_typename, desc,
- desc->devnum, 0, 0);
-
+ disk = efi_disk_add_dev(NULL, NULL, if_typename,
+ desc, desc->devnum, 0, 0);
+ if (!disk)
+ return -ENOMEM;
disks++;
/* Partitions show up as block devices in EFI */
- disks += efi_disk_create_partitions(desc, if_typename,
- desc->devnum, dev->name);
+ disks += efi_disk_create_partitions(
+ disk->parent.handle, desc, if_typename,
+ desc->devnum, dev->name);
}
#else
int i, if_type;
@@ -353,12 +404,16 @@
if_typename, i);
/* Add block device for the full device */
- efi_disk_add_dev(devname, if_typename, desc, i, 0, 0);
+ disk = efi_disk_add_dev(NULL, NULL, if_typename, desc,
+ i, 0, 0);
+ if (!disk)
+ return -ENOMEM;
disks++;
/* Partitions show up as block devices in EFI */
- disks += efi_disk_create_partitions(desc, if_typename,
- i, devname);
+ disks += efi_disk_create_partitions(
+ disk->parent.handle, desc,
+ if_typename, i, devname);
}
}
#endif
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index af29cc4..9d2214b 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -74,6 +74,40 @@
}
/*
+ * Determine the memory types to be used for code and data.
+ *
+ * @loaded_image_info image descriptor
+ * @image_type field Subsystem of the optional header for
+ * Windows specific field
+ */
+static void efi_set_code_and_data_type(
+ struct efi_loaded_image *loaded_image_info,
+ uint16_t image_type)
+{
+ switch (image_type) {
+ case IMAGE_SUBSYSTEM_EFI_APPLICATION:
+ loaded_image_info->image_code_type = EFI_LOADER_CODE;
+ loaded_image_info->image_data_type = EFI_LOADER_DATA;
+ break;
+ case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
+ loaded_image_info->image_code_type = EFI_BOOT_SERVICES_CODE;
+ loaded_image_info->image_data_type = EFI_BOOT_SERVICES_DATA;
+ break;
+ case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+ case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
+ loaded_image_info->image_code_type = EFI_RUNTIME_SERVICES_CODE;
+ loaded_image_info->image_data_type = EFI_RUNTIME_SERVICES_DATA;
+ break;
+ default:
+ printf("%s: invalid image type: %u\n", __func__, image_type);
+ /* Let's assume it is an application */
+ loaded_image_info->image_code_type = EFI_LOADER_CODE;
+ loaded_image_info->image_data_type = EFI_LOADER_DATA;
+ break;
+ }
+}
+
+/*
* This function loads all sections from a PE binary into a newly reserved
* piece of memory. On successful load it then returns the entry point for
* the binary. Otherwise NULL.
@@ -94,7 +128,6 @@
unsigned long virt_size = 0;
bool can_run_nt64 = true;
bool can_run_nt32 = true;
- uint16_t image_type;
#if defined(CONFIG_ARM64)
can_run_nt32 = false;
@@ -131,55 +164,38 @@
IMAGE_NT_HEADERS64 *nt64 = (void *)nt;
IMAGE_OPTIONAL_HEADER64 *opt = &nt64->OptionalHeader;
image_size = opt->SizeOfImage;
- efi_reloc = efi_alloc(virt_size, EFI_LOADER_DATA);
+ efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
+ efi_reloc = efi_alloc(virt_size,
+ loaded_image_info->image_code_type);
if (!efi_reloc) {
- printf("%s: Could not allocate %ld bytes\n",
- __func__, virt_size);
+ printf("%s: Could not allocate %lu bytes\n",
+ __func__, virt_size);
return NULL;
}
entry = efi_reloc + opt->AddressOfEntryPoint;
rel_size = opt->DataDirectory[rel_idx].Size;
rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
- image_type = opt->Subsystem;
} else if (can_run_nt32 &&
(nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)) {
IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader;
image_size = opt->SizeOfImage;
- efi_reloc = efi_alloc(virt_size, EFI_LOADER_DATA);
+ efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
+ efi_reloc = efi_alloc(virt_size,
+ loaded_image_info->image_code_type);
if (!efi_reloc) {
- printf("%s: Could not allocate %ld bytes\n",
- __func__, virt_size);
+ printf("%s: Could not allocate %lu bytes\n",
+ __func__, virt_size);
return NULL;
}
entry = efi_reloc + opt->AddressOfEntryPoint;
rel_size = opt->DataDirectory[rel_idx].Size;
rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
- image_type = opt->Subsystem;
} else {
printf("%s: Invalid optional header magic %x\n", __func__,
nt->OptionalHeader.Magic);
return NULL;
}
- switch (image_type) {
- case IMAGE_SUBSYSTEM_EFI_APPLICATION:
- loaded_image_info->image_code_type = EFI_LOADER_CODE;
- loaded_image_info->image_data_type = EFI_LOADER_DATA;
- break;
- case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
- loaded_image_info->image_code_type = EFI_BOOT_SERVICES_CODE;
- loaded_image_info->image_data_type = EFI_BOOT_SERVICES_DATA;
- break;
- case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
- case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
- loaded_image_info->image_code_type = EFI_RUNTIME_SERVICES_CODE;
- loaded_image_info->image_data_type = EFI_RUNTIME_SERVICES_DATA;
- break;
- default:
- printf("%s: invalid image type: %u\n", __func__, image_type);
- break;
- }
-
/* Load sections into RAM */
for (i = num_sections - 1; i >= 0; i--) {
IMAGE_SECTION_HEADER *sec = §ions[i];
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 0aa3e08..aaf6442 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -275,6 +275,15 @@
return 0;
}
+/*
+ * Allocate memory pages.
+ *
+ * @type type of allocation to be performed
+ * @memory_type usage type of the allocated memory
+ * @pages number of pages to be allocated
+ * @memory allocated memory
+ * @return status code
+ */
efi_status_t efi_allocate_pages(int type, int memory_type,
efi_uintn_t pages, uint64_t *memory)
{
@@ -338,6 +347,13 @@
return NULL;
}
+/*
+ * Free memory pages.
+ *
+ * @memory start of the memory area to be freed
+ * @pages number of pages to be freed
+ * @return status code
+ */
efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
{
uint64_t r = 0;
@@ -351,8 +367,15 @@
return EFI_NOT_FOUND;
}
-efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size,
- void **buffer)
+/*
+ * Allocate memory from pool.
+ *
+ * @pool_type type of the pool from which memory is to be allocated
+ * @size number of bytes to be allocated
+ * @buffer allocated memory
+ * @return status code
+ */
+efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
{
efi_status_t r;
efi_physical_addr_t t;
@@ -375,6 +398,12 @@
return r;
}
+/*
+ * Free memory from pool.
+ *
+ * @buffer start of memory to be freed
+ * @return status code
+ */
efi_status_t efi_free_pool(void *buffer)
{
efi_status_t r;
@@ -392,6 +421,17 @@
return r;
}
+/*
+ * Get map describing memory usage.
+ *
+ * @memory_map_size on entry the size, in bytes, of the memory map buffer,
+ * on exit the size of the copied memory map
+ * @memory_map buffer to which the memory map is written
+ * @map_key key for the memory map
+ * @descriptor_size size of an individual memory descriptor
+ * @descriptor_version version number of the memory descriptor structure
+ * @return status code
+ */
efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
struct efi_mem_desc *memory_map,
efi_uintn_t *map_key,
diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c
index b8c147d..1ec0179 100644
--- a/lib/efi_loader/helloworld.c
+++ b/lib/efi_loader/helloworld.c
@@ -14,6 +14,22 @@
#include <efi_api.h>
static const efi_guid_t loaded_image_guid = LOADED_IMAGE_GUID;
+static const efi_guid_t fdt_guid = EFI_FDT_GUID;
+static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
+
+static int hw_memcmp(const void *buf1, const void *buf2, size_t length)
+{
+ const u8 *pos1 = buf1;
+ const u8 *pos2 = buf2;
+
+ for (; length; --length) {
+ if (*pos1 != *pos2)
+ return *pos1 - *pos2;
+ ++pos1;
+ ++pos2;
+ }
+ return 0;
+}
/*
* Entry point of the EFI application.
@@ -29,6 +45,7 @@
struct efi_boot_services *boottime = systable->boottime;
struct efi_loaded_image *loaded_image;
efi_status_t ret;
+ efi_uintn_t i;
con_out->output_string(con_out, L"Hello, world!\n");
@@ -40,6 +57,15 @@
L"Cannot open loaded image protocol\n");
goto out;
}
+ /* Find configuration tables */
+ for (i = 0; i < systable->nr_tables; ++i) {
+ if (!hw_memcmp(&systable->tables[i].guid, &fdt_guid,
+ sizeof(efi_guid_t)))
+ con_out->output_string(con_out, L"Have device tree\n");
+ if (!hw_memcmp(&systable->tables[i].guid, &smbios_guid,
+ sizeof(efi_guid_t)))
+ con_out->output_string(con_out, L"Have SMBIOS table\n");
+ }
/* Output the load options */
con_out->output_string(con_out, L"Load options: ");
if (loaded_image->load_options_size && loaded_image->load_options)
diff --git a/lib/efi_selftest/.gitignore b/lib/efi_selftest/.gitignore
new file mode 100644
index 0000000..c527e46
--- /dev/null
+++ b/lib/efi_selftest/.gitignore
@@ -0,0 +1,2 @@
+efi_miniapp_file_image.h
+*.efi
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 837e862..90246f7 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -7,8 +7,12 @@
# This file only gets included with CONFIG_EFI_LOADER set, so all
# object inclusion implicitly depends on it
+CFLAGS_efi_selftest_miniapp.o := $(CFLAGS_EFI) -Os -ffreestanding
+CFLAGS_REMOVE_efi_selftest_miniapp.o := $(CFLAGS_NON_EFI) -Os
+
obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += \
efi_selftest.o \
+efi_selftest_controllers.o \
efi_selftest_console.o \
efi_selftest_devicepath.o \
efi_selftest_events.o \
@@ -20,3 +24,39 @@
efi_selftest_tpl.o \
efi_selftest_util.o \
efi_selftest_watchdog.o
+
+ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy)
+obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += efi_selftest_block_device.o
+endif
+
+# TODO: As of v2018.01 the relocation code for the EFI application cannot
+# be built on x86_64.
+ifeq ($(CONFIG_X86_64),)
+
+ifneq ($(CONFIG_CMD_BOOTEFI_SELFTEST),)
+
+obj-y += \
+efi_selftest_startimage_exit.o \
+efi_selftest_startimage_return.o
+
+targets += \
+efi_miniapp_file_image_exit.h \
+efi_miniapp_file_image_return.h \
+efi_selftest_miniapp_exit.efi \
+efi_selftest_miniapp_return.efi
+
+$(obj)/efi_miniapp_file_image_exit.h: $(obj)/efi_selftest_miniapp_exit.efi
+ $(obj)/../../tools/file2include $(obj)/efi_selftest_miniapp_exit.efi > \
+ $(obj)/efi_miniapp_file_image_exit.h
+
+$(obj)/efi_miniapp_file_image_return.h: $(obj)/efi_selftest_miniapp_return.efi
+ $(obj)/../../tools/file2include $(obj)/efi_selftest_miniapp_return.efi > \
+ $(obj)/efi_miniapp_file_image_return.h
+
+$(obj)/efi_selftest_startimage_exit.o: $(obj)/efi_miniapp_file_image_exit.h
+
+$(obj)/efi_selftest_startimage_return.o: $(obj)/efi_miniapp_file_image_return.h
+
+endif
+
+endif
diff --git a/lib/efi_selftest/efi_selftest.c b/lib/efi_selftest/efi_selftest.c
index 4e5a12c..fc5ef25 100644
--- a/lib/efi_selftest/efi_selftest.c
+++ b/lib/efi_selftest/efi_selftest.c
@@ -65,7 +65,7 @@
efi_st_error("ExitBootServices did not return EFI_SUCCESS\n");
return;
}
- efi_st_printf("\nBoot services terminated\n");
+ efi_st_printc(EFI_WHITE, "\nBoot services terminated\n");
}
/*
@@ -81,13 +81,14 @@
if (!test->setup)
return EFI_ST_SUCCESS;
- efi_st_printf("\nSetting up '%s'\n", test->name);
+ efi_st_printc(EFI_LIGHTBLUE, "\nSetting up '%s'\n", test->name);
ret = test->setup(handle, systable);
if (ret != EFI_ST_SUCCESS) {
efi_st_error("Setting up '%s' failed\n", test->name);
++*failures;
} else {
- efi_st_printf("Setting up '%s' succeeded\n", test->name);
+ efi_st_printc(EFI_LIGHTGREEN,
+ "Setting up '%s' succeeded\n", test->name);
}
return ret;
}
@@ -105,13 +106,14 @@
if (!test->execute)
return EFI_ST_SUCCESS;
- efi_st_printf("\nExecuting '%s'\n", test->name);
+ efi_st_printc(EFI_LIGHTBLUE, "\nExecuting '%s'\n", test->name);
ret = test->execute();
if (ret != EFI_ST_SUCCESS) {
efi_st_error("Executing '%s' failed\n", test->name);
++*failures;
} else {
- efi_st_printf("Executing '%s' succeeded\n", test->name);
+ efi_st_printc(EFI_LIGHTGREEN,
+ "Executing '%s' succeeded\n", test->name);
}
return ret;
}
@@ -129,13 +131,14 @@
if (!test->teardown)
return EFI_ST_SUCCESS;
- efi_st_printf("\nTearing down '%s'\n", test->name);
+ efi_st_printc(EFI_LIGHTBLUE, "\nTearing down '%s'\n", test->name);
ret = test->teardown();
if (ret != EFI_ST_SUCCESS) {
efi_st_error("Tearing down '%s' failed\n", test->name);
++*failures;
} else {
- efi_st_printf("Tearing down '%s' succeeded\n", test->name);
+ efi_st_printc(EFI_LIGHTGREEN,
+ "Tearing down '%s' succeeded\n", test->name);
}
return ret;
}
@@ -262,12 +265,12 @@
}
}
- efi_st_printf("\nTesting EFI API implementation\n");
+ efi_st_printc(EFI_WHITE, "\nTesting EFI API implementation\n");
if (testname)
- efi_st_printf("\nSelected test: '%ps'\n", testname);
+ efi_st_printc(EFI_WHITE, "\nSelected test: '%ps'\n", testname);
else
- efi_st_printf("\nNumber of tests to execute: %u\n",
+ efi_st_printc(EFI_WHITE, "\nNumber of tests to execute: %u\n",
ll_entry_count(struct efi_unit_test,
efi_unit_test));
@@ -291,7 +294,7 @@
&failures);
/* Give feedback */
- efi_st_printf("\nSummary: %u failures\n\n", failures);
+ efi_st_printc(EFI_WHITE, "\nSummary: %u failures\n\n", failures);
/* Reset system */
efi_st_printf("Preparing for reset. Press any key.\n");
diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c
new file mode 100644
index 0000000..9e4b93d
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_block_device.c
@@ -0,0 +1,395 @@
+/*
+ * efi_selftest_block
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This test checks the driver for block IO devices.
+ * A disk image is created in memory.
+ * A handle is created for the new block IO device.
+ * The block I/O protocol is installed on the handle.
+ * ConnectController is used to setup partitions and to install the simple
+ * file protocol.
+ * A known file is read from the file system and verified.
+ */
+
+#include <efi_selftest.h>
+#include "efi_selftest_disk_image.h"
+
+/* Block size of compressed disk image */
+#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8
+
+/* Binary logarithm of the block size */
+#define LB_BLOCK_SIZE 9
+
+static struct efi_boot_services *boottime;
+
+static const efi_guid_t block_io_protocol_guid = BLOCK_IO_GUID;
+static const efi_guid_t guid_device_path = DEVICE_PATH_GUID;
+static const efi_guid_t guid_simple_file_system_protocol =
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
+static efi_guid_t guid_vendor =
+ EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d,
+ 0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xb7, 0xb8);
+
+static struct efi_device_path *dp;
+
+/* One 8 byte block of the compressed disk image */
+struct line {
+ size_t addr;
+ char *line;
+};
+
+/* Compressed disk image */
+struct compressed_disk_image {
+ size_t length;
+ struct line lines[];
+};
+
+static const struct compressed_disk_image img = EFI_ST_DISK_IMG;
+
+/* Decompressed disk image */
+static u8 *image;
+
+/*
+ * Reset service of the block IO protocol.
+ *
+ * @this block IO protocol
+ * @return status code
+ */
+static efi_status_t EFIAPI reset(
+ struct efi_block_io *this,
+ char extended_verification)
+{
+ return EFI_SUCCESS;
+}
+
+/*
+ * Read service of the block IO protocol.
+ *
+ * @this block IO protocol
+ * @media_id media id
+ * @lba start of the read in logical blocks
+ * @buffer_size number of bytes to read
+ * @buffer target buffer
+ * @return status code
+ */
+static efi_status_t EFIAPI read_blocks(
+ struct efi_block_io *this, u32 media_id, u64 lba,
+ efi_uintn_t buffer_size, void *buffer)
+{
+ u8 *start;
+
+ if ((lba << LB_BLOCK_SIZE) + buffer_size > img.length)
+ return EFI_INVALID_PARAMETER;
+ start = image + (lba << LB_BLOCK_SIZE);
+
+ boottime->copy_mem(buffer, start, buffer_size);
+
+ return EFI_SUCCESS;
+}
+
+/*
+ * Write service of the block IO protocol.
+ *
+ * @this block IO protocol
+ * @media_id media id
+ * @lba start of the write in logical blocks
+ * @buffer_size number of bytes to read
+ * @buffer source buffer
+ * @return status code
+ */
+static efi_status_t EFIAPI write_blocks(
+ struct efi_block_io *this, u32 media_id, u64 lba,
+ efi_uintn_t buffer_size, void *buffer)
+{
+ u8 *start;
+
+ if ((lba << LB_BLOCK_SIZE) + buffer_size > img.length)
+ return EFI_INVALID_PARAMETER;
+ start = image + (lba << LB_BLOCK_SIZE);
+
+ boottime->copy_mem(start, buffer, buffer_size);
+
+ return EFI_SUCCESS;
+}
+
+/*
+ * Flush service of the block IO protocol.
+ *
+ * @this block IO protocol
+ * @return status code
+ */
+static efi_status_t EFIAPI flush_blocks(struct efi_block_io *this)
+{
+ return EFI_SUCCESS;
+}
+
+/*
+ * Decompress the disk image.
+ *
+ * @image decompressed disk image
+ * @return status code
+ */
+static efi_status_t decompress(u8 **image)
+{
+ u8 *buf;
+ size_t i;
+ size_t addr;
+ size_t len;
+ efi_status_t ret;
+
+ ret = boottime->allocate_pool(EFI_LOADER_DATA, img.length,
+ (void **)&buf);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Out of memory\n");
+ return ret;
+ }
+ boottime->set_mem(buf, img.length, 0);
+
+ for (i = 0; ; ++i) {
+ if (!img.lines[i].line)
+ break;
+ addr = img.lines[i].addr;
+ len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE;
+ if (addr + len > img.length)
+ len = img.length - addr;
+ boottime->copy_mem(buf + addr, img.lines[i].line, len);
+ }
+ *image = buf;
+ return ret;
+}
+
+static struct efi_block_io_media media;
+
+static struct efi_block_io block_io = {
+ .media = &media,
+ .reset = reset,
+ .read_blocks = read_blocks,
+ .write_blocks = write_blocks,
+ .flush_blocks = flush_blocks,
+};
+
+/* Handle for the block IO device */
+static efi_handle_t disk_handle;
+
+/*
+ * Setup unit test.
+ *
+ * @handle: handle of the loaded image
+ * @systable: system table
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+ const struct efi_system_table *systable)
+{
+ efi_status_t ret;
+ struct efi_device_path_vendor vendor_node;
+ struct efi_device_path end_node;
+
+ boottime = systable->boottime;
+
+ decompress(&image);
+
+ block_io.media->block_size = 1 << LB_BLOCK_SIZE;
+ block_io.media->last_block = img.length >> LB_BLOCK_SIZE;
+
+ ret = boottime->install_protocol_interface(
+ &disk_handle, &block_io_protocol_guid,
+ EFI_NATIVE_INTERFACE, &block_io);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to install block I/O protocol\n");
+ return EFI_ST_FAILURE;
+ }
+
+ ret = boottime->allocate_pool(EFI_LOADER_DATA,
+ sizeof(struct efi_device_path_vendor) +
+ sizeof(struct efi_device_path),
+ (void **)&dp);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Out of memory\n");
+ return EFI_ST_FAILURE;
+ }
+ vendor_node.dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
+ vendor_node.dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
+ vendor_node.dp.length = sizeof(struct efi_device_path_vendor);
+
+ boottime->copy_mem(&vendor_node.guid, &guid_vendor,
+ sizeof(efi_guid_t));
+ boottime->copy_mem(dp, &vendor_node,
+ sizeof(struct efi_device_path_vendor));
+ end_node.type = DEVICE_PATH_TYPE_END;
+ end_node.sub_type = DEVICE_PATH_SUB_TYPE_END;
+ end_node.length = sizeof(struct efi_device_path);
+
+ boottime->copy_mem((char *)dp + sizeof(struct efi_device_path_vendor),
+ &end_node, sizeof(struct efi_device_path));
+ ret = boottime->install_protocol_interface(&disk_handle,
+ &guid_device_path,
+ EFI_NATIVE_INTERFACE,
+ dp);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("InstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Tear down unit test.
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int teardown(void)
+{
+ efi_status_t r = EFI_ST_SUCCESS;
+
+ if (disk_handle) {
+ r = boottime->uninstall_protocol_interface(disk_handle,
+ &guid_device_path,
+ dp);
+ if (r != EFI_SUCCESS) {
+ efi_st_error("Uninstall device path failed\n");
+ return EFI_ST_FAILURE;
+ }
+ r = boottime->uninstall_protocol_interface(
+ disk_handle, &block_io_protocol_guid,
+ &block_io);
+ if (r != EFI_SUCCESS) {
+ efi_st_todo(
+ "Failed to uninstall block I/O protocol\n");
+ return EFI_ST_SUCCESS;
+ }
+ }
+
+ if (image) {
+ r = efi_free_pool(image);
+ if (r != EFI_SUCCESS) {
+ efi_st_error("Failed to free image\n");
+ return EFI_ST_FAILURE;
+ }
+ }
+ return r;
+}
+
+/*
+ * Get length of device path without end tag.
+ *
+ * @dp device path
+ * @return length of device path in bytes
+ */
+static efi_uintn_t dp_size(struct efi_device_path *dp)
+{
+ struct efi_device_path *pos = dp;
+
+ while (pos->type != DEVICE_PATH_TYPE_END)
+ pos = (struct efi_device_path *)((char *)pos + pos->length);
+ return (char *)pos - (char *)dp;
+}
+
+/*
+ * Execute unit test.
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+ efi_status_t ret;
+ efi_uintn_t no_handles, i, len;
+ efi_handle_t *handles;
+ efi_handle_t handle_partition = NULL;
+ struct efi_device_path *dp_partition;
+ struct efi_simple_file_system_protocol *file_system;
+ struct efi_file_handle *root, *file;
+ u64 buf_size;
+ char buf[16] __aligned(ARCH_DMA_MINALIGN);
+
+ ret = boottime->connect_controller(disk_handle, NULL, NULL, 1);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to connect controller\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->locate_handle_buffer(
+ BY_PROTOCOL, &guid_device_path, NULL,
+ &no_handles, &handles);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to locate handles\n");
+ return EFI_ST_FAILURE;
+ }
+ len = dp_size(dp);
+ for (i = 0; i < no_handles; ++i) {
+ ret = boottime->open_protocol(handles[i], &guid_device_path,
+ (void **)&dp_partition,
+ NULL, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to open device path protocol\n");
+ return EFI_ST_FAILURE;
+ }
+ if (len >= dp_size(dp_partition))
+ continue;
+ if (efi_st_memcmp(dp, dp_partition, len))
+ continue;
+ handle_partition = handles[i];
+ break;
+ }
+ ret = boottime->free_pool(handles);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to free pool memory\n");
+ return EFI_ST_FAILURE;
+ }
+ if (!handle_partition) {
+ efi_st_error("Partition handle not found\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->open_protocol(handle_partition,
+ &guid_simple_file_system_protocol,
+ (void **)&file_system, NULL, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to open simple file system protocol\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = file_system->open_volume(file_system, &root);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to open volume\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = root->open(root, &file, (s16 *)L"hello.txt", EFI_FILE_MODE_READ,
+ 0);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to open file\n");
+ return EFI_ST_FAILURE;
+ }
+ buf_size = sizeof(buf) - 1;
+ ret = file->read(file, &buf_size, buf);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to read file\n");
+ return EFI_ST_FAILURE;
+ }
+ if (efi_st_memcmp(buf, "Hello world!", 12)) {
+ efi_st_error("Unexpected file content\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = file->close(file);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to close file\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = root->close(root);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to close volume\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(blkdev) = {
+ .name = "block device",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+ .teardown = teardown,
+};
diff --git a/lib/efi_selftest/efi_selftest_console.c b/lib/efi_selftest/efi_selftest_console.c
index 6a7fd20..e1649f4 100644
--- a/lib/efi_selftest/efi_selftest_console.c
+++ b/lib/efi_selftest/efi_selftest_console.c
@@ -130,22 +130,25 @@
}
/*
- * Print a formatted string to the EFI console
+ * Print a colored formatted string to the EFI console
*
- * @fmt: format string
- * @...: optional arguments
+ * @color color, see constants in efi_api.h, use -1 for no color
+ * @fmt format string
+ * @... optional arguments
*/
-void efi_st_printf(const char *fmt, ...)
+void efi_st_printc(int color, const char *fmt, ...)
{
va_list args;
u16 buf[160];
const char *c;
u16 *pos = buf;
const char *s;
- const u16 *u;
+ u16 *u;
va_start(args, fmt);
+ if (color >= 0)
+ con_out->set_attribute(con_out, (unsigned long)color);
c = fmt;
for (; *c; ++c) {
switch (*c) {
@@ -188,9 +191,13 @@
/* u16 string */
case 's':
u = va_arg(args, u16*);
- /* Ensure string fits into buffer */
- for (; *u && pos < buf + 120; ++u)
- *pos++ = *u;
+ if (pos > buf) {
+ *pos = 0;
+ con_out->output_string(con_out,
+ buf);
+ }
+ con_out->output_string(con_out, u);
+ pos = buf;
break;
default:
--c;
@@ -216,6 +223,8 @@
va_end(args);
*pos = 0;
con_out->output_string(con_out, buf);
+ if (color >= 0)
+ con_out->set_attribute(con_out, EFI_LIGHTGRAY);
}
/*
diff --git a/lib/efi_selftest/efi_selftest_controllers.c b/lib/efi_selftest/efi_selftest_controllers.c
new file mode 100644
index 0000000..1a22aba
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_controllers.c
@@ -0,0 +1,385 @@
+/*
+ * efi_selftest_controllers
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This unit test checks the following protocol services:
+ * ConnectController, DisconnectController,
+ * InstallProtocol, UninstallProtocol,
+ * OpenProtocol, CloseProtcol, OpenProtocolInformation
+ */
+
+#include <efi_selftest.h>
+
+#define NUMBER_OF_CHILD_CONTROLLERS 4
+
+static struct efi_boot_services *boottime;
+const efi_guid_t guid_driver_binding_protocol =
+ EFI_DRIVER_BINDING_PROTOCOL_GUID;
+static efi_guid_t guid_controller =
+ EFI_GUID(0xe6ab1d96, 0x6bff, 0xdb42,
+ 0xaa, 0x05, 0xc8, 0x1f, 0x7f, 0x45, 0x26, 0x34);
+static efi_guid_t guid_child_controller =
+ EFI_GUID(0x1d41f6f5, 0x2c41, 0xddfb,
+ 0xe2, 0x9b, 0xb8, 0x0e, 0x2e, 0xe8, 0x3a, 0x85);
+static efi_handle_t handle_controller;
+static efi_handle_t handle_child_controller[NUMBER_OF_CHILD_CONTROLLERS];
+static efi_handle_t handle_driver;
+
+/*
+ * Count child controllers
+ *
+ * @handle handle on which child controllers are installed
+ * @protocol protocol for which the child controlles where installed
+ * @count number of child controllers
+ * @return status code
+ */
+static efi_status_t count_child_controllers(efi_handle_t handle,
+ efi_guid_t *protocol,
+ efi_uintn_t *count)
+{
+ efi_status_t ret;
+ efi_uintn_t entry_count;
+ struct efi_open_protocol_info_entry *entry_buffer;
+
+ *count = 0;
+ ret = boottime->open_protocol_information(handle, protocol,
+ &entry_buffer, &entry_count);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ if (!entry_count)
+ return EFI_SUCCESS;
+ while (entry_count) {
+ if (entry_buffer[--entry_count].attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
+ ++*count;
+ }
+ ret = boottime->free_pool(entry_buffer);
+ if (ret != EFI_SUCCESS)
+ efi_st_error("Cannot free buffer\n");
+ return ret;
+}
+
+/*
+ * Check if the driver supports the controller.
+ *
+ * @this driver binding protocol
+ * @controller_handle handle of the controller
+ * @remaining_device_path path specifying the child controller
+ * @return status code
+ */
+static efi_status_t EFIAPI supported(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path)
+{
+ efi_status_t ret;
+ void *interface;
+
+ ret = boottime->open_protocol(
+ controller_handle, &guid_controller,
+ &interface, handle_driver,
+ controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER);
+ switch (ret) {
+ case EFI_ACCESS_DENIED:
+ case EFI_ALREADY_STARTED:
+ return ret;
+ case EFI_SUCCESS:
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+ ret = boottime->close_protocol(
+ controller_handle, &guid_controller,
+ handle_driver, controller_handle);
+ if (ret != EFI_SUCCESS)
+ ret = EFI_UNSUPPORTED;
+ return ret;
+}
+
+/*
+ * Create child controllers and attach driver.
+ *
+ * @this driver binding protocol
+ * @controller_handle handle of the controller
+ * @remaining_device_path path specifying the child controller
+ * @return status code
+ */
+static efi_status_t EFIAPI start(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path)
+{
+ size_t i;
+ efi_status_t ret;
+ void *interface;
+
+ /* Attach driver to controller */
+ ret = boottime->open_protocol(
+ controller_handle, &guid_controller,
+ &interface, handle_driver,
+ controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER);
+ switch (ret) {
+ case EFI_ACCESS_DENIED:
+ case EFI_ALREADY_STARTED:
+ return ret;
+ case EFI_SUCCESS:
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ /* Create child controllers */
+ for (i = 0; i < NUMBER_OF_CHILD_CONTROLLERS; ++i) {
+ ret = boottime->install_protocol_interface(
+ &handle_child_controller[i], &guid_child_controller,
+ EFI_NATIVE_INTERFACE, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("InstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->open_protocol(
+ controller_handle, &guid_controller,
+ &interface, handle_child_controller[i],
+ handle_child_controller[i],
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("OpenProtocol failed\n");
+ return EFI_ST_FAILURE;
+ }
+ }
+ return ret;
+}
+
+/*
+ * Remove a single child controller from the parent controller.
+ *
+ * @controller_handle parent controller
+ * @child_handle child controller
+ * @return status code
+ */
+static efi_status_t disconnect_child(efi_handle_t controller_handle,
+ efi_handle_t child_handle)
+{
+ efi_status_t ret;
+
+ ret = boottime->close_protocol(
+ controller_handle, &guid_controller,
+ child_handle, child_handle);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Cannot close protocol\n");
+ return ret;
+ }
+ ret = boottime->uninstall_protocol_interface(
+ child_handle, &guid_child_controller, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Cannot uninstall protocol interface\n");
+ return ret;
+ }
+ return ret;
+}
+
+/*
+ * Remove child controllers and disconnect the controller.
+ *
+ * @this driver binding protocol
+ * @controller_handle handle of the controller
+ * @number_of_children number of child controllers to remove
+ * @child_handle_buffer handles of the child controllers to remove
+ * @return status code
+ */
+static efi_status_t EFIAPI stop(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ size_t number_of_children,
+ efi_handle_t *child_handle_buffer)
+{
+ efi_status_t ret;
+ efi_uintn_t count;
+ struct efi_open_protocol_info_entry *entry_buffer;
+
+ /* Destroy provided child controllers */
+ if (number_of_children) {
+ efi_uintn_t i;
+
+ for (i = 0; i < number_of_children; ++i) {
+ ret = disconnect_child(controller_handle,
+ child_handle_buffer[i]);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ }
+ return EFI_SUCCESS;
+ }
+
+ /* Destroy all children */
+ ret = boottime->open_protocol_information(
+ controller_handle, &guid_controller,
+ &entry_buffer, &count);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("OpenProtocolInformation failed\n");
+ return ret;
+ }
+ while (count) {
+ if (entry_buffer[--count].attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+ ret = disconnect_child(
+ controller_handle,
+ entry_buffer[count].agent_handle);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ }
+ }
+ ret = boottime->free_pool(entry_buffer);
+ if (ret != EFI_SUCCESS)
+ efi_st_error("Cannot free buffer\n");
+
+ /* Detach driver from controller */
+ ret = boottime->close_protocol(
+ controller_handle, &guid_controller,
+ handle_driver, controller_handle);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Cannot close protocol\n");
+ return ret;
+ }
+ return EFI_SUCCESS;
+}
+
+/* Driver binding protocol interface */
+static struct efi_driver_binding_protocol binding_interface = {
+ supported,
+ start,
+ stop,
+ 0xffffffff,
+ NULL,
+ NULL,
+ };
+
+/*
+ * Setup unit test.
+ *
+ * @handle handle of the loaded image
+ * @systable system table
+ */
+static int setup(const efi_handle_t img_handle,
+ const struct efi_system_table *systable)
+{
+ efi_status_t ret;
+
+ boottime = systable->boottime;
+
+ /* Create controller handle */
+ ret = boottime->install_protocol_interface(
+ &handle_controller, &guid_controller,
+ EFI_NATIVE_INTERFACE, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("InstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Create driver handle */
+ ret = boottime->install_protocol_interface(
+ &handle_driver, &guid_driver_binding_protocol,
+ EFI_NATIVE_INTERFACE, &binding_interface);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("InstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ * The number of child controllers is checked after each of the following
+ * actions:
+ *
+ * Connect a controller to a driver.
+ * Disconnect and destroy a child controller.
+ * Disconnect and destroy the remaining child controllers.
+ *
+ * Connect a controller to a driver.
+ * Uninstall the driver protocol from the controller.
+ */
+static int execute(void)
+{
+ efi_status_t ret;
+ efi_uintn_t count;
+
+ /* Connect controller to driver */
+ ret = boottime->connect_controller(handle_controller, NULL, NULL, 1);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to connect controller\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check number of child controllers */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS) {
+ efi_st_error("Number of children %u != %u\n",
+ (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS);
+ }
+ /* Destroy second child controller */
+ ret = boottime->disconnect_controller(handle_controller,
+ handle_driver,
+ handle_child_controller[1]);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to disconnect child controller\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check number of child controllers */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS - 1) {
+ efi_st_error("Destroying single child controller failed\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Destroy remaining child controllers and disconnect controller */
+ ret = boottime->disconnect_controller(handle_controller, NULL, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to disconnect controller\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check number of child controllers */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret != EFI_SUCCESS || count) {
+ efi_st_error("Destroying child controllers failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Connect controller to driver */
+ ret = boottime->connect_controller(handle_controller, NULL, NULL, 1);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to connect controller\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check number of child controllers */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS) {
+ efi_st_error("Number of children %u != %u\n",
+ (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS);
+ }
+ /* Uninstall controller protocol */
+ ret = boottime->uninstall_protocol_interface(handle_controller,
+ &guid_controller, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to uninstall protocols\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check number of child controllers */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret == EFI_SUCCESS)
+ efi_st_error("Uninstall failed\n");
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(controllers) = {
+ .name = "controllers",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+};
diff --git a/lib/efi_selftest/efi_selftest_devicepath.c b/lib/efi_selftest/efi_selftest_devicepath.c
index 1ab54eb..92940c7 100644
--- a/lib/efi_selftest/efi_selftest_devicepath.c
+++ b/lib/efi_selftest/efi_selftest_devicepath.c
@@ -192,31 +192,41 @@
{
efi_status_t ret;
- ret = boottime->uninstall_protocol_interface(&handle1,
+ ret = boottime->uninstall_protocol_interface(handle1,
&guid_device_path,
dp1);
- if (ret != EFI_SUCCESS)
- efi_st_todo("UninstallProtocolInterface failed\n");
- ret = boottime->uninstall_protocol_interface(&handle1,
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->uninstall_protocol_interface(handle1,
&guid_protocol,
&interface);
- if (ret != EFI_SUCCESS)
- efi_st_todo("UninstallProtocolInterface failed\n");
- ret = boottime->uninstall_protocol_interface(&handle2,
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->uninstall_protocol_interface(handle2,
&guid_device_path,
dp2);
- if (ret != EFI_SUCCESS)
- efi_st_todo("UninstallProtocolInterface failed\n");
- ret = boottime->uninstall_protocol_interface(&handle2,
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->uninstall_protocol_interface(handle2,
&guid_protocol,
&interface);
- if (ret != EFI_SUCCESS)
- efi_st_todo("UninstallProtocolInterface failed\n");
- ret = boottime->uninstall_protocol_interface(&handle3,
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->uninstall_protocol_interface(handle3,
&guid_device_path,
dp3);
- if (ret != EFI_SUCCESS)
- efi_st_todo("UninstallProtocolInterface failed\n");
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
if (dp1) {
ret = boottime->free_pool(dp1);
if (ret != EFI_SUCCESS) {
@@ -299,17 +309,16 @@
efi_st_error("FreePool failed\n");
return EFI_ST_FAILURE;
}
- ret = boottime->close_protocol(handles[i], &guid_device_path,
- NULL, NULL);
- if (ret != EFI_SUCCESS)
- efi_st_todo("Cannot close device path protocol.\n");
+ /*
+ * CloseProtocol cannot be called without agent handle.
+ * There is no need to close the device path protocol.
+ */
}
ret = boottime->free_pool(handles);
if (ret != EFI_SUCCESS) {
efi_st_error("FreePool failed\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("\n");
/* Test ConvertDevicePathToText */
string = device_path_to_text->convert_device_path_to_text(
@@ -318,15 +327,14 @@
efi_st_error("ConvertDevicePathToText failed\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("dp2: %ps\n", string);
if (efi_st_strcmp_16_8(
string,
"/VenHw(dbca4c98-6cb0-694d-0872-819c650cbbb1)/VenHw(dbca4c98-6cb0-694d-0872-819c650cbba2)")
) {
+ efi_st_printf("dp2: %ps\n", string);
efi_st_error("Incorrect text from ConvertDevicePathToText\n");
return EFI_ST_FAILURE;
}
-
ret = boottime->free_pool(string);
if (ret != EFI_SUCCESS) {
efi_st_error("FreePool failed\n");
@@ -340,17 +348,17 @@
efi_st_error("ConvertDeviceNodeToText failed\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("dp_node: %ps\n", string);
+ if (efi_st_strcmp_16_8(string, "u-boot")) {
+ efi_st_printf("dp_node: %ps\n", string);
+ efi_st_error(
+ "Incorrect conversion by ConvertDeviceNodeToText\n");
+ return EFI_ST_FAILURE;
+ }
ret = boottime->free_pool(string);
if (ret != EFI_SUCCESS) {
efi_st_error("FreePool failed\n");
return EFI_ST_FAILURE;
}
- if (efi_st_strcmp_16_8(string, "u-boot")) {
- efi_st_error(
- "Incorrect conversion by ConvertDeviceNodeToText\n");
- return EFI_ST_FAILURE;
- }
/* Test LocateDevicePath */
remaining_dp = (struct efi_device_path *)dp3;
@@ -370,13 +378,18 @@
efi_st_error("ConvertDevicePathToText failed\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("remaining device path: %ps\n", string);
if (efi_st_strcmp_16_8(string,
"/VenHw(dbca4c98-6cb0-694d-0872-819c650cbbc3)")
) {
+ efi_st_printf("remaining device path: %ps\n", string);
efi_st_error("LocateDevicePath: wrong remaining device path\n");
return EFI_ST_FAILURE;
}
+ ret = boottime->free_pool(string);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("FreePool failed\n");
+ return EFI_ST_FAILURE;
+ }
return EFI_ST_SUCCESS;
}
diff --git a/lib/efi_selftest/efi_selftest_disk_image.h b/lib/efi_selftest/efi_selftest_disk_image.h
new file mode 100644
index 0000000..4775dac
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_disk_image.h
@@ -0,0 +1,69 @@
+/*
+ * Non-zero 8 byte strings of a disk image
+ *
+ * Generated with tools/file2include
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#define EFI_ST_DISK_IMG { 0x00010000, { \
+ {0x000001b8, "\x94\x37\x69\xfc\x00\x00\x00\x00"}, /* .7i..... */ \
+ {0x000001c0, "\x02\x00\x83\x02\x02\x00\x01\x00"}, /* ........ */ \
+ {0x000001c8, "\x00\x00\x7f\x00\x00\x00\x00\x00"}, /* ........ */ \
+ {0x000001f8, "\x00\x00\x00\x00\x00\x00\x55\xaa"}, /* ......U. */ \
+ {0x00000200, "\xeb\x3c\x90\x6d\x6b\x66\x73\x2e"}, /* .<.mkfs. */ \
+ {0x00000208, "\x66\x61\x74\x00\x02\x04\x01\x00"}, /* fat..... */ \
+ {0x00000210, "\x02\x00\x02\x7f\x00\xf8\x01\x00"}, /* ........ */ \
+ {0x00000218, "\x20\x00\x40\x00\x00\x00\x00\x00"}, /* .@..... */ \
+ {0x00000220, "\x00\x00\x00\x00\x80\x00\x29\x86"}, /* ......). */ \
+ {0x00000228, "\xe8\x82\x80\x4e\x4f\x20\x4e\x41"}, /* ...NO NA */ \
+ {0x00000230, "\x4d\x45\x20\x20\x20\x20\x46\x41"}, /* ME FA */ \
+ {0x00000238, "\x54\x31\x32\x20\x20\x20\x0e\x1f"}, /* T12 .. */ \
+ {0x00000240, "\xbe\x5b\x7c\xac\x22\xc0\x74\x0b"}, /* .[|.".t. */ \
+ {0x00000248, "\x56\xb4\x0e\xbb\x07\x00\xcd\x10"}, /* V....... */ \
+ {0x00000250, "\x5e\xeb\xf0\x32\xe4\xcd\x16\xcd"}, /* ^..2.... */ \
+ {0x00000258, "\x19\xeb\xfe\x54\x68\x69\x73\x20"}, /* ...This */ \
+ {0x00000260, "\x69\x73\x20\x6e\x6f\x74\x20\x61"}, /* is not a */ \
+ {0x00000268, "\x20\x62\x6f\x6f\x74\x61\x62\x6c"}, /* bootabl */ \
+ {0x00000270, "\x65\x20\x64\x69\x73\x6b\x2e\x20"}, /* e disk. */ \
+ {0x00000278, "\x20\x50\x6c\x65\x61\x73\x65\x20"}, /* Please */ \
+ {0x00000280, "\x69\x6e\x73\x65\x72\x74\x20\x61"}, /* insert a */ \
+ {0x00000288, "\x20\x62\x6f\x6f\x74\x61\x62\x6c"}, /* bootabl */ \
+ {0x00000290, "\x65\x20\x66\x6c\x6f\x70\x70\x79"}, /* e floppy */ \
+ {0x00000298, "\x20\x61\x6e\x64\x0d\x0a\x70\x72"}, /* and..pr */ \
+ {0x000002a0, "\x65\x73\x73\x20\x61\x6e\x79\x20"}, /* ess any */ \
+ {0x000002a8, "\x6b\x65\x79\x20\x74\x6f\x20\x74"}, /* key to t */ \
+ {0x000002b0, "\x72\x79\x20\x61\x67\x61\x69\x6e"}, /* ry again */ \
+ {0x000002b8, "\x20\x2e\x2e\x2e\x20\x0d\x0a\x00"}, /* ... ... */ \
+ {0x000003f8, "\x00\x00\x00\x00\x00\x00\x55\xaa"}, /* ......U. */ \
+ {0x00000400, "\xf8\xff\xff\x00\x00\x00\x00\xf0"}, /* ........ */ \
+ {0x00000408, "\xff\x00\x00\x00\x00\x00\x00\x00"}, /* ........ */ \
+ {0x00000600, "\xf8\xff\xff\x00\x00\x00\x00\xf0"}, /* ........ */ \
+ {0x00000608, "\xff\x00\x00\x00\x00\x00\x00\x00"}, /* ........ */ \
+ {0x00000800, "\xe5\x70\x00\x00\x00\xff\xff\xff"}, /* .p...... */ \
+ {0x00000808, "\xff\xff\xff\x0f\x00\x0e\xff\xff"}, /* ........ */ \
+ {0x00000810, "\xff\xff\xff\xff\xff\xff\xff\xff"}, /* ........ */ \
+ {0x00000818, "\xff\xff\x00\x00\xff\xff\xff\xff"}, /* ........ */ \
+ {0x00000820, "\xe5\x2e\x00\x68\x00\x65\x00\x6c"}, /* ...h.e.l */ \
+ {0x00000828, "\x00\x6c\x00\x0f\x00\x0e\x6f\x00"}, /* .l....o. */ \
+ {0x00000830, "\x2e\x00\x74\x00\x78\x00\x74\x00"}, /* ..t.x.t. */ \
+ {0x00000838, "\x2e\x00\x00\x00\x73\x00\x77\x00"}, /* ....s.w. */ \
+ {0x00000840, "\xe5\x45\x4c\x4c\x4f\x54\x7e\x31"}, /* .ELLOT~1 */ \
+ {0x00000848, "\x53\x57\x50\x20\x00\x64\xd0\x8a"}, /* SWP .d.. */ \
+ {0x00000850, "\x92\x4b\x92\x4b\x00\x00\xd0\x8a"}, /* .K.K.... */ \
+ {0x00000858, "\x92\x4b\x00\x00\x00\x00\x00\x00"}, /* .K...... */ \
+ {0x00000860, "\x41\x68\x00\x65\x00\x6c\x00\x6c"}, /* Ah.e.l.l */ \
+ {0x00000868, "\x00\x6f\x00\x0f\x00\xf1\x2e\x00"}, /* .o...... */ \
+ {0x00000870, "\x74\x00\x78\x00\x74\x00\x00\x00"}, /* t.x.t... */ \
+ {0x00000878, "\xff\xff\x00\x00\xff\xff\xff\xff"}, /* ........ */ \
+ {0x00000880, "\x48\x45\x4c\x4c\x4f\x20\x20\x20"}, /* HELLO */ \
+ {0x00000888, "\x54\x58\x54\x20\x00\x64\xd4\x8a"}, /* TXT .d.. */ \
+ {0x00000890, "\x92\x4b\x92\x4b\x00\x00\xd4\x8a"}, /* .K.K.... */ \
+ {0x00000898, "\x92\x4b\x05\x00\x0d\x00\x00\x00"}, /* .K...... */ \
+ {0x000008a0, "\xe5\x45\x4c\x4c\x4f\x54\x7e\x31"}, /* .ELLOT~1 */ \
+ {0x000008a8, "\x53\x57\x58\x20\x00\x64\xd0\x8a"}, /* SWX .d.. */ \
+ {0x000008b0, "\x92\x4b\x92\x4b\x00\x00\xd0\x8a"}, /* .K.K.... */ \
+ {0x000008b8, "\x92\x4b\x00\x00\x00\x00\x00\x00"}, /* .K...... */ \
+ {0x00006000, "\x48\x65\x6c\x6c\x6f\x20\x77\x6f"}, /* Hello wo */ \
+ {0x00006008, "\x72\x6c\x64\x21\x0a\x00\x00\x00"}, /* rld!.... */ \
+ {0, NULL} } }
diff --git a/lib/efi_selftest/efi_selftest_events.c b/lib/efi_selftest/efi_selftest_events.c
index ad9490b..5393e39 100644
--- a/lib/efi_selftest/efi_selftest_events.c
+++ b/lib/efi_selftest/efi_selftest_events.c
@@ -142,8 +142,8 @@
efi_st_error("WaitForEvent returned wrong index\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("Notification count periodic: %u\n", timer_ticks);
if (timer_ticks < 8 || timer_ticks > 12) {
+ efi_st_printf("Notification count periodic: %u\n", timer_ticks);
efi_st_error("Incorrect timing of events\n");
return EFI_ST_FAILURE;
}
@@ -170,8 +170,9 @@
efi_st_error("Could not wait for event\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("Notification count single shot: %u\n", timer_ticks);
if (timer_ticks != 1) {
+ efi_st_printf("Notification count single shot: %u\n",
+ timer_ticks);
efi_st_error("Single shot timer failed\n");
return EFI_ST_FAILURE;
}
@@ -180,8 +181,9 @@
efi_st_error("Could not wait for event\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("Notification count stopped timer: %u\n", timer_ticks);
if (timer_ticks != 1) {
+ efi_st_printf("Notification count stopped timer: %u\n",
+ timer_ticks);
efi_st_error("Stopped timer fired\n");
return EFI_ST_FAILURE;
}
diff --git a/lib/efi_selftest/efi_selftest_manageprotocols.c b/lib/efi_selftest/efi_selftest_manageprotocols.c
index f20f152..874f861 100644
--- a/lib/efi_selftest/efi_selftest_manageprotocols.c
+++ b/lib/efi_selftest/efi_selftest_manageprotocols.c
@@ -194,7 +194,7 @@
&guid3, &interface3,
NULL);
if (ret == EFI_SUCCESS) {
- efi_st_todo("UninstallMultipleProtocolInterfaces did not catch error\n");
+ efi_st_error("UninstallMultipleProtocolInterfaces did not catch error\n");
return EFI_ST_FAILURE;
}
@@ -273,8 +273,8 @@
&guid2, &interface2,
NULL);
if (ret != EFI_SUCCESS) {
- efi_st_todo("UninstallMultipleProtocolInterfaces failed\n");
- /* This test is known to fail due to missing implementation */
+ efi_st_error("UninstallMultipleProtocolInterfaces failed\n");
+ return EFI_ST_FAILURE;
}
/*
* Check that the protocols are really uninstalled.
@@ -287,8 +287,8 @@
return EFI_ST_FAILURE;
}
if (count != 1) {
- efi_st_todo("UninstallMultipleProtocolInterfaces failed to uninstall protocols\n");
- /* This test is known to fail due to missing implementation */
+ efi_st_error("UninstallMultipleProtocolInterfaces failed to uninstall protocols\n");
+ return EFI_ST_FAILURE;
}
ret = find_in_buffer(handle1, count, buffer);
if (ret != EFI_SUCCESS) {
@@ -327,19 +327,19 @@
ret = boottime->uninstall_protocol_interface(handle1, &guid1,
&interface1);
if (ret != EFI_SUCCESS) {
- efi_st_todo("UninstallProtocolInterface failed\n");
- /* This test is known to fail due to missing implementation */
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
}
ret = boottime->handle_protocol(handle1, &guid1, (void **)&interface);
if (ret == EFI_SUCCESS) {
- efi_st_todo("UninstallProtocolInterface failed\n");
- /* This test is known to fail due to missing implementation */
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
}
ret = boottime->uninstall_protocol_interface(handle1, &guid3,
&interface1);
if (ret != EFI_SUCCESS) {
- efi_st_todo("UninstallProtocolInterface failed\n");
- /* This test is known to fail due to missing implementation */
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
}
return EFI_ST_SUCCESS;
diff --git a/lib/efi_selftest/efi_selftest_miniapp_exit.c b/lib/efi_selftest/efi_selftest_miniapp_exit.c
new file mode 100644
index 0000000..5ec57ab
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_miniapp_exit.c
@@ -0,0 +1,37 @@
+/*
+ * efi_selftest_miniapp_exit
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This EFI application is run by the StartImage selftest.
+ * It uses the Exit boot service to return.
+ */
+
+#include <common.h>
+#include <efi_api.h>
+
+/*
+ * Entry point of the EFI application.
+ *
+ * @handle handle of the loaded image
+ * @systable system table
+ * @return status code
+ */
+efi_status_t EFIAPI efi_main(efi_handle_t handle,
+ struct efi_system_table *systable)
+{
+ struct efi_simple_text_output_protocol *con_out = systable->con_out;
+
+ con_out->output_string(con_out, L"EFI application calling Exit\n");
+
+ /* The return value is checked by the calling test */
+ systable->boottime->exit(handle, EFI_UNSUPPORTED, 0, NULL);
+
+ /*
+ * This statement should not be reached.
+ * To enable testing use a different return value.
+ */
+ return EFI_SUCCESS;
+}
diff --git a/lib/efi_selftest/efi_selftest_miniapp_return.c b/lib/efi_selftest/efi_selftest_miniapp_return.c
new file mode 100644
index 0000000..0a82391
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_miniapp_return.c
@@ -0,0 +1,32 @@
+/*
+ * efi_selftest_miniapp_return
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This EFI application is run by the StartImage selftest.
+ * It returns directly without calling the Exit boot service.
+ */
+
+#include <common.h>
+#include <efi_api.h>
+
+/*
+ * Entry point of the EFI application.
+ *
+ * @handle handle of the loaded image
+ * @systable system table
+ * @return status code
+ */
+efi_status_t EFIAPI efi_main(efi_handle_t handle,
+ struct efi_system_table *systable)
+{
+ struct efi_simple_text_output_protocol *con_out = systable->con_out;
+
+ con_out->output_string(con_out,
+ L"EFI application returning w/o calling Exit\n");
+
+ /* The return value is checked by the calling test */
+ return EFI_INCOMPATIBLE_VERSION;
+}
diff --git a/lib/efi_selftest/efi_selftest_startimage_exit.c b/lib/efi_selftest/efi_selftest_startimage_exit.c
new file mode 100644
index 0000000..0809690
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_startimage_exit.c
@@ -0,0 +1,149 @@
+/*
+ * efi_selftest_start_image
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This test checks the StartImage boot service.
+ * The efi_selftest_miniapp_exit.efi application is loaded into memory
+ * and started.
+ */
+
+#include <efi_selftest.h>
+/* Include containing the miniapp.efi application */
+#include "efi_miniapp_file_image_exit.h"
+
+/* Block size of compressed disk image */
+#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8
+
+/* Binary logarithm of the block size */
+#define LB_BLOCK_SIZE 9
+
+static efi_handle_t image_handle;
+static struct efi_boot_services *boottime;
+
+/* One 8 byte block of the compressed disk image */
+struct line {
+ size_t addr;
+ char *line;
+};
+
+/* Compressed file image */
+struct compressed_file_image {
+ size_t length;
+ struct line lines[];
+};
+
+static struct compressed_file_image img = EFI_ST_DISK_IMG;
+
+/* Decompressed file image */
+static u8 *image;
+
+/*
+ * Decompress the disk image.
+ *
+ * @image decompressed disk image
+ * @return status code
+ */
+static efi_status_t decompress(u8 **image)
+{
+ u8 *buf;
+ size_t i;
+ size_t addr;
+ size_t len;
+ efi_status_t ret;
+
+ ret = boottime->allocate_pool(EFI_LOADER_DATA, img.length,
+ (void **)&buf);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Out of memory\n");
+ return ret;
+ }
+ boottime->set_mem(buf, img.length, 0);
+
+ for (i = 0; ; ++i) {
+ if (!img.lines[i].line)
+ break;
+ addr = img.lines[i].addr;
+ len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE;
+ if (addr + len > img.length)
+ len = img.length - addr;
+ boottime->copy_mem(buf + addr, img.lines[i].line, len);
+ }
+ *image = buf;
+ return ret;
+}
+
+/*
+ * Setup unit test.
+ *
+ * @handle: handle of the loaded image
+ * @systable: system table
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+ const struct efi_system_table *systable)
+{
+ image_handle = handle;
+ boottime = systable->boottime;
+
+ /* Load the application image into memory */
+ decompress(&image);
+
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Tear down unit test.
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int teardown(void)
+{
+ efi_status_t r = EFI_ST_SUCCESS;
+
+ if (image) {
+ r = efi_free_pool(image);
+ if (r != EFI_SUCCESS) {
+ efi_st_error("Failed to free image\n");
+ return EFI_ST_FAILURE;
+ }
+ }
+ return r;
+}
+
+/*
+ * Execute unit test.
+ *
+ * Load and start the application image.
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+ efi_status_t ret;
+ efi_handle_t handle;
+
+ ret = boottime->load_image(false, image_handle, NULL, image,
+ img.length, &handle);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to load image\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->start_image(handle, NULL, NULL);
+ if (ret != EFI_UNSUPPORTED) {
+ efi_st_error("Wrong return value from application\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(startimage_exit) = {
+ .name = "start image exit",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+ .teardown = teardown,
+};
diff --git a/lib/efi_selftest/efi_selftest_startimage_return.c b/lib/efi_selftest/efi_selftest_startimage_return.c
new file mode 100644
index 0000000..2209911
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_startimage_return.c
@@ -0,0 +1,149 @@
+/*
+ * efi_selftest_start_image
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This test checks the StartImage boot service.
+ * The efi_selftest_miniapp_return.efi application is loaded into memory
+ * and started.
+ */
+
+#include <efi_selftest.h>
+/* Include containing the miniapp.efi application */
+#include "efi_miniapp_file_image_return.h"
+
+/* Block size of compressed disk image */
+#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8
+
+/* Binary logarithm of the block size */
+#define LB_BLOCK_SIZE 9
+
+static efi_handle_t image_handle;
+static struct efi_boot_services *boottime;
+
+/* One 8 byte block of the compressed disk image */
+struct line {
+ size_t addr;
+ char *line;
+};
+
+/* Compressed file image */
+struct compressed_file_image {
+ size_t length;
+ struct line lines[];
+};
+
+static struct compressed_file_image img = EFI_ST_DISK_IMG;
+
+/* Decompressed file image */
+static u8 *image;
+
+/*
+ * Decompress the disk image.
+ *
+ * @image decompressed disk image
+ * @return status code
+ */
+static efi_status_t decompress(u8 **image)
+{
+ u8 *buf;
+ size_t i;
+ size_t addr;
+ size_t len;
+ efi_status_t ret;
+
+ ret = boottime->allocate_pool(EFI_LOADER_DATA, img.length,
+ (void **)&buf);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Out of memory\n");
+ return ret;
+ }
+ boottime->set_mem(buf, img.length, 0);
+
+ for (i = 0; ; ++i) {
+ if (!img.lines[i].line)
+ break;
+ addr = img.lines[i].addr;
+ len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE;
+ if (addr + len > img.length)
+ len = img.length - addr;
+ boottime->copy_mem(buf + addr, img.lines[i].line, len);
+ }
+ *image = buf;
+ return ret;
+}
+
+/*
+ * Setup unit test.
+ *
+ * @handle: handle of the loaded image
+ * @systable: system table
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+ const struct efi_system_table *systable)
+{
+ image_handle = handle;
+ boottime = systable->boottime;
+
+ /* Load the application image into memory */
+ decompress(&image);
+
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Tear down unit test.
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int teardown(void)
+{
+ efi_status_t r = EFI_ST_SUCCESS;
+
+ if (image) {
+ r = efi_free_pool(image);
+ if (r != EFI_SUCCESS) {
+ efi_st_error("Failed to free image\n");
+ return EFI_ST_FAILURE;
+ }
+ }
+ return r;
+}
+
+/*
+ * Execute unit test.
+ *
+ * Load and start the application image.
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+ efi_status_t ret;
+ efi_handle_t handle;
+
+ ret = boottime->load_image(false, image_handle, NULL, image,
+ img.length, &handle);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to load image\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->start_image(handle, NULL, NULL);
+ if (ret != EFI_INCOMPATIBLE_VERSION) {
+ efi_st_error("Wrong return value from application\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(startimage) = {
+ .name = "start image return",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+ .teardown = teardown,
+};
diff --git a/lib/efi_selftest/efi_selftest_tpl.c b/lib/efi_selftest/efi_selftest_tpl.c
index 6ea0bb7..8243fae 100644
--- a/lib/efi_selftest/efi_selftest_tpl.c
+++ b/lib/efi_selftest/efi_selftest_tpl.c
@@ -144,9 +144,10 @@
efi_st_error("WaitForEvent returned wrong index\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("Notification count with TPL level TPL_APPLICATION: %u\n",
- notification_count);
if (notification_count < 8 || notification_count > 12) {
+ efi_st_printf(
+ "Notification count with TPL level TPL_APPLICATION: %u\n",
+ notification_count);
efi_st_error("Incorrect timing of events\n");
return EFI_ST_FAILURE;
}
@@ -181,9 +182,10 @@
efi_st_error("Could not check event\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("Notification count with TPL level TPL_CALLBACK: %u\n",
- notification_count);
if (notification_count != 0) {
+ efi_st_printf(
+ "Notification count with TPL level TPL_CALLBACK: %u\n",
+ notification_count);
efi_st_error("Suppressed timer fired\n");
return EFI_ST_FAILURE;
}
@@ -200,9 +202,10 @@
efi_st_error("Could not wait for event\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("Notification count with TPL level TPL_APPLICATION: %u\n",
- notification_count);
if (notification_count < 1) {
+ efi_st_printf(
+ "Notification count with TPL level TPL_APPLICATION: %u\n",
+ notification_count);
efi_st_error("Queued timer event did not fire\n");
return EFI_ST_FAILURE;
}
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 6b138fa..df9d9ae 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -83,8 +83,9 @@
}
fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node,
- const char *prop_name, int index, int na, int ns,
- fdt_size_t *sizep, bool translate)
+ const char *prop_name, int index, int na,
+ int ns, fdt_size_t *sizep,
+ bool translate)
{
const fdt32_t *prop, *prop_end;
const fdt32_t *prop_addr, *prop_size, *prop_after_size;
@@ -138,8 +139,9 @@
}
fdt_addr_t fdtdec_get_addr_size_auto_parent(const void *blob, int parent,
- int node, const char *prop_name, int index, fdt_size_t *sizep,
- bool translate)
+ int node, const char *prop_name,
+ int index, fdt_size_t *sizep,
+ bool translate)
{
int na, ns;
@@ -164,8 +166,9 @@
}
fdt_addr_t fdtdec_get_addr_size_auto_noparent(const void *blob, int node,
- const char *prop_name, int index, fdt_size_t *sizep,
- bool translate)
+ const char *prop_name, int index,
+ fdt_size_t *sizep,
+ bool translate)
{
int parent;
@@ -182,7 +185,7 @@
}
fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
- const char *prop_name, fdt_size_t *sizep)
+ const char *prop_name, fdt_size_t *sizep)
{
int ns = sizep ? (sizeof(fdt_size_t) / sizeof(fdt32_t)) : 0;
@@ -191,15 +194,14 @@
ns, sizep, false);
}
-fdt_addr_t fdtdec_get_addr(const void *blob, int node,
- const char *prop_name)
+fdt_addr_t fdtdec_get_addr(const void *blob, int node, const char *prop_name)
{
return fdtdec_get_addr_size(blob, node, prop_name, NULL);
}
#if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI)
int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
- const char *prop_name, struct fdt_pci_addr *addr)
+ const char *prop_name, struct fdt_pci_addr *addr)
{
const u32 *cell;
int len;
@@ -231,10 +233,10 @@
addr->phys_mid = fdt32_to_cpu(cell[1]);
addr->phys_lo = fdt32_to_cpu(cell[1]);
break;
- } else {
- cell += (FDT_PCI_ADDR_CELLS +
- FDT_PCI_SIZE_CELLS);
}
+
+ cell += (FDT_PCI_ADDR_CELLS +
+ FDT_PCI_SIZE_CELLS);
}
if (i == num) {
@@ -243,10 +245,10 @@
}
return 0;
- } else {
- ret = -EINVAL;
}
+ ret = -EINVAL;
+
fail:
debug("(not found)\n");
return ret;
@@ -263,11 +265,9 @@
end = list + len;
while (list < end) {
- char *s;
-
len = strlen(list);
if (len >= strlen("pciVVVV,DDDD")) {
- s = strstr(list, "pci");
+ char *s = strstr(list, "pci");
/*
* check if the string is something like pciVVVV,DDDD.RR
@@ -297,7 +297,7 @@
/* extract the bar number from fdt_pci_addr */
barnum = addr->phys_hi & 0xff;
- if ((barnum < PCI_BASE_ADDRESS_0) || (barnum > PCI_CARDBUS_CIS))
+ if (barnum < PCI_BASE_ADDRESS_0 || barnum > PCI_CARDBUS_CIS)
return -EINVAL;
barnum = (barnum - PCI_BASE_ADDRESS_0) / 4;
@@ -308,7 +308,7 @@
#endif
uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name,
- uint64_t default_val)
+ uint64_t default_val)
{
const uint64_t *cell64;
int length;
@@ -333,7 +333,7 @@
*/
cell = fdt_getprop(blob, node, "status", NULL);
if (cell)
- return 0 == strcmp(cell, "okay");
+ return strcmp(cell, "okay") == 0;
return 1;
}
@@ -343,20 +343,19 @@
/* Search our drivers */
for (id = COMPAT_UNKNOWN; id < COMPAT_COUNT; id++)
- if (0 == fdt_node_check_compatible(blob, node,
- compat_names[id]))
+ if (fdt_node_check_compatible(blob, node,
+ compat_names[id]) == 0)
return id;
return COMPAT_UNKNOWN;
}
-int fdtdec_next_compatible(const void *blob, int node,
- enum fdt_compat_id id)
+int fdtdec_next_compatible(const void *blob, int node, enum fdt_compat_id id)
{
return fdt_node_offset_by_compatible(blob, node, compat_names[id]);
}
int fdtdec_next_compatible_subnode(const void *blob, int node,
- enum fdt_compat_id id, int *depthp)
+ enum fdt_compat_id id, int *depthp)
{
do {
node = fdt_next_node(blob, node, depthp);
@@ -370,8 +369,8 @@
return -FDT_ERR_NOTFOUND;
}
-int fdtdec_next_alias(const void *blob, const char *name,
- enum fdt_compat_id id, int *upto)
+int fdtdec_next_alias(const void *blob, const char *name, enum fdt_compat_id id,
+ int *upto)
{
#define MAX_STR_LEN 20
char str[MAX_STR_LEN + 20];
@@ -393,7 +392,8 @@
}
int fdtdec_find_aliases_for_id(const void *blob, const char *name,
- enum fdt_compat_id id, int *node_list, int maxcount)
+ enum fdt_compat_id id, int *node_list,
+ int maxcount)
{
memset(node_list, '\0', sizeof(*node_list) * maxcount);
@@ -402,7 +402,8 @@
/* TODO: Can we tighten this code up a little? */
int fdtdec_add_aliases_for_id(const void *blob, const char *name,
- enum fdt_compat_id id, int *node_list, int maxcount)
+ enum fdt_compat_id id, int *node_list,
+ int maxcount)
{
int name_len = strlen(name);
int nodes[maxcount];
@@ -429,7 +430,7 @@
}
if (node >= 0)
debug("%s: warning: maxcount exceeded with alias '%s'\n",
- __func__, name);
+ __func__, name);
/* Now find all the aliases */
for (offset = fdt_first_property_offset(blob, alias_node);
@@ -452,7 +453,7 @@
number = simple_strtoul(path + name_len, NULL, 10);
if (number < 0 || number >= maxcount) {
debug("%s: warning: alias '%s' is out of range\n",
- __func__, path);
+ __func__, path);
continue;
}
@@ -498,7 +499,7 @@
if (!node_list[i]) {
for (; j < maxcount; j++)
if (nodes[j] &&
- fdtdec_get_is_enabled(blob, nodes[j]))
+ fdtdec_get_is_enabled(blob, nodes[j]))
break;
/* Have we run out of nodes to add? */
@@ -641,7 +642,8 @@
* @return pointer to cell, which is only valid if err == 0
*/
static const void *get_prop_check_min_len(const void *blob, int node,
- const char *prop_name, int min_len, int *err)
+ const char *prop_name, int min_len,
+ int *err)
{
const void *cell;
int len;
@@ -658,15 +660,17 @@
}
int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
- u32 *array, int count)
+ u32 *array, int count)
{
const u32 *cell;
- int i, err = 0;
+ int err = 0;
debug("%s: %s\n", __func__, prop_name);
cell = get_prop_check_min_len(blob, node, prop_name,
sizeof(u32) * count, &err);
if (!err) {
+ int i;
+
for (i = 0; i < count; i++)
array[i] = fdt32_to_cpu(cell[i]);
}
@@ -850,7 +854,7 @@
}
int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name,
- u8 *array, int count)
+ u8 *array, int count)
{
const u8 *cell;
int err;
@@ -862,7 +866,7 @@
}
const u8 *fdtdec_locate_byte_array(const void *blob, int node,
- const char *prop_name, int count)
+ const char *prop_name, int count)
{
const u8 *cell;
int err;
@@ -874,7 +878,7 @@
}
int fdtdec_get_config_int(const void *blob, const char *prop_name,
- int default_val)
+ int default_val)
{
int config_node;
@@ -971,7 +975,8 @@
while (ptr + na + ns <= end) {
if (i == index) {
- res->start = res->end = fdtdec_get_number(ptr, na);
+ res->start = fdtdec_get_number(ptr, na);
+ res->end = res->start;
res->end += fdtdec_get_number(&ptr[na], ns) - 1;
return 0;
}
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index dd572d2..226f4eb 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -11,16 +11,17 @@
* from hush: simple_itoa() was lifted from boa-0.93.15
*/
-#include <stdarg.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-
#include <common.h>
#include <charset.h>
-#include <uuid.h>
-
+#include <efi_loader.h>
#include <div64.h>
+#include <uuid.h>
+#include <stdarg.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
#define noinline __attribute__((noinline))
/* we use this so that we can do without the ctype library */
@@ -292,6 +293,26 @@
return buf;
}
+#if defined(CONFIG_EFI_LOADER) && \
+ !defined(CONFIG_SPL_BUILD) && !defined(API_BUILD)
+static char *device_path_string(char *buf, char *end, void *dp, int field_width,
+ int precision, int flags)
+{
+ u16 *str;
+
+ if (!dp)
+ return "<NULL>";
+
+ str = efi_dp_str((struct efi_device_path *)dp);
+ if (!str)
+ return ERR_PTR(-ENOMEM);
+
+ buf = string16(buf, end, str, field_width, precision, flags);
+ efi_free_pool(str);
+ return buf;
+}
+#endif
+
#ifdef CONFIG_CMD_NET
static const char hex_asc[] = "0123456789abcdef";
#define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
@@ -435,6 +456,12 @@
#endif
switch (*fmt) {
+#if defined(CONFIG_EFI_LOADER) && \
+ !defined(CONFIG_SPL_BUILD) && !defined(API_BUILD)
+ case 'D':
+ return device_path_string(buf, end, ptr, field_width,
+ precision, flags);
+#endif
#ifdef CONFIG_CMD_NET
case 'a':
flags |= SPECIAL | ZEROPAD;
@@ -604,6 +631,8 @@
str = pointer(fmt + 1, str, end,
va_arg(args, void *),
field_width, precision, flags);
+ if (IS_ERR(str))
+ return PTR_ERR(str);
/* Skip all alphanumeric pointer suffixes */
while (isalnum(fmt[1]))
fmt++;
@@ -768,6 +797,9 @@
i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
va_end(args);
+ /* Handle error */
+ if (i <= 0)
+ return i;
/* Print the string */
puts(printbuffer);
return i;
@@ -784,6 +816,9 @@
*/
i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
+ /* Handle error */
+ if (i <= 0)
+ return i;
/* Print the string */
puts(printbuffer);
return i;
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index c98f262..1d3e2e8 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -344,9 +344,7 @@
CONFIG_D2NET_V2
CONFIG_DA850_AM18X_EVM
CONFIG_DA850_EVM_MAX_CPU_CLK
-CONFIG_DA850_LOWLEVEL
CONFIG_DA8XX_GPIO
-CONFIG_DAVINCI_SPI
CONFIG_DBAU1000
CONFIG_DBAU1X00
CONFIG_DBGU
@@ -602,7 +600,6 @@
CONFIG_ETHPRIME
CONFIG_ETH_BUFSIZE
CONFIG_ETH_RXSIZE
-CONFIG_EXT4_WRITE
CONFIG_EXTRA_BOOTARGS
CONFIG_EXTRA_CLOCK
CONFIG_EXTRA_ENV
@@ -752,7 +749,6 @@
CONFIG_FSMC_NAND_BASE
CONFIG_FSMTDBLK
CONFIG_FSNOTIFY
-CONFIG_FS_EXT4
CONFIG_FS_POSIX_ACL
CONFIG_FTAHBC020S
CONFIG_FTAHBC020S_BASE
@@ -1279,7 +1275,6 @@
CONFIG_MACB2_PHY
CONFIG_MACB3_PHY
CONFIG_MACB_SEARCH_PHY
-CONFIG_MACH_DAVINCI_DA850_EVM
CONFIG_MACH_OMAPL138_LCDK
CONFIG_MACH_SPECIFIC
CONFIG_MACH_TYPE
@@ -1520,15 +1515,12 @@
CONFIG_ODROID_REV_AIN
CONFIG_OFF_PADCONF
CONFIG_OF_
-CONFIG_OF_SPI
-CONFIG_OF_SPI_FLASH
CONFIG_OF_STDOUT_PATH
CONFIG_OMAP_EHCI_PHY1_RESET_GPIO
CONFIG_OMAP_EHCI_PHY2_RESET_GPIO
CONFIG_OMAP_EHCI_PHY3_RESET_GPIO
CONFIG_OMAP_USB2PHY2_HOST
CONFIG_OMAP_USB3PHY1_HOST
-CONFIG_OMAP_USB_PHY
CONFIG_ORIGEN
CONFIG_OS1_ENV_ADDR
CONFIG_OS2_ENV_ADDR
@@ -1795,7 +1787,6 @@
CONFIG_ROCKCHIP_CHIP_TAG
CONFIG_ROCKCHIP_MAX_INIT_SIZE
CONFIG_ROCKCHIP_SDHCI_MAX_FREQ
-CONFIG_ROCKCHIP_USB2_PHY
CONFIG_ROM_STUBS
CONFIG_ROOTFS_OFFSET
CONFIG_ROOTPATH
@@ -1974,8 +1965,6 @@
CONFIG_SOC_AU1500
CONFIG_SOC_AU1550
CONFIG_SOC_AU1X00
-CONFIG_SOC_DA850
-CONFIG_SOC_DA8XX
CONFIG_SOC_DM355
CONFIG_SOC_DM365
CONFIG_SOC_DM644X
@@ -2168,7 +2157,6 @@
CONFIG_SUPPORT_EMMC_BOOT
CONFIG_SUPPORT_EMMC_RPMB
CONFIG_SUPPORT_RAW_INITRD
-CONFIG_SUPPORT_VFAT
CONFIG_SUVD3
CONFIG_SXNI855T
CONFIG_SYSFLAGS_ADDR
@@ -4748,7 +4736,6 @@
CONFIG_TWL4030_INPUT
CONFIG_TWL4030_KEYPAD
CONFIG_TWL4030_LED
-CONFIG_TWL4030_USB
CONFIG_TWL6030_INPUT
CONFIG_TWL6030_POWER
CONFIG_TWR
@@ -4817,7 +4804,6 @@
CONFIG_USBID_ADDR
CONFIG_USBNET_DEV_ADDR
CONFIG_USBTTY
-CONFIG_USB_AM35X
CONFIG_USB_ATMEL
CONFIG_USB_ATMEL_CLK_SEL_PLLB
CONFIG_USB_ATMEL_CLK_SEL_UPLL
@@ -4877,21 +4863,14 @@
CONFIG_USB_INVENTRA_DMA
CONFIG_USB_ISP1301_I2C_ADDR
CONFIG_USB_MAX_CONTROLLER_COUNT
-CONFIG_USB_MUSB_AM35X
CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
-CONFIG_USB_MUSB_DSPS
-CONFIG_USB_MUSB_HCD
-CONFIG_USB_MUSB_OMAP2PLUS
-CONFIG_USB_MUSB_PIO_ONLY
CONFIG_USB_MUSB_TIMEOUT
CONFIG_USB_MUSB_TUSB6010
-CONFIG_USB_MUSB_UDC
CONFIG_USB_OHCI
CONFIG_USB_OHCI_EP93XX
CONFIG_USB_OHCI_LPC32XX
CONFIG_USB_OHCI_NEW
CONFIG_USB_OHCI_SUNXI
-CONFIG_USB_OMAP3
CONFIG_USB_OTG
CONFIG_USB_OTG_BLACKLIST_HUB
CONFIG_USB_PHY_CFG_BASE
diff --git a/test/print_ut.c b/test/print_ut.c
index a42c554..1aa68be 100644
--- a/test/print_ut.c
+++ b/test/print_ut.c
@@ -7,12 +7,46 @@
#define DEBUG
#include <common.h>
+#if defined(CONFIG_EFI_LOADER) && \
+ !defined(CONFIG_SPL_BUILD) && !defined(API_BUILD)
+#include <efi_api.h>
+#endif
#include <display_options.h>
#include <version.h>
#define FAKE_BUILD_TAG "jenkins-u-boot-denx_uboot_dm-master-build-aarch64" \
"and a lot more text to come"
+/* Test efi_loader specific printing */
+static void efi_ut_print(void)
+{
+#if defined(CONFIG_EFI_LOADER) && \
+ !defined(CONFIG_SPL_BUILD) && !defined(API_BUILD)
+ char str[10];
+ u8 buf[sizeof(struct efi_device_path_sd_mmc_path) +
+ sizeof(struct efi_device_path)];
+ u8 *pos = buf;
+ struct efi_device_path *dp_end;
+ struct efi_device_path_sd_mmc_path *dp_sd =
+ (struct efi_device_path_sd_mmc_path *)pos;
+
+ /* Create a device path for an SD card */
+ dp_sd->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
+ dp_sd->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_SD;
+ dp_sd->dp.length = sizeof(struct efi_device_path_sd_mmc_path);
+ dp_sd->slot_number = 3;
+ pos += sizeof(struct efi_device_path_sd_mmc_path);
+ /* Append end node */
+ dp_end = (struct efi_device_path *)pos;
+ dp_end->type = DEVICE_PATH_TYPE_END;
+ dp_end->sub_type = DEVICE_PATH_SUB_TYPE_END;
+ dp_end->length = sizeof(struct efi_device_path);
+
+ snprintf(str, sizeof(str), "_%pD_", buf);
+ assert(!strcmp("_/SD(3)_", str));
+#endif
+}
+
static int do_ut_print(cmd_tbl_t *cmdtp, int flag, int argc,
char *const argv[])
{
@@ -75,6 +109,9 @@
assert(!strncmp(FAKE_BUILD_TAG, s + 9 + len, 12));
assert(!strcmp("\n\n", s + big_str_len - 3));
+ /* Test efi_loader specific printing */
+ efi_ut_print();
+
printf("%s: Everything went swimmingly\n", __func__);
return 0;
}
diff --git a/tools/.gitignore b/tools/.gitignore
index 6a487d2..c8cdaef 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -6,6 +6,7 @@
/easylogo/easylogo
/envcrc
/fdtgrep
+/file2include
/fit_check_sign
/fit_info
/gdb/gdbcont
diff --git a/tools/Makefile b/tools/Makefile
index 571f571..b7d7d41 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -57,6 +57,8 @@
hostprogs-y += dumpimage mkimage
hostprogs-$(CONFIG_FIT_SIGNATURE) += fit_info fit_check_sign
+hostprogs-$(CONFIG_CMD_BOOTEFI_SELFTEST) += file2include
+
FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
# The following files are synced with upstream DTC.
@@ -118,6 +120,7 @@
mkimage-objs := $(dumpimage-mkimage-objs) mkimage.o
fit_info-objs := $(dumpimage-mkimage-objs) fit_info.o
fit_check_sign-objs := $(dumpimage-mkimage-objs) fit_check_sign.o
+file2include-objs := file2include.o
ifneq ($(CONFIG_MX23)$(CONFIG_MX28),)
# Add CONFIG_MXS into host CFLAGS, so we can check whether or not register
diff --git a/tools/file2include.c b/tools/file2include.c
new file mode 100644
index 0000000..9145f08
--- /dev/null
+++ b/tools/file2include.c
@@ -0,0 +1,106 @@
+/*
+ * Convert a file image to a C define
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * For testing EFI disk management we need an in memory image of
+ * a disk.
+ *
+ * The tool file2include converts a file to a C include. The file
+ * is separated into strings of 8 bytes. Only the non-zero strings
+ * are written to the include. The output format has been designed
+ * to maintain readability.
+ *
+ * As the disk image needed for testing contains mostly zeroes a high
+ * compression ratio can be attained.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <malloc.h>
+
+/* Size of the blocks written to the compressed file */
+#define BLOCK_SIZE 8
+
+int main(int argc, char *argv[])
+{
+ FILE *file;
+ int ret;
+ unsigned char *buf;
+ size_t count, i, j;
+
+ /* Provide usage help */
+ if (argc != 2) {
+ printf("Usage:\n%s FILENAME\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+ /* Open file */
+ file = fopen(argv[1], "r");
+ if (!file) {
+ perror("fopen");
+ return EXIT_FAILURE;
+ }
+ /* Get file length */
+ ret = fseek(file, 0, SEEK_END);
+ if (ret < 0) {
+ perror("fseek");
+ return EXIT_FAILURE;
+ }
+ count = ftell(file);
+ if (!count) {
+ fprintf(stderr, "File %s has length 0\n", argv[1]);
+ return EXIT_FAILURE;
+ }
+ rewind(file);
+ /* Read file */
+ buf = malloc(count);
+ if (!buf) {
+ perror("calloc");
+ return EXIT_FAILURE;
+ }
+ count = fread(buf, 1, count, file);
+
+ /* Generate output */
+ printf("/*\n");
+ printf(" * Non-zero %u byte strings of a disk image\n", BLOCK_SIZE);
+ printf(" *\n");
+ printf(" * Generated with tools/file2include\n");
+ printf(" *\n");
+ printf(" * SPDX-License-Identifier: GPL-2.0+\n");
+ printf(" */\n\n");
+ printf("#define EFI_ST_DISK_IMG { 0x%08zx, { \\\n", count);
+
+ for (i = 0; i < count; i += BLOCK_SIZE) {
+ int c = 0;
+
+ for (j = i; j < i + BLOCK_SIZE && j < count; ++j) {
+ if (buf[j])
+ c = 1;
+ }
+ if (!c)
+ continue;
+ printf("\t{0x%08zx, \"", i);
+ for (j = i; j < i + BLOCK_SIZE && j < count; ++j)
+ printf("\\x%02x", buf[j]);
+ printf("\"}, /* ");
+ for (j = i; j < i + BLOCK_SIZE && j < count; ++j) {
+ if (buf[j] >= 0x20 && buf[j] <= 0x7e)
+ printf("%c", buf[j]);
+ else
+ printf(".");
+ }
+ printf(" */ \\\n");
+ }
+ printf("\t{0, NULL} } }\n");
+
+ /* Release resources */
+ free(buf);
+ ret = fclose(file);
+ if (ret) {
+ perror("fclose");
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/tools/patman/get_maintainer.py b/tools/patman/get_maintainer.py
index 2deb5db..22b0918 100644
--- a/tools/patman/get_maintainer.py
+++ b/tools/patman/get_maintainer.py
@@ -44,4 +44,5 @@
return []
stdout = command.Output(get_maintainer, '--norolestats', fname)
- return stdout.splitlines()
+ lines = stdout.splitlines()
+ return [ x.replace('"', '') for x in lines ]