Hi, I'm trying to understand how the DDR is configured on LS1028ARDB platform so that to know how this can be done on a custom board, and although it does not seem too much complicated I'm not sure about few parameters in ATF source code used for this purpose.
Here is the code:
static const struct rc_timing rcz[] = {
{
1600, // speed_bin
8, // clk_adj
5 // wrlvl
},
{}
};
static const struct board_timing ram[] = {
{
0x1f, // rc
rcz,
0x1020200, //add1
0x00000003 //add2
},
};
int ddr_board_options(struct ddr_info *priv)
{
int ret;
struct memctl_opt *popts = &priv->opt;
ret = cal_board_params(priv, ram, ARRAY_SIZE(ram));
if (ret != 0) {
return ret;
}
popts->bstopre = U(0x40); /* precharge value */
popts->half_strength_drive_en = 1;
popts->cpo_sample = U(0x46);
popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) |
DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */
popts->addr_hash = 1; /* address hashing */
return 0;
}
/* DDR model number: MT40A1G8SA-075:E */
struct dimm_params ddr_raw_timing = {
.n_ranks = U(1),
.rank_density = ULL(4294967296),
.capacity = ULL(4294967296),
.primary_sdram_width = U(32),
.ec_sdram_width = U(4),
.rdimm = U(0),
.mirrored_dimm = U(0),
.n_row_addr = U(16),
.n_col_addr = U(10),
.bank_group_bits = U(2),
.edc_config = U(2),
.burst_lengths_bitmask = U(0x0c),
.tckmin_x_ps = 750,
.tckmax_ps = 1900,
.caslat_x = U(0x0001FFE00),
.taa_ps = 13500,
.trcd_ps = 13500,
.trp_ps = 13500,
.tras_ps = 32000,
.trc_ps = 45500,
.twr_ps = 15000,
.trfc1_ps = 350000,
.trfc2_ps = 260000,
.trfc4_ps = 160000,
.tfaw_ps = 21000,
.trrds_ps = 3000,
.trrdl_ps = 4900,
.tccdl_ps = 5000,
.refresh_rate_ps = U(7800000),
.dq_mapping[0] = U(0x16),
.dq_mapping[1] = U(0x36),
.dq_mapping[2] = U(0x16),
.dq_mapping[3] = U(0x36),
.dq_mapping[4] = U(0x16),
.dq_mapping[5] = U(0x36),
.dq_mapping[6] = U(0x16),
.dq_mapping[7] = U(0x36),
.dq_mapping[8] = U(0x16),
.dq_mapping[9] = U(0x0),
.dq_mapping[10] = U(0x0),
.dq_mapping[11] = U(0x0),
.dq_mapping[12] = U(0x0),
.dq_mapping[13] = U(0x0),
.dq_mapping[14] = U(0x0),
.dq_mapping[15] = U(0x0),
.dq_mapping[16] = U(0x0),
.dq_mapping[17] = U(0x0),
.dq_mapping_ors = U(0),
.rc = U(0x1f),
};
I would be grateful if somebody could help me to understand:
- dimm_params->rc - what's its purpose and why is it the same as board_timing->rc?
- board_timing->add1 and board_timing->add2 - what's the purpose of these two and how to decide what value should be set here?
And yes, I'm aware that probably CodeWarrior is capable of generating appropriate code, however first I would like to understand what this code actually does.