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.
Hi @pb3,
Regarding to the question "- board_timing->add1 and board_timing->add2 - what's the purpose of these two and how to decide what value should be set here?",
This values are determinated for the values specified on the following images:
As you mention before this values can be taken in codewarrior trought validation tool (Centering the clock test) with Codewarrior TAP (Debugger).
The purpose of this values are set the delay to write levelling start time for DQS [1 to 8].
Regards
HI @pb3,
Just to let you know that I am working on your question.
When I have any update I will let you know
Regards