[U-Boot] [PATCH 3/6] sunxi: add option for 16-bit DW DRAM controller

André Przywara andre.przywara at arm.com
Wed Mar 15 00:52:33 UTC 2017


On 13/03/17 17:50, Icenowy Zheng wrote:

Hi Icenowy,

> Some Allwinner SoCs features a DesignWare-like controller with only 16
> bit bus width.
> 
> Add support for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy at aosc.xyz>
> ---
>  arch/arm/mach-sunxi/dram_sunxi_dw.c | 34 +++++++++++++++++++++++++++++-----
>  board/sunxi/Kconfig                 | 16 ++++++++++++++++
>  2 files changed, 45 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c
> index 0c73a43075..b08998c0d1 100644
> --- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
> +++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
> @@ -298,6 +298,13 @@ static void mctl_h3_zq_calibration_quirk(struct dram_para *para)

So can you confirm that this quirk is still needed for the V3s?

>  {
>  	struct sunxi_mctl_ctl_reg * const mctl_ctl =
>  			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
> +	int zq_count;
> +
> +#if defined CONFIG_SUNXI_DRAM_DW_16BIT

Can we have a proper variable here, probably as a member of struct
dram_para? This should work similar to the socid: the compiler would
optimize out the not-needed code path.

> +	zq_count = 4;

And can you explain the 4 and 6 here? Either by using Jens' formula or
by adding a comment?

Cheers,
Andre.

> +#else
> +	zq_count = 6;
> +#endif
>  
>  	if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
>  	    (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
> @@ -326,7 +333,7 @@ static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
>  
>  		writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
>  
> -		for (i = 0; i < 6; i++) {
> +		for (i = 0; i < zq_count; i++) {
>  			u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
>  
>  			writel((zq << 20) | (zq << 16) | (zq << 12) |
> @@ -348,7 +355,9 @@ static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
>  
>  		writel((zq_val[1] << 16) | zq_val[0], &mctl_ctl->zqdr[0]);
>  		writel((zq_val[3] << 16) | zq_val[2], &mctl_ctl->zqdr[1]);
> -		writel((zq_val[5] << 16) | zq_val[4], &mctl_ctl->zqdr[2]);
> +		if (zq_count > 4)
> +			writel((zq_val[5] << 16) | zq_val[4],
> +			       &mctl_ctl->zqdr[2]);
>  	}
>  }
>  
> @@ -473,8 +482,14 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
>  
>  	/* set half DQ */
>  	if (!para->bus_full_width) {
> +#if defined CONFIG_SUNXI_DRAM_DW_32BIT


>  		writel(0x0, &mctl_ctl->dx[2].gcr);
>  		writel(0x0, &mctl_ctl->dx[3].gcr);
> +#elif defined CONFIG_SUNXI_DRAM_DW_16BIT
> +		writel(0x0, &mctl_ctl->dx[1].gcr);
> +#else
> +#error Unsupported DRAM bus width!
> +#endif
>  	}
>  
>  	/* data training configuration */
> @@ -499,20 +514,29 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
>  	/* detect ranks and bus width */
>  	if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
>  		/* only one rank */
> -		if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2) ||
> -		    ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)) {
> +		if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2)
> +#if defined CONFIG_SUNXI_DRAM_DW_32BIT
> +		    || ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)
> +#endif
> +		    ) {
>  			clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
>  			para->dual_rank = 0;
>  		}
>  
>  		/* only half DQ width */
> +#if defined CONFIG_SUNXI_DRAM_DW_32BIT
>  		if (((readl(&mctl_ctl->dx[2].gsr[0]) >> 24) & 0x1) ||
>  		    ((readl(&mctl_ctl->dx[3].gsr[0]) >> 24) & 0x1)) {
>  			writel(0x0, &mctl_ctl->dx[2].gcr);
>  			writel(0x0, &mctl_ctl->dx[3].gcr);
>  			para->bus_full_width = 0;
>  		}
> -
> +#elif defined CONFIG_SUNXI_DRAM_DW_16BIT
> +		if ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x1) {
> +			writel(0x0, &mctl_ctl->dx[1].gcr);
> +			para->bus_full_width = 0;
> +		}
> +#endif
>  		mctl_set_cr(para);
>  		udelay(20);
>  
> diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
> index e71fdaee86..d8a1e341e8 100644
> --- a/board/sunxi/Kconfig
> +++ b/board/sunxi/Kconfig
> @@ -50,6 +50,20 @@ config SUNXI_DRAM_DW
>  	not have official open-source DRAM initialization code, but can
>  	use modified H3 DRAM initialization code.
>  
> +if SUNXI_DRAM_DW
> +config SUNXI_DRAM_DW_16BIT
> +	bool
> +	---help---
> +	Select this for sunxi SoCs with DesignWare DRAM controller and
> +	have only 16-bit memory buswidth.
> +
> +config SUNXI_DRAM_DW_32BIT
> +	bool
> +	---help---
> +	Select this for sunxi SoCs with DesignWare DRAM controller with
> +	32-bit memory buswidth.
> +endif
> +
>  choice
>  	prompt "Sunxi SoC Variant"
>  	optional
> @@ -121,6 +135,7 @@ config MACH_SUN8I_H3
>  	select SUNXI_GEN_SUN6I
>  	select SUPPORT_SPL
>  	select SUNXI_DRAM_DW
> +	select SUNXI_DRAM_DW_32BIT
>  	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
>  
>  config MACH_SUN8I_V3S
> @@ -144,6 +159,7 @@ config MACH_SUN50I
>  	select SUNXI_GEN_SUN6I
>  	select SUPPORT_SPL
>  	select SUNXI_DRAM_DW
> +	select SUNXI_DRAM_DW_32BIT
>  
>  endchoice
>  
> 



More information about the U-Boot mailing list