From fc1526f651a557ddbf7c3cba8575be963573871f Mon Sep 17 00:00:00 2001 From: Han Pengfei Date: Sun, 15 May 2022 14:11:59 +0800 Subject: drivers: ram: rockchip: Fix dram channels calculation for rk3399 Only add the dram channel when we finally setup it successfully at the last step. Signed-off-by: Han Pengfei Reviewed-by: Kever Yang --- drivers/ram/rockchip/sdram_rk3399.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c index c0a06dcaed0..8b4d5252924 100644 --- a/drivers/ram/rockchip/sdram_rk3399.c +++ b/drivers/ram/rockchip/sdram_rk3399.c @@ -2964,8 +2964,6 @@ static int sdram_init(struct dram_info *dram, if (cap_info->rank == 0) { clear_channel_params(params, 1); continue; - } else { - params->base.num_channels++; } if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) { @@ -2991,6 +2989,8 @@ static int sdram_init(struct dram_info *dram, printf("no ddrconfig find, Cap not support!\n"); continue; } + + params->base.num_channels++; set_ddrconfig(chan, params, channel, cap_info->ddrconfig); set_cap_relate_config(chan, params, channel); } -- cgit v1.3.1 From 7b561e2ab8ac980023c5e5325f45a8ca1951c0dd Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 11 Aug 2022 08:58:46 +0100 Subject: ram: rk3399: Fix .set_rate_index() error handling Functions pointed to by this op pointer can return non-zero values indicating an error. Ensure any error value is propagated back up the call-chain. Signed-off-by: Lee Jones Tested-by: Xavier Drudis Ferran Reviewed-by: Kever Yang --- drivers/ram/rockchip/sdram_rk3399.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c index 8b4d5252924..5faff396410 100644 --- a/drivers/ram/rockchip/sdram_rk3399.c +++ b/drivers/ram/rockchip/sdram_rk3399.c @@ -3005,7 +3005,9 @@ static int sdram_init(struct dram_info *dram, params->base.stride = calculate_stride(params); dram_all_config(dram, params); - dram->ops->set_rate_index(dram, params); + ret = dram->ops->set_rate_index(dram, params); + if (ret) + return ret; debug("Finish SDRAM initialization...\n"); return 0; -- cgit v1.3.1 From daef678cffb9fb387c44d45d827d2b8ea199eb5b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 11 Aug 2022 08:58:47 +0100 Subject: ram: rk3399: Fix faulty frequency change reports Frequency changes to 400MHz are presently reported as: lpddr4_set_rate_0: change freq to 400000000 mhz 0, 1 This is obviously wrong by 6 orders of magnitude. Ensure frequency changes are reported accurately. Signed-off-by: Lee Jones Tested-by: Xavier Drudis Ferran Reviewed-by: Kever Yang --- drivers/ram/rockchip/sdram_rk3399.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c index 5faff396410..f76904f05b2 100644 --- a/drivers/ram/rockchip/sdram_rk3399.c +++ b/drivers/ram/rockchip/sdram_rk3399.c @@ -2552,8 +2552,8 @@ static int lpddr4_set_rate(struct dram_info *dram, dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq); if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) - printf("%s: change freq to %d mhz %d, %d\n", __func__, - dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq, + printf("%s: change freq to %dMHz %d, %d\n", __func__, + dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz, ctl_fn, phy_fn); } -- cgit v1.3.1 From 337e92e79c95ffb8c0c6e7b4023c955c50fca018 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 11 Aug 2022 08:58:48 +0100 Subject: ram: rk3399: Conduct memory training at 400MHz MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the default initialisation frequency is 50MHz. Although this does appear to be suitable for some LPDDR4 RAM chips, training at this low frequency has been seen to cause Column errors, leading to Capacity check errors on others. Here we force RAM initialisation to happen at 400MHz before ramping up to the final value running value of 800MHz after everything has been successfully configured. Link: https://lore.kernel.org/u-boot/Yo4v3jUeHXTovjOH@google.com/ Suggested-by: YouMin Chen Signed-off-by: Lee Jones Tested-by: Xavier Drudis Ferran Reviewed-by: Kever Yang Tested-by: Michal Suchánek --- drivers/ram/rockchip/sdram_rk3399.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c index f76904f05b2..cbf502bd0e9 100644 --- a/drivers/ram/rockchip/sdram_rk3399.c +++ b/drivers/ram/rockchip/sdram_rk3399.c @@ -85,7 +85,7 @@ struct sdram_rk3399_ops { int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank, struct rk3399_sdram_params *sdram); int (*set_rate_index)(struct dram_info *dram, - struct rk3399_sdram_params *params); + struct rk3399_sdram_params *params, u32 ctl_fn); void (*modify_param)(const struct chan_info *chan, struct rk3399_sdram_params *params); struct rk3399_sdram_params * @@ -1644,7 +1644,8 @@ static int data_training_first(struct dram_info *dram, u32 channel, u8 rank, } static int switch_to_phy_index1(struct dram_info *dram, - struct rk3399_sdram_params *params) + struct rk3399_sdram_params *params, + u32 unused) { u32 channel; u32 *denali_phy; @@ -2539,26 +2540,25 @@ static int lpddr4_set_ctl(struct dram_info *dram, } static int lpddr4_set_rate(struct dram_info *dram, - struct rk3399_sdram_params *params) + struct rk3399_sdram_params *params, + u32 ctl_fn) { - u32 ctl_fn; u32 phy_fn; - for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) { - phy_fn = lpddr4_get_phy_fn(params, ctl_fn); + phy_fn = lpddr4_get_phy_fn(params, ctl_fn); - lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]); - lpddr4_set_ctl(dram, params, ctl_fn, - dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq); + lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]); + lpddr4_set_ctl(dram, params, ctl_fn, + dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq); - if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) - printf("%s: change freq to %dMHz %d, %d\n", __func__, - dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz, - ctl_fn, phy_fn); - } + if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) + printf("%s: change freq to %dMHz %d, %d\n", __func__, + dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz, + ctl_fn, phy_fn); return 0; } + #endif /* CONFIG_RAM_RK3399_LPDDR4 */ /* CS0,n=1 @@ -2955,6 +2955,12 @@ static int sdram_init(struct dram_info *dram, params->ch[ch].cap_info.rank = rank; } +#if defined(CONFIG_RAM_RK3399_LPDDR4) + /* LPDDR4 needs to be trained at 400MHz */ + lpddr4_set_rate(dram, params, 0); + params->base.ddr_freq = dfs_cfgs_lpddr4[0].base.ddr_freq / MHz; +#endif + params->base.num_channels = 0; for (channel = 0; channel < 2; channel++) { const struct chan_info *chan = &dram->chan[channel]; @@ -3005,7 +3011,7 @@ static int sdram_init(struct dram_info *dram, params->base.stride = calculate_stride(params); dram_all_config(dram, params); - ret = dram->ops->set_rate_index(dram, params); + ret = dram->ops->set_rate_index(dram, params, 1); if (ret) return ret; -- cgit v1.3.1 From f103c112660217f8875398435e47d545ba934a5c Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Sun, 21 Aug 2022 09:17:24 +0200 Subject: clk: rockchip: rk3399: Fix Unknown clock 77 on mmc@fe310000 Adding some debug prints I can see: MMC: mmc@fe320000: Got clock clock-controller@ff760000 76 mmc@fe310000: Got clock clock-controller@ff760000 77 Unknown clock 77 rockchip_dwmmc_get_mmc_clk: err=-2 mmc@fe310000: 3, mmc@fe320000: 1, mmc@fe330000: 0 According to kernel code the SDIO clock is identical to SDMMC clock except for the con 16->15 change. Add support for the clock to avoid the error. Signed-off-by: Michal Suchanek Reviewed-by: Kever Yang --- drivers/clk/rockchip/clk_rk3399.c | 66 +++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index 7d31a9f22a8..97bf1c6e15b 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -728,6 +728,12 @@ static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id) u32 div, con; switch (clk_id) { + case HCLK_SDIO: + case SCLK_SDIO: + con = readl(&cru->clksel_con[15]); + /* dwmmc controller have internal div 2 */ + div = 2; + break; case HCLK_SDMMC: case SCLK_SDMMC: con = readl(&cru->clksel_con[16]); @@ -750,37 +756,46 @@ static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id) return DIV_TO_RATE(GPLL_HZ, div); } +static void rk3399_dwmmc_set_clk(struct rockchip_cru *cru, + unsigned int con, ulong set_rate) +{ + /* Select clk_sdmmc source from GPLL by default */ + /* mmc clock defaulg div 2 internal, provide double in cru */ + int src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate); + + if (src_clk_div > 128) { + /* use 24MHz source for 400KHz clock */ + src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); + assert(src_clk_div - 1 < 128); + rk_clrsetreg(&cru->clksel_con[con], + CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | + (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); + } else { + rk_clrsetreg(&cru->clksel_con[con], + CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | + (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); + } +} + static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru, ulong clk_id, ulong set_rate) { - int src_clk_div; - int aclk_emmc = 198 * MHz; - switch (clk_id) { + case HCLK_SDIO: + case SCLK_SDIO: + rk3399_dwmmc_set_clk(cru, 15, set_rate); + break; case HCLK_SDMMC: case SCLK_SDMMC: - /* Select clk_sdmmc source from GPLL by default */ - /* mmc clock defaulg div 2 internal, provide double in cru */ - src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate); - - if (src_clk_div > 128) { - /* use 24MHz source for 400KHz clock */ - src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); - assert(src_clk_div - 1 < 128); - rk_clrsetreg(&cru->clksel_con[16], - CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, - CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | - (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); - } else { - rk_clrsetreg(&cru->clksel_con[16], - CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, - CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | - (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); - } + rk3399_dwmmc_set_clk(cru, 16, set_rate); break; - case SCLK_EMMC: + case SCLK_EMMC: { + int aclk_emmc = 198 * MHz; /* Select aclk_emmc source from GPLL */ - src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc); + int src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc); + assert(src_clk_div - 1 < 32); rk_clrsetreg(&cru->clksel_con[21], @@ -797,6 +812,7 @@ static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru, CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); break; + } default: return -EINVAL; } @@ -918,6 +934,8 @@ static ulong rk3399_clk_get_rate(struct clk *clk) switch (clk->id) { case 0 ... 63: return 0; + case HCLK_SDIO: + case SCLK_SDIO: case HCLK_SDMMC: case SCLK_SDMMC: case SCLK_EMMC: @@ -992,6 +1010,8 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate) case PCLK_PERILP1: return 0; + case HCLK_SDIO: + case SCLK_SDIO: case HCLK_SDMMC: case SCLK_SDMMC: case SCLK_EMMC: -- cgit v1.3.1