Hello,
We are implementing TF-A boot for our custom LS2088A/LS2044A hardware.
We have static DDR on our custom board.
The atf implementations have examples for using one DDR controller for CONFIG_STATIC_DDR configuration using board_static_ddr(struct ddr_info *priv) function where the DDR parameters for one controller can be passed to the ddr_info structure .
How do we pass the DDR controller parameters for two controllers simultaneously using board_static_ddr?
Thanks
Ram
Hello Ramasubramanian Subramanian,
Please refer to DDR controller initialization for LX2160ARDB, please refer to plat/nxp/soc-lx2160/lx2160ardb/ddr_init.c.
long long board_static_ddr(struct ddr_info *priv)
{
memcpy(&priv->ddr_reg, &static_1600, sizeof(static_1600));
memcpy(&priv->dimm, &static_dimm, sizeof(static_dimm));
priv->conf.cs_on_dimm[0] = 0x3;
ddr_board_options(priv);
compute_ddr_phy(priv);
return ULL(0x400000000);
}
long long _init_ddr(void)
{...
/* Set two DDRC. Unused DDRC will be removed automatically. */
info.num_ctlrs = 2;
info.spd_addr = spd_addr;
info.ddr[0] = (void *)NXP_DDR_ADDR;
info.ddr[1] = (void *)NXP_DDR2_ADDR;
info.phy[0] = (void *)NXP_DDR_PHY1_ADDR;
info.phy[1] = (void *)NXP_DDR_PHY2_ADDR;
info.clk = get_ddr_freq(&sys, 0);
if (!info.clk)
info.clk = get_ddr_freq(&sys, 1);
info.dimm_on_ctlr = 2;
dram_size = dram_init(&info);
...
}
The function board_static_ddr is invoked by dram_init in plat/nxp/drivers/ddr/nxp-ddr/ddr.c.
Please refer to write_ddrc_regs invoked by dram_init.
static int write_ddrc_regs(struct ddr_info *priv)
{
int i;
int ret;
for (i = 0; i < priv->num_ctlrs; i++) {
ret = ddrc_set_regs(priv->clk, &priv->ddr_reg, priv->ddr[i], 0);
if (ret) {
ERROR("Writing DDR register(s) failed\n");
return ret;
}
}
return 0;
}
Thanks,
Yiping
Hello,
long long board_static_ddr(struct ddr_info *priv)
{
memcpy(&priv->ddr_reg, &static_1600, sizeof(static_1600));
memcpy(&priv->dimm, &static_dimm, sizeof(static_dimm));
priv->conf.cs_on_dimm[0] = 0x3;
ddr_board_options(priv);
compute_ddr_phy(priv);
return ULL(0x400000000);
}
In the example which you have referred, one of the memory controllers, it uses static DDR and the othe other dimm.
In our case, we have to pass two sets of different DDR parameters for static DDR.
Here you use static_1600 struct to copy the ddr parameters to the ddr_reg for one controller and for the second controller &static_dimm for the DIMM DDR.
You could modify _init_ddr in ./plat/nxp/soc-lx2160/lx2160ardb/ddr_init.c as the following to support two sets of different DDR parameters.
/* Set two DDRC. Unused DDRC will be removed automatically. */
info.num_ctlrs = 1;
info.spd_addr = spd_addr;
info.ddr[0] = (void *)NXP_DDR_ADDR;
info.phy[0] = (void *)NXP_DDR_PHY1_ADDR;
...
dram_size = dram_init(&info);
info.ddr[0] = (void *)NXP_DDR2_ADDR;
info.phy[0] = (void *)NXP_DDR_PHY2_ADDR;
dram_size = dram_init(&info);
Please modify function board_static_ddr as the following
long long board_static_ddr(struct ddr_info *priv)
{
if (pri.ddr[0] == NXP_DDR_ADDR)
memcpy(&priv->ddr_reg, &static_1600_ddr1, sizeof(static_1600_ddr1));
else
memcpy(&priv->ddr_reg, &static_1600_ddr2, sizeof(static_1600_ddr2));
memcpy(&priv->dimm, &static_dimm, sizeof(static_dimm));
priv->conf.cs_on_dimm[0] = 0x3;
ddr_board_options(priv);
compute_ddr_phy(priv);
return ULL(0x400000000);
}