[U-Boot] [PATCH v2 6/9] mpc85xx: Enable unique mode registers and dynamic ODT for DDR3
Wolfgang Denk
wd at denx.de
Sat Dec 18 23:53:27 CET 2010
Dear York Sun,
In message <1292630381-23022-6-git-send-email-yorksun at freescale.com> you wrote:
> Added fsl_ddr_get_version() function to for DDR3 to poll DDRC IP version
> (major, minor, errata) to determine if unique mode registers are available.
> If true, always use unique mode registers. Dynamic ODT is enabled if needed.
> The table is documented in doc/README.fsl-ddr. This function may also need
> to be extend for future other platforms if such a feature exists.
>
> Enable address parity and RCW by default for RDIMMs.
>
> Change default output driver impedance from 34 ohm to 40ohm. Make it 34ohm for
> quad-rank RDIMMs.
...
> +static void set_ddr_sdram_mode_3(fsl_ddr_cfg_regs_t *ddr,
> + const memctl_options_t *popts)
> +{
> + u16 esdmode; /* Extended SDRAM mode */
> + u16 sdmode; /* SDRAM mode */
> + u32 rtt;
> +
> + sdmode = ddr->ddr_sdram_mode & 0xFFFF;
> + esdmode = (ddr->ddr_sdram_mode >> 16) & 0xFFFF;
> +
> + if (popts->rtt_override)
> + rtt = popts->rtt_override_value;
> + else
> + rtt = popts->cs_local_opts[1].odt_rtt_norm;
> +
> + esdmode &= 0xFDBB; /* clear bit 9,6,2 */
> + esdmode |= (0
> + | ((rtt & 0x4) << 7) /* rtt field is split */
> + | ((rtt & 0x2) << 5) /* rtt field is split */
> + | ((rtt & 0x1) << 2) /* rtt field is split */
> + );
> +
> + ddr->ddr_sdram_mode_3 = (0
> + | ((esdmode & 0xFFFF) << 16)
> + | ((sdmode & 0xFFFF) << 0)
> + );
> + debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n", ddr->ddr_sdram_mode_3);
> +}
...
> +static void set_ddr_sdram_mode_5(fsl_ddr_cfg_regs_t *ddr,
> + const memctl_options_t *popts)
> +{
> + u16 esdmode; /* Extended SDRAM mode */
> + u16 sdmode; /* SDRAM mode */
> + u32 rtt;
> +
> + sdmode = ddr->ddr_sdram_mode & 0xFFFF;
> + esdmode = (ddr->ddr_sdram_mode >> 16) & 0xFFFF;
> +
> + if (popts->rtt_override)
> + rtt = popts->rtt_override_value;
> + else
> + rtt = popts->cs_local_opts[2].odt_rtt_norm;
> +
> + esdmode &= 0xFDBB; /* clear bit 9,6,2 */
> + esdmode |= (0
> + | ((rtt & 0x4) << 7) /* rtt field is split */
> + | ((rtt & 0x2) << 5) /* rtt field is split */
> + | ((rtt & 0x1) << 2) /* rtt field is split */
> + );
> +
> + ddr->ddr_sdram_mode_5 = (0
> + | ((esdmode & 0xFFFF) << 16)
> + | ((sdmode & 0xFFFF) << 0)
> + );
> + debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", ddr->ddr_sdram_mode_5);
> +}
Seems the only difference between these functions is the index into
the array?
> +static void set_ddr_sdram_mode_4(fsl_ddr_cfg_regs_t *ddr,
> + const memctl_options_t *popts)
> +{
> + u16 esdmode2 = 0; /* Extended SDRAM mode 2 */
> + u16 esdmode3 = 0; /* Extended SDRAM mode 3 */
> + u32 rtt_wr = 0; /* Dynamic ODT off */
> +
> + esdmode2 = (ddr->ddr_sdram_mode_2 >> 16) & 0xFFFF;
> + esdmode3 = ddr->ddr_sdram_mode_2 & 0xFFFF;
> +
> + if (popts->rtt_override)
> + rtt_wr = popts->rtt_wr_override_value;
> + else
> + rtt_wr = popts->cs_local_opts[1].odt_rtt_wr;
> +
> + esdmode2 &= 0xF9FF; /* clear bit 10, 9 */
> + esdmode2 |= (rtt_wr & 0x3) << 9;
> + ddr->ddr_sdram_mode_4 = (0
> + | ((esdmode2 & 0xFFFF) << 16)
> + | ((esdmode3 & 0xFFFF) << 0)
> + );
> + debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n", ddr->ddr_sdram_mode_4);
> +}
...
> +static void set_ddr_sdram_mode_6(fsl_ddr_cfg_regs_t *ddr,
> + const memctl_options_t *popts)
> +{
> + u16 esdmode2 = 0; /* Extended SDRAM mode 2 */
> + u16 esdmode3 = 0; /* Extended SDRAM mode 3 */
> + u32 rtt_wr = 0; /* Dynamic ODT off */
> +
> + esdmode2 = (ddr->ddr_sdram_mode_2 >> 16) & 0xFFFF;
> + esdmode3 = ddr->ddr_sdram_mode_2 & 0xFFFF;
> +
> + if (popts->rtt_override)
> + rtt_wr = popts->rtt_wr_override_value;
> + else
> + rtt_wr = popts->cs_local_opts[2].odt_rtt_wr;
> +
> + esdmode2 &= 0xF9FF; /* clear bit 10, 9 */
> + esdmode2 |= (rtt_wr & 0x3) << 9;
> + ddr->ddr_sdram_mode_6 = (0
> + | ((esdmode2 & 0xFFFF) << 16)
> + | ((esdmode3 & 0xFFFF) << 0)
> + );
> + debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n", ddr->ddr_sdram_mode_6);
> +}
Same here.
> +static void set_ddr_sdram_mode_7(fsl_ddr_cfg_regs_t *ddr,
> + const memctl_options_t *popts)
> +{
> + u16 esdmode; /* Extended SDRAM mode */
> + u16 sdmode; /* SDRAM mode */
> + u32 rtt;
> +
> + sdmode = ddr->ddr_sdram_mode & 0xFFFF;
> + esdmode = (ddr->ddr_sdram_mode >> 16) & 0xFFFF;
> +
> + if (popts->rtt_override)
> + rtt = popts->rtt_override_value;
> + else
> + rtt = popts->cs_local_opts[3].odt_rtt_norm;
> +
> + esdmode &= 0xFDBB; /* clear bit 9,6,2 */
> + esdmode |= (0
> + | ((rtt & 0x4) << 7) /* rtt field is split */
> + | ((rtt & 0x2) << 5) /* rtt field is split */
> + | ((rtt & 0x1) << 2) /* rtt field is split */
> + );
> +
> + ddr->ddr_sdram_mode_7 = (0
> + | ((esdmode & 0xFFFF) << 16)
> + | ((sdmode & 0xFFFF) << 0)
> + );
> + debug("FSLDDR: ddr_sdram_mode_7 = 0x%08x\n", ddr->ddr_sdram_mode_7);
> +}
> +
> +static void set_ddr_sdram_mode_8(fsl_ddr_cfg_regs_t *ddr,
> + const memctl_options_t *popts)
> +{
> + u16 esdmode2 = 0; /* Extended SDRAM mode 2 */
> + u16 esdmode3 = 0; /* Extended SDRAM mode 3 */
> + u32 rtt_wr = 0; /* Rtt_WR - dynamic ODT off */
> +
> + esdmode2 = (ddr->ddr_sdram_mode_2 >> 16) & 0xFFFF;
> + esdmode3 = ddr->ddr_sdram_mode_2 & 0xFFFF;
> +
> + if (popts->rtt_override)
> + rtt_wr = popts->rtt_wr_override_value;
> + else
> + rtt_wr = popts->cs_local_opts[3].odt_rtt_wr;
> +
> + esdmode2 &= 0xF9FF; /* clear bit 10, 9 */
> + esdmode2 |= (rtt_wr & 0x3) << 9;
> + ddr->ddr_sdram_mode_8 = (0
> + | ((esdmode2 & 0xFFFF) << 16)
> + | ((esdmode3 & 0xFFFF) << 0)
> + );
> + debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n", ddr->ddr_sdram_mode_8);
> +}
And two more copies...
Please do not duplicate code.
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
There are very few personal problems that cannot be solved through a
suitable application of high explosives.
More information about the U-Boot
mailing list