From 92ac73e4c2579444ee5017f37aa61e116ccf15c9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 1 Oct 2016 20:04:50 -0600 Subject: rockchip: rk3036: Move rockchip_get_cru() out of the driver This function is called from outside the driver. It should be placed into common SoC code. Move it. Also rename the driver symbol to be more consistent with the other rockchip clock drivers. Signed-off-by: Simon Glass Reviewed-by: Kever Yang --- arch/arm/mach-rockchip/rk3036/Makefile | 2 ++ arch/arm/mach-rockchip/rk3036/clk_rk3036.c | 33 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 arch/arm/mach-rockchip/rk3036/clk_rk3036.c (limited to 'arch/arm/mach-rockchip') diff --git a/arch/arm/mach-rockchip/rk3036/Makefile b/arch/arm/mach-rockchip/rk3036/Makefile index 916a7a4378..20d28f7c21 100644 --- a/arch/arm/mach-rockchip/rk3036/Makefile +++ b/arch/arm/mach-rockchip/rk3036/Makefile @@ -4,6 +4,8 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-y += clk_rk3036.o + ifndef CONFIG_SPL_BUILD obj-y += syscon_rk3036.o endif diff --git a/arch/arm/mach-rockchip/rk3036/clk_rk3036.c b/arch/arm/mach-rockchip/rk3036/clk_rk3036.c new file mode 100644 index 0000000000..6a06afb103 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3036/clk_rk3036.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +int rockchip_get_clk(struct udevice **devp) +{ + return uclass_get_device_by_driver(UCLASS_CLK, + DM_GET_DRIVER(rockchip_rk3036_cru), devp); +} + +void *rockchip_get_cru(void) +{ + struct rk3036_clk_priv *priv; + struct udevice *dev; + int ret; + + ret = rockchip_get_clk(&dev); + if (ret) + return ERR_PTR(ret); + + priv = dev_get_priv(dev); + + return priv->cru; +} -- cgit From c8a6bc968312f572cc84e3928ae5a293f2454849 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 1 Oct 2016 20:04:51 -0600 Subject: rockchip: rk3399: Move rockchip_get_cru() out of the driver This function is called from outside the driver. It should be placed into common SoC code. Move it. Also rename the driver symbol to be more consistent with the other rockchip clock drivers. Signed-off-by: Simon Glass Reviewed-by: Kever Yang --- arch/arm/mach-rockchip/rk3399/Makefile | 1 + arch/arm/mach-rockchip/rk3399/clk_rk3399.c | 33 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 arch/arm/mach-rockchip/rk3399/clk_rk3399.c (limited to 'arch/arm/mach-rockchip') diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile index 607f9c9612..98ebeac340 100644 --- a/arch/arm/mach-rockchip/rk3399/Makefile +++ b/arch/arm/mach-rockchip/rk3399/Makefile @@ -4,5 +4,6 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-y += clk_rk3399.o obj-y += rk3399.o obj-y += syscon_rk3399.o diff --git a/arch/arm/mach-rockchip/rk3399/clk_rk3399.c b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c new file mode 100644 index 0000000000..7663591154 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +int rockchip_get_clk(struct udevice **devp) +{ + return uclass_get_device_by_driver(UCLASS_CLK, + DM_GET_DRIVER(rockchip_rk3399_pmuclk), devp); +} + +void *rockchip_get_cru(void) +{ + struct rk3399_clk_priv *priv; + struct udevice *dev; + int ret; + + ret = rockchip_get_clk(&dev); + if (ret) + return ERR_PTR(ret); + + priv = dev_get_priv(dev); + + return priv->cru; +} -- cgit From 5564ed5dd980c1e67780fb6a7fdbe29fd76174ed Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 1 Oct 2016 20:04:52 -0600 Subject: rockchip: rk3288: Move rockchip_get_cru() out of the driver This function is called from outside the driver. It should be placed into common SoC code. Move it. Signed-off-by: Simon Glass Reviewed-by: Kever Yang --- arch/arm/mach-rockchip/rk3288/clk_rk3288.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'arch/arm/mach-rockchip') diff --git a/arch/arm/mach-rockchip/rk3288/clk_rk3288.c b/arch/arm/mach-rockchip/rk3288/clk_rk3288.c index 2099e349c1..a45b923a2c 100644 --- a/arch/arm/mach-rockchip/rk3288/clk_rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/clk_rk3288.c @@ -9,9 +9,25 @@ #include #include #include +#include int rockchip_get_clk(struct udevice **devp) { return uclass_get_device_by_driver(UCLASS_CLK, DM_GET_DRIVER(rockchip_rk3288_cru), devp); } + +void *rockchip_get_cru(void) +{ + struct rk3288_clk_priv *priv; + struct udevice *dev; + int ret; + + ret = rockchip_get_clk(&dev); + if (ret) + return ERR_PTR(ret); + + priv = dev_get_priv(dev); + + return priv->cru; +} -- cgit From 27b95d25c570e29fe58ae01e308467a1f682411e Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 7 Oct 2016 15:56:16 +0800 Subject: rk3399: disable the clock multiplier support when SoC init The Clock Multiplier in rk3399 EMMC programmable clock generator is broken, we can remove its support from SoC GRF register. Without this patch, rk3399 emmc driver is not work after below patch applied: 6dffdbc mmc: sdhci: Add the programmable clock mode support Signed-off-by: Kever Yang --- arch/arm/mach-rockchip/rk3399/rk3399.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch/arm/mach-rockchip') diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c index b9d7629407..8bb950ebd1 100644 --- a/arch/arm/mach-rockchip/rk3399/rk3399.c +++ b/arch/arm/mach-rockchip/rk3399/rk3399.c @@ -6,6 +6,10 @@ #include #include +#include +#include + +#define GRF_EMMCCORE_CON11 0xff77f02c static struct mm_region rk3399_mem_map[] = { { @@ -28,3 +32,13 @@ static struct mm_region rk3399_mem_map[] = { }; struct mm_region *mem_map = rk3399_mem_map; + +int arch_cpu_init(void) +{ + /* We do some SoC one time setting here. */ + + /* Emmc clock generator: disable the clock multipilier */ + rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff); + + return 0; +} -- cgit From 1b64a05072f56dbefd7c4ed1eee5df50f6748eaf Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 7 Oct 2016 15:59:49 +0800 Subject: rk3288: fix reg address for GRF_SOC_CON2 The GRF base address is missing, fix it. Signed-off-by: Kever Yang --- arch/arm/mach-rockchip/rk3288/rk3288.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/mach-rockchip') diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c index 92f34bbbcb..acc3b7932a 100644 --- a/arch/arm/mach-rockchip/rk3288/rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/rk3288.c @@ -6,7 +6,7 @@ #include #include -#define GRF_SOC_CON2 0x24c +#define GRF_SOC_CON2 0xff77024c int arch_cpu_init(void) { -- cgit From 7d6c78f5731e71c7619c621c4c7e30c56f0fd9bf Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 7 Oct 2016 17:47:58 +0800 Subject: rk3288: sdram: auto-detect the capacity Add support for rk3288 dram capacity auto detect, support DDR3 and LPDDR3, DDR2 is not supported. The program will automatically detect: - channel number - rank number - column address number - row address number The dts file do not need to describe those info after apply this patch. Signed-off-by: Kever Yang Tested-by: Simon Glass Tested-by: Vagrant Cascadian Tested-by: Vagrant Cascadian --- arch/arm/mach-rockchip/rk3288/sdram_rk3288.c | 272 ++++++++++++++++++++++----- 1 file changed, 230 insertions(+), 42 deletions(-) (limited to 'arch/arm/mach-rockchip') diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c index 8020e9c6e2..be3d713202 100644 --- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c @@ -57,6 +57,10 @@ struct rk3288_sdram_params { struct regmap *map; }; +#define TEST_PATTEN 0x5aa5f00f +#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4) +#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4) + #ifdef CONFIG_SPL_BUILD static void copy_to_reg(u32 *dest, const u32 *src, u32 n) { @@ -214,7 +218,7 @@ static void ddr_set_en_bst_odt(struct rk3288_grf *grf, uint channel, } static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl, - const struct rk3288_sdram_params *sdram_params, + struct rk3288_sdram_params *sdram_params, struct rk3288_grf *grf) { unsigned int burstlen; @@ -264,7 +268,7 @@ static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl, } static void phy_cfg(const struct chan_info *chan, u32 channel, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { struct rk3288_ddr_publ *publ = chan->publ; struct rk3288_msch *msch = chan->msch; @@ -446,7 +450,7 @@ static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel, } static int data_training(const struct chan_info *chan, u32 channel, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { unsigned int j; int ret = 0; @@ -549,7 +553,7 @@ static void move_to_access_state(const struct chan_info *chan) } static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { struct rk3288_ddr_publ *publ = chan->publ; @@ -563,7 +567,7 @@ static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, } static void dram_all_config(const struct dram_info *dram, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { unsigned int chan; u32 sys_reg = 0; @@ -589,9 +593,191 @@ static void dram_all_config(const struct dram_info *dram, writel(sys_reg, &dram->pmu->sys_reg[2]); rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride); } +const int ddrconf_table[] = { + /* row col,bw */ + 0, + ((1 << 4) | 1), + ((2 << 4) | 1), + ((3 << 4) | 1), + ((4 << 4) | 1), + ((1 << 4) | 2), + ((2 << 4) | 2), + ((3 << 4) | 2), + ((1 << 4) | 0), + ((2 << 4) | 0), + ((3 << 4) | 0), + 0, + 0, + 0, + 0, + ((4 << 4) | 2), +}; + +static int sdram_rank_bw_detect(struct dram_info *dram, int channel, + struct rk3288_sdram_params *sdram_params) +{ + int reg; + int need_trainig = 0; + const struct chan_info *chan = &dram->chan[channel]; + struct rk3288_ddr_publ *publ = chan->publ; + + if (-1 == data_training(chan, channel, sdram_params)) { + reg = readl(&publ->datx8[0].dxgsr[0]); + /* Check the result for rank 0 */ + if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { + debug("data training fail!\n"); + return -EIO; + } else if ((channel == 1) && + (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { + sdram_params->num_channels = 1; + } + + /* Check the result for rank 1 */ + if (reg & DQS_GATE_TRAINING_ERROR_RANK1) { + sdram_params->ch[channel].rank = 1; + clrsetbits_le32(&publ->pgcr, 0xF << 18, + sdram_params->ch[channel].rank << 18); + need_trainig = 1; + } + reg = readl(&publ->datx8[2].dxgsr[0]); + if (reg & (1 << 4)) { + sdram_params->ch[channel].bw = 1; + set_bandwidth_ratio(chan, channel, + sdram_params->ch[channel].bw, + dram->grf); + need_trainig = 1; + } + } + /* Assume the Die bit width are the same with the chip bit width */ + sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw; + + if (need_trainig && + (-1 == data_training(chan, channel, sdram_params))) { + if (sdram_params->base.dramtype == LPDDR3) { + ddr_phy_ctl_reset(dram->cru, channel, 1); + udelay(10); + ddr_phy_ctl_reset(dram->cru, channel, 0); + udelay(10); + } + debug("2nd data training failed!"); + return -EIO; + } + + return 0; +} + +static int sdram_col_row_detect(struct dram_info *dram, int channel, + struct rk3288_sdram_params *sdram_params) +{ + int row, col; + unsigned int addr; + const struct chan_info *chan = &dram->chan[channel]; + struct rk3288_ddr_pctl *pctl = chan->pctl; + struct rk3288_ddr_publ *publ = chan->publ; + int ret = 0; + + /* Detect col */ + for (col = 11; col >= 9; col--) { + writel(0, CONFIG_SYS_SDRAM_BASE); + addr = CONFIG_SYS_SDRAM_BASE + + (1 << (col + sdram_params->ch[channel].bw - 1)); + writel(TEST_PATTEN, addr); + if ((readl(addr) == TEST_PATTEN) && + (readl(CONFIG_SYS_SDRAM_BASE) == 0)) + break; + } + if (col == 8) { + printf("Col detect error\n"); + ret = -EINVAL; + goto out; + } else { + sdram_params->ch[channel].col = col; + } + + move_to_config_state(publ, pctl); + writel(4, &chan->msch->ddrconf); + move_to_access_state(chan); + /* Detect row*/ + for (row = 16; row >= 12; row--) { + writel(0, CONFIG_SYS_SDRAM_BASE); + addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1)); + writel(TEST_PATTEN, addr); + if ((readl(addr) == TEST_PATTEN) && + (readl(CONFIG_SYS_SDRAM_BASE) == 0)) + break; + } + if (row == 11) { + printf("Row detect error\n"); + ret = -EINVAL; + } else { + sdram_params->ch[channel].cs1_row = row; + sdram_params->ch[channel].row_3_4 = 0; + debug("chn %d col %d, row %d\n", channel, col, row); + sdram_params->ch[channel].cs0_row = row; + } + +out: + return ret; +} + +static int sdram_get_niu_config(struct rk3288_sdram_params *sdram_params) +{ + int i, tmp, size, ret = 0; + + tmp = sdram_params->ch[0].col - 9; + tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1; + tmp |= ((sdram_params->ch[0].cs0_row - 12) << 4); + size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]); + for (i = 0; i < size; i++) + if (tmp == ddrconf_table[i]) + break; + if (i >= size) { + printf("niu config not found\n"); + ret = -EINVAL; + } else { + sdram_params->base.ddrconfig = i; + } + + return ret; +} + +static int sdram_get_stride(struct rk3288_sdram_params *sdram_params) +{ + int stride = -1; + int ret = 0; + long cap = sdram_params->num_channels * (1u << + (sdram_params->ch[0].cs0_row + + sdram_params->ch[0].col + + (sdram_params->ch[0].rank - 1) + + sdram_params->ch[0].bw + + 3 - 20)); + + switch (cap) { + case 512: + stride = 0; + break; + case 1024: + stride = 5; + break; + case 2048: + stride = 9; + break; + case 4096: + stride = 0xd; + break; + default: + stride = -1; + printf("could not find correct stride, cap error!\n"); + ret = -EINVAL; + break; + } + sdram_params->base.stride = stride; + + return ret; +} static int sdram_init(struct dram_info *dram, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { int channel; int zqcr; @@ -619,12 +805,14 @@ static int sdram_init(struct dram_info *dram, struct rk3288_ddr_pctl *pctl = chan->pctl; struct rk3288_ddr_publ *publ = chan->publ; + /* map all the 4GB space to the current channel */ + if (channel) + rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x17); + else + rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x1a); phy_pctrl_reset(dram->cru, publ, channel); phy_dll_bypass_set(publ, sdram_params->base.ddr_freq); - if (channel >= sdram_params->num_channels) - continue; - dfi_cfg(pctl, sdram_params->base.dramtype); pctl_cfg(channel, pctl, sdram_params, dram->grf); @@ -658,16 +846,20 @@ static int sdram_init(struct dram_info *dram, udelay(1); } + /* Using 32bit bus width for detect */ + sdram_params->ch[channel].bw = 2; set_bandwidth_ratio(chan, channel, sdram_params->ch[channel].bw, dram->grf); /* - * set cs + * set cs, using n=3 for detect * CS0, n=1 * CS1, n=2 * CS0 & CS1, n = 3 */ + sdram_params->ch[channel].rank = 2, clrsetbits_le32(&publ->pgcr, 0xF << 18, (sdram_params->ch[channel].rank | 1) << 18); + /* DS=40ohm,ODT=155ohm */ zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT | 2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT | @@ -693,16 +885,8 @@ static int sdram_init(struct dram_info *dram, } } - if (-1 == data_training(chan, channel, sdram_params)) { - if (sdram_params->base.dramtype == LPDDR3) { - ddr_phy_ctl_reset(dram->cru, channel, 1); - udelay(10); - ddr_phy_ctl_reset(dram->cru, channel, 0); - udelay(10); - } - debug("failed!"); - return -EIO; - } + /* Detect the rank and bit-width with data-training */ + sdram_rank_bw_detect(dram, channel, sdram_params); if (sdram_params->base.dramtype == LPDDR3) { u32 i; @@ -710,12 +894,31 @@ static int sdram_init(struct dram_info *dram, for (i = 0; i < 17; i++) send_command_op(pctl, 1, MRR_CMD, i, 0); } + writel(15, &chan->msch->ddrconf); move_to_access_state(chan); + /* DDR3 and LPDDR3 are always 8 bank, no need detect */ + sdram_params->ch[channel].bk = 3; + /* Detect Col and Row number*/ + ret = sdram_col_row_detect(dram, channel, sdram_params); + if (ret) + goto error; } + /* Find NIU DDR configuration */ + ret = sdram_get_niu_config(sdram_params); + if (ret) + goto error; + /* Find stride setting */ + ret = sdram_get_stride(sdram_params); + if (ret) + goto error; + dram_all_config(dram, sdram_params); debug("%s done\n", __func__); return 0; +error: + printf("DRAM init failed!\n"); + hang(); } #endif /* CONFIG_SPL_BUILD */ @@ -743,7 +946,6 @@ size_t sdram_size_mb(struct rk3288_pmu *pmu) SYS_REG_BW_MASK)); row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) & SYS_REG_ROW_3_4_MASK; - chipsize_mb = (1 << (cs0_row + col + bk + bw - 20)); if (rank > 1) @@ -815,21 +1017,10 @@ static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev) struct rk3288_sdram_params *params = dev_get_platdata(dev); const void *blob = gd->fdt_blob; int node = dev->of_offset; - int i, ret; - - params->num_channels = fdtdec_get_int(blob, node, - "rockchip,num-channels", 1); - for (i = 0; i < params->num_channels; i++) { - ret = fdtdec_get_byte_array(blob, node, - "rockchip,sdram-channel", - (u8 *)¶ms->ch[i], - sizeof(params->ch[i])); - if (ret) { - debug("%s: Cannot read rockchip,sdram-channel\n", - __func__); - return -EINVAL; - } - } + int ret; + + /* Rk3288 supports dual-channel, set default channel num to 2 */ + params->num_channels = 2; ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing", (u32 *)¶ms->pctl_timing, sizeof(params->pctl_timing) / sizeof(u32)); @@ -870,18 +1061,15 @@ static int conv_of_platdata(struct udevice *dev) { struct rk3288_sdram_params *plat = dev_get_platdata(dev); struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat; - int i, ret; + int ret; - for (i = 0; i < 2; i++) { - memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel, - sizeof(plat->ch[i])); - } memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing, sizeof(plat->pctl_timing)); memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing, sizeof(plat->phy_timing)); memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base)); - plat->num_channels = of_plat->rockchip_num_channels; + /* Rk3288 supports dual-channel, set default channel num to 2 */ + plat->num_channels = 2; ret = regmap_init_mem_platdata(dev, of_plat->reg, ARRAY_SIZE(of_plat->reg) / 2, &plat->map); -- cgit From 4594ac07847f5c7fe7294ce6c71849fea0a431e0 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Sat, 8 Oct 2016 15:23:38 +0800 Subject: rk3288: kconfig: remove duplicate definition of SPL_MMC_SUPPORT SPL_MMC_SUPPORT defined in rockchip top level Kconfig instead of inside rk3288 and default to disable if ROCKCHIP_SPL_BACK_TO_BROM defined. Signed-off-by: Kever Yang Reviewed-by: Simon Glass --- arch/arm/mach-rockchip/rk3288/Kconfig | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/arm/mach-rockchip') diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig index 94863a925e..c53d2e2033 100644 --- a/arch/arm/mach-rockchip/rk3288/Kconfig +++ b/arch/arm/mach-rockchip/rk3288/Kconfig @@ -81,9 +81,6 @@ config SPL_LIBCOMMON_SUPPORT config SPL_LIBGENERIC_SUPPORT default y -config SPL_MMC_SUPPORT - default y - config SPL_SERIAL_SUPPORT default y -- cgit