[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 = &params->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