[U-Boot] [PATCH v3 14/18] ram: rk3399: Compute stride for 2 channels
Kever Yang
kever.yang at rock-chips.com
Tue Jul 16 07:44:15 UTC 2019
On 2019/7/16 上午2:28, Jagan Teki wrote:
> stride value from sdram timings can be computed dynamically
> based on the determined capacity for the given channel.
>
> Right now these stride values are taken as part of sdram timings
> via dtsi, but it possible to use same timings dtsi for given
> frequency even though the configured board sdram do support
> single channel with different size by dynamically detect the
> stride value.
>
> Example, NanoPi NEO4 do have DDR3-1866, but with single channel
> and 1GB size with dynamic stride detection it is possible to
> use existing rk3399-sdram-ddr3-1866.dtsi whose stride,
> number of channels and capacity it support is d efferent.
>
> So, add initial support to calculate the stride value for
> 2 channels sdram, which is available by default on existing
> boards.
>
> Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
> Signed-off-by: YouMin Chen <cym at rock-chips.com>
Reviewed-by: Kever Yang <Kever.yang at rock-chips.com>
Thanks,
- Kever
> ---
> drivers/ram/rockchip/sdram_rk3399.c | 71 ++++++++++++++++++++++++++++-
> 1 file changed, 70 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
> index 084c949728..c626ef602c 100644
> --- a/drivers/ram/rockchip/sdram_rk3399.c
> +++ b/drivers/ram/rockchip/sdram_rk3399.c
> @@ -1183,8 +1183,75 @@ static int switch_to_phy_index1(struct dram_info *dram,
> return 0;
> }
>
> +static unsigned char calculate_stride(struct rk3399_sdram_params *params)
> +{
> + unsigned int stride = params->base.stride;
> + unsigned int channel, chinfo = 0;
> + unsigned int ch_cap[2] = {0, 0};
> + u64 cap;
> +
> + for (channel = 0; channel < 2; channel++) {
> + unsigned int cs0_cap = 0;
> + unsigned int cs1_cap = 0;
> + struct sdram_cap_info *cap_info = ¶ms->ch[channel].cap_info;
> +
> + if (cap_info->col == 0)
> + continue;
> +
> + cs0_cap = (1 << (cap_info->cs0_row + cap_info->col +
> + cap_info->bk + cap_info->bw - 20));
> + if (cap_info->rank > 1)
> + cs1_cap = cs0_cap >> (cap_info->cs0_row
> + - cap_info->cs1_row);
> + if (cap_info->row_3_4) {
> + cs0_cap = cs0_cap * 3 / 4;
> + cs1_cap = cs1_cap * 3 / 4;
> + }
> + ch_cap[channel] = cs0_cap + cs1_cap;
> + chinfo |= 1 << channel;
> + }
> +
> + /* stride calculation for 2 channels, default gstride type is 256B */
> + if (ch_cap[0] == ch_cap[1]) {
> + cap = ch_cap[0] + ch_cap[1];
> + switch (cap) {
> + /* 512MB */
> + case 512:
> + stride = 0;
> + break;
> + /* 1GB */
> + case 1024:
> + stride = 0x5;
> + break;
> + /*
> + * 768MB + 768MB same as total 2GB memory
> + * useful space: 0-768MB 1GB-1792MB
> + */
> + case 1536:
> + /* 2GB */
> + case 2048:
> + stride = 0x9;
> + break;
> + /* 1536MB + 1536MB */
> + case 3072:
> + stride = 0x11;
> + break;
> + /* 4GB */
> + case 4096:
> + stride = 0xD;
> + break;
> + default:
> + printf("%s: Unable to calculate stride for ", __func__);
> + print_size((cap * (1 << 20)), " capacity\n");
> + break;
> + }
> + }
> +
> + return stride;
> +}
> +
> static int sdram_init(struct dram_info *dram,
> - const struct rk3399_sdram_params *params)
> + struct rk3399_sdram_params *params)
> {
> unsigned char dramtype = params->base.dramtype;
> unsigned int ddr_freq = params->base.ddr_freq;
> @@ -1232,6 +1299,8 @@ static int sdram_init(struct dram_info *dram,
> set_ddrconfig(chan, params, channel,
> params->ch[channel].cap_info.ddrconfig);
> }
> +
> + params->base.stride = calculate_stride(params);
> dram_all_config(dram, params);
> switch_to_phy_index1(dram, params);
>
More information about the U-Boot
mailing list