LS2088A TFA boot: atf support for static ddr initialization for two controllers

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LS2088A TFA boot: atf support for static ddr initialization for two controllers

1,254 Views
rams
Contributor I

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

Labels (1)
0 Kudos
3 Replies

1,077 Views
yipingwang
NXP TechSupport
NXP TechSupport

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

0 Kudos

1,077 Views
rams
Contributor I

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.

0 Kudos

1,077 Views
yipingwang
NXP TechSupport
NXP TechSupport

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);
}

0 Kudos