[U-Boot] [PATCH v2 14/23] sunxi: H3: add DRAM controller single bit delay support

Maxime Ripard maxime.ripard at free-electrons.com
Tue Dec 6 12:02:24 CET 2016


On Mon, Dec 05, 2016 at 01:52:21AM +0000, Andre Przywara wrote:
> From: Jens Kuske <jenskuske at gmail.com>
> 
> Instead of setting the delay for whole bytes allow setting
> it for each individual bit. Also add support for
> address/command lane delays.
> 
> Signed-off-by: Jens Kuske <jenskuske at gmail.com>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  arch/arm/mach-sunxi/dram_sun8i_h3.c | 54 ++++++++++++++++++-------------------
>  1 file changed, 27 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/arm/mach-sunxi/dram_sun8i_h3.c b/arch/arm/mach-sunxi/dram_sun8i_h3.c
> index 3dd6803..1647d76 100644
> --- a/arch/arm/mach-sunxi/dram_sun8i_h3.c
> +++ b/arch/arm/mach-sunxi/dram_sun8i_h3.c
> @@ -16,12 +16,13 @@
>  #include <linux/kconfig.h>
>  
>  struct dram_para {
> -	u32 read_delays;
> -	u32 write_delays;
>  	u16 page_size;
>  	u8 bus_width;
>  	u8 dual_rank;
>  	u8 row_bits;
> +	const u8 dx_read_delays[4][11];
> +	const u8 dx_write_delays[4][11];
> +	const u8 ac_delays[31];
>  };

Some documentation on what is the expected format and what it
corresponds to would be welcome.

>  
>  static inline int ns_to_t(int nanoseconds)
> @@ -64,34 +65,25 @@ static void mctl_phy_init(u32 val)
>  	mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
>  }
>  
> -static void mctl_dq_delay(u32 read, u32 write)
> +static void mctl_set_bit_delays(struct dram_para *para)
>  {
>  	struct sunxi_mctl_ctl_reg * const mctl_ctl =
>  			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
>  	int i, j;
> -	u32 val;
> -
> -	for (i = 0; i < 4; i++) {
> -		val = DXBDLR_WRITE_DELAY((write >> (i * 4)) & 0xf) |
> -		      DXBDLR_READ_DELAY(((read >> (i * 4)) & 0xf) * 2);
> -
> -		for (j = DXBDLR_DQ(0); j <= DXBDLR_DM; j++)
> -			writel(val, &mctl_ctl->dx[i].bdlr[j]);
> -	}
>  
>  	clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
>  
> -	for (i = 0; i < 4; i++) {
> -		val = DXBDLR_WRITE_DELAY((write >> (16 + i * 4)) & 0xf) |
> -		      DXBDLR_READ_DELAY((read >> (16 + i * 4)) & 0xf);
> +	for (i = 0; i < 4; i++)
> +		for (j = 0; j < 11; j++)
> +			writel(DXBDLR_WRITE_DELAY(para->dx_write_delays[i][j]) |
> +			       DXBDLR_READ_DELAY(para->dx_read_delays[i][j]),
> +			       &mctl_ctl->dx[i].bdlr[j]);
>  
> -		writel(val, &mctl_ctl->dx[i].bdlr[DXBDLR_DQS]);
> -		writel(val, &mctl_ctl->dx[i].bdlr[DXBDLR_DQSN]);
> -	}
> +	for (i = 0; i < 31; i++)
> +		writel(ACBDLR_WRITE_DELAY(para->ac_delays[i]),
> +		       &mctl_ctl->acbdlr[i]);
>  
>  	setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
> -
> -	udelay(1);
>  }
>  
>  static void mctl_set_master_priority(void)
> @@ -372,11 +364,8 @@ static int mctl_channel_init(struct dram_para *para)
>  	clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
>  			(para->dual_rank ? 0x3 : 0x1) << 24);
>  
> -
> -	if (para->read_delays || para->write_delays) {
> -		mctl_dq_delay(para->read_delays, para->write_delays);
> -		udelay(50);
> -	}
> +	mctl_set_bit_delays(para);
> +	udelay(50);
>  
>  	mctl_zq_calibration(para);
>  
> @@ -458,12 +447,23 @@ unsigned long sunxi_dram_init(void)
>  			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
>  
>  	struct dram_para para = {
> -		.read_delays = 0x00007979,	/* dram_tpr12 */
> -		.write_delays = 0x6aaa0000,	/* dram_tpr11 */
>  		.dual_rank = 0,
>  		.bus_width = 32,
>  		.row_bits = 15,
>  		.page_size = 4096,
> +
> +		.dx_read_delays =  {{ 18, 18, 18, 18, 18, 18, 18, 18, 18,  0,  0 },
> +		                    { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },
> +		                    { 18, 18, 18, 18, 18, 18, 18, 18, 18,  0,  0 },
> +		                    { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 }},
> +		.dx_write_delays = {{  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 10 },
> +		                    {  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 10 },
> +		                    {  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 10 },
> +		                    {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  6 }},
> +		.ac_delays = {  0,  0,  0,  0,  0,  0,  0,  0,
> +		                0,  0,  0,  0,  0,  0,  0,  0,
> +		                0,  0,  0,  0,  0,  0,  0,  0,
> +		                0,  0,  0,  0,  0,  0,  0      },

You're mixing tabs and spaces for the indentation, and the tab before
that bracket looks useless.

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20161206/ef174ed0/attachment.sig>


More information about the U-Boot mailing list