[RFC PATCH 07/13] sunxi: add support for R329 DRAM controller
Samuel Holland
samuel at sholland.org
Sat Nov 6 04:06:12 CET 2021
On 7/22/21 1:30 AM, Icenowy Zheng wrote:
> R329 has a new DRAM controller, which looks like a combination of the
> H6/H616 MCTL_COM part and the SUNXI_DW MCTL_CTL part. This design has
> already got reused by Allwinner, and V831/V833 SoCs have similar
> memory controller.
>
> Add support for it. To prepare for further support of other SoCs,
> routines with socid parameter are added, although not checked now.
>
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
I cannot really review the DRAM init part. But it works, so that's
probably good enough.
Tested-by: Samuel Holland <samuel at sholland.org>
There are a couple of magic values I happen to have an explanation for:
> diff --git a/arch/arm/mach-sunxi/dram_sun50i_r329.c b/arch/arm/mach-sunxi/dram_sun50i_r329.c
> new file mode 100644
> index 0000000000..730883999c
> --- /dev/null
> +++ b/arch/arm/mach-sunxi/dram_sun50i_r329.c
> ...> +unsigned long sunxi_dram_init(void)
> +{
> + struct sunxi_mctl_com_reg * const mctl_com =
> + (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
> + struct sunxi_mctl_ctl_reg * const mctl_ctl =
> + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
> +
> + struct dram_para para = {
> + .dual_rank = 0,
> + .bus_full_width = 1,
> + .row_bits = 16,
> + .bank_bits = 3,
> + .page_size = 8192,
> +
> + .dx_read_delays = SUN50I_R329_DX_READ_DELAYS,
> + .dx_write_delays = SUN50I_R329_DX_WRITE_DELAYS,
> + .ac_delays = SUN50I_R329_AC_DELAYS,
> + };
> +
> + /* Unknown magic */
> + writel(0x10, 0x07010250);
This is VDD_SYS_POWEROFF_GATING_REG, presumably disabling pad hold.
> + writel(0x330000, 0x07010310);
> + writel(0x330003, 0x07010310);
This is a resistor calibration process. See here:
https://github.com/smaeul/sun20i_d1_spl/blob/342cb1d8/include/arch/cpu_ncat.h#L172
https://github.com/smaeul/sun20i_d1_spl/blob/342cb1d8/board/sun20iw1p1/clock.c#L186
Some other BSP code has:
#define REG_CALIB_CONTROL_REG 0x0310
#define OHMS200_REG 0x0314
#define OHMS240_REG 0x0318
#define REG_CALIB_STATUS_REG 0x031c
So this suggests we are calibrating the termination resistors.
Regards,
Samuel
> +
> +#if defined(CONFIG_MACH_SUN50I_R329)
> + uint16_t socid = SOCID_R329;
> +#endif
> +
> + mctl_sys_init(¶);
> + if (mctl_channel_init(socid, ¶))
> + return 0;
> +
> + udelay(1);
> +
> + clrbits_le32(&mctl_ctl->unk_0x0a0, 0xffff);
> + clrbits_le32(&mctl_ctl->pwrctl, 0x1);
> +
> + /* HDR/DDR dynamic mode */
> + clrbits_le32(&mctl_ctl->pgcr[0], 0xf000);
> +
> + /* power down zq calibration module for power save */
> + setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
> +
> + /* DQ hold disable (tpr13[26] == 1) */
> + clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13));
> +
> + mctl_auto_detect_dram_size(¶);
> + mctl_apply_para(¶);
> +
> + /* enable master access */
> + writel(0xffffffff, &mctl_com->maer0);
> + writel(0x7f, &mctl_com->maer1);
> + writel(0xffff, &mctl_com->maer2);
> +
> + return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
> + (para.dual_rank ? 2 : 1);
> +}
More information about the U-Boot
mailing list