On Tue, May 13, 2025 at 1:36 PM Dario Binacchi <dario.binac...@amarulasolutions.com> wrote: > > From: Michael Trimarchi <mich...@amarulasolutions.com> > > When using SPL on i.mx6 we frequently notice some DDR initialization > mismatches between the SPL code and the non-SPL code. > > As the non-SPL code have been tested for long time and proves to be > reliable, let's configure the DDR in the exact same way as the non-SPL > case. > > The idea is simple: just use the DCD table and write directly to the DDR > registers. > > Signed-off-by: Michael Trimarchi <mich...@amarulasolutions.com> > Signed-off-by: Dario Binacchi <dario.binac...@amarulasolutions.com> > --- > > arch/arm/include/asm/arch-mx6/mx6-ddr.h | 2 + > arch/arm/mach-imx/mx6/ddr.c | 3 + > board/bsh/imx6ulz_smm_m2/spl.c | 235 +++++++++++++++++------- > 3 files changed, 178 insertions(+), 62 deletions(-) > > diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h > b/arch/arm/include/asm/arch-mx6/mx6-ddr.h > index ad9c1ac906a3..bd3ff65bcd96 100644 > --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h > +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h > @@ -457,6 +457,8 @@ struct mx6_mmdc_calibration { > u32 p1_mpwrdlctl; > /* lpddr2 zq hw calibration */ > u32 mpzqlp2ctl; > + /* MDC Duty Cycle Control Register */ > + u32 mpdccr; > }; > > /* configure iomux (pinctl/padctl) */ > diff --git a/arch/arm/mach-imx/mx6/ddr.c b/arch/arm/mach-imx/mx6/ddr.c > index 5a1258e002d2..749ceee0cdbf 100644 > --- a/arch/arm/mach-imx/mx6/ddr.c > +++ b/arch/arm/mach-imx/mx6/ddr.c > @@ -1444,6 +1444,9 @@ void mx6_ddr3_cfg(const struct mx6_ddr_sysinfo *sysinfo, > mmdc0->mpdgctrl1 = calib->p0_mpdgctrl1; > mmdc0->mprddlctl = calib->p0_mprddlctl; > mmdc0->mpwrdlctl = calib->p0_mpwrdlctl; > + if (calib->mpdccr) > + mmdc0->mpdccr = calib->mpdccr; > + > if (sysinfo->dsize > 1) { > MMDC1(mpwldectrl0, calib->p1_mpwldectrl0); > MMDC1(mpwldectrl1, calib->p1_mpwldectrl1); > diff --git a/board/bsh/imx6ulz_smm_m2/spl.c b/board/bsh/imx6ulz_smm_m2/spl.c > index 724841b57456..0fa510446813 100644 > --- a/board/bsh/imx6ulz_smm_m2/spl.c > +++ b/board/bsh/imx6ulz_smm_m2/spl.c > @@ -31,70 +31,184 @@ static void setup_iomux_uart(void) > imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads)); > } > > -static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = { > - .grp_addds = 0x00000028, > - .grp_ddrmode_ctl = 0x00020000, > - .grp_b0ds = 0x00000028, > - .grp_ctlds = 0x00000028, > - .grp_b1ds = 0x00000028, > - .grp_ddrpke = 0x00000000, > - .grp_ddrmode = 0x00020000, > - .grp_ddr_type = 0x000c0000, > +struct dram_cfg_param { > + unsigned int reg; > + unsigned int val; > };
static struct. > > -static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = { > - .dram_dqm0 = 0x00000028, > - .dram_dqm1 = 0x00000028, > - .dram_ras = 0x00000028, > - .dram_cas = 0x00000028, > - .dram_odt0 = 0x00000028, > - .dram_odt1 = 0x00000028, > - .dram_sdba2 = 0x00000000, > - .dram_sdclk_0 = 0x00000028, > - .dram_sdqs0 = 0x00000028, > - .dram_sdqs1 = 0x00000028, > - .dram_reset = 0x000c0028, > +struct dram_timing_info { > + const struct dram_cfg_param *ddrc_cfg; > + unsigned int ddrc_cfg_num; static struct. Please check globally in the series where the definitions can be made static. > +static const struct dram_cfg_param ddr_ddrc_cfg_128mb[] = { > + // IOMUX > + > + //DDR IO TYPE: Please use the standard C comment style: /* For single line comment */ /* * Or this style, * For multi-line comments. */ Also, please put a space before DDR. The same applies everywhere in this series. > + //Write calibration > + { 0x021b0850, 0x4040362E }, // MPWRDLCTL PHY0 > + > + //read data bit delay: 3 is the reccommended default value, although > out of reset value is 0 Typo: recommended > + //MMDC init: > + { 0x021b0004, 0x0002002D }, // MMDC0_MDPDC > + { 0x021b0008, 0x1B333030 }, // MMDC0_MDOTC > + { 0x021b000c, 0x2B2F52F3 }, // MMDC0_MDCFG0 > + { 0x021b0010, 0xB66D0B63 }, // MMDC0_MDCFG1 > + { 0x021b0014, 0x01FF00DB }, // MMDC0_MDCFG2 > + > + //MDMISC: RALAT kept to the high level of 5. > + //MDMISC: consider reducing RALAT if your 528MHz board design allow > that. > + //Lower RALAT benefits: > + //a. better operation at low frequency, for LPDDR2 freq < 100MHz, > change RALAT to 3 > + //b. Small performence improvement Typo: performance > + // {0x021b001c,0x0200803A}, // MMDC0_MDSCR, MR2 write, CS1 > + // {0x021b001c,0x0000803B}, // MMDC0_MDSCR, MR3 write, CS1 > + // {0x021b001c,0x00048039}, // MMDC0_MDSCR, MR1 write, CS1 > + // {0x021b001c,0x15208038}, // MMDC0_MDSCR, MR0write, CS1 > + // {0x021b001c,0x04008048}, // MMDC0_MDSCR, ZQ calibration command > sent to device on CS1 Please don't add the comment code. Please remove these commented code lines. > +static void ddr_cfg_write(const struct dram_timing_info *dram_timing_info) > +{ > + int i = 0; You don't need to initialize i.