We have designed a custom board using LS1043A based on the LS1043ARDB reference design. We have 4GB of DDR4, using 4 x MT40A1G8SA-075:E, clocked at 800 MHz (1600 DDR). The RCW used and relevant parts of the atf/plat/nxp/soc-ls1043/ls1043ardb/ddr_init.c is given further below.
Notes:
1. Clocking is derived from differential SYSCLK inputs which is 100 MHz
2. SD Card boot image (not secure boot) is build with “flex-builder -i mksw -m ls1043ardb -b sd”
Booting from SD card progresses till loading of next stage where the BL3 never starts. The console stops at the following point:
INFO: BL2: Doing platform setup
INFO: BL2: Loading image id 3
INFO: sd-mmc read done.
We believe that this could be due to errors on the DDR. We are looking for help in what needs to be modified in order to get it to the uboot prompt. We have the following observations and queries in this regard:
1. We have bit swizzling within each nibble and accordingly we changed the DQ pin mapping in ddr_raw_timing variable in file ddr_init.c. Till we changed this to the correct values based on the bit swizzling on our board (Relevant parts of the schematics attached), the BL2 compiled with DDR_DEBUG=yes, DDR_BIST=yes and DEBUG=1 was reporting “Error in training” and “DDR init failed” messages. But now we are not getting these errors (see boot log below). It even reports “Built-in self-test passed” message, although there is a “time out” error – see output on console below:
INFO: Running built-in self test ...
INFO: Wait up to 3300 ms
ERROR: Timeout
NOTICE: Build-in self test passed
QUERY: Does the above mean that the DDR is working properly? If so what other reason could be there for the boot to fail? Note that the same code with just the bit-swizzling (DQ map settings) corrected to have no swizzliing boots in the LS1043ARDB reference design board.
2. We also changed the rank_density and capacity to 4294967296u for 4GB in the struct dimm_params along with increasing n_row_addr to 16 (15 in RDB with 2 GB DDR), but retained n_ranks=1 and bank_group_bits = 2.
QUERY: Is this ok?
3. The timing configuration variables were modified based on the DDR part’s datasheet. These modified timings were verified to work in RDB as the part used in RDB has very similar timings. But we did not modify the “struct rc_timing rcz” and “struct board_timing ram[]” from their values for RDB as we do not know what these parameters mean.
QUERY: Should we be changing rcz and ram[] variables? Any documentation on these?
4. We did not modify anything in the ddr_board_options() function.
QUERY: Any changes required here?
5. QUERY: Any issue in the schematics attached?
6. QUERY: Anything else we can try out to fix the issue?
ddr_init.c File
struct dimm_params ddr_raw_timing = { //MODIFIED
.n_ranks = 1,
.rank_density = 4294967296u, //MODIFIED
.capacity = 4294967296u, //MODIFIED
.primary_sdram_width = 32,
.rdimm = 0,
.mirrored_dimm = 0,
.n_row_addr = 16, //MODIFIED
.n_col_addr = 10,
.bank_group_bits = 2,
.edc_config = 0,
.burst_lengths_bitmask = 0x0c,
.tckmin_x_ps = 938,
.tckmax_ps = 1500,
.caslat_x = 0x0001FFE00, //MODIFIED
.dq_mapping[0] = 0x00,
.dq_mapping[1] = 0x21, //MODIFIED
.dq_mapping[2] = 0x16, //MODIFIED
.dq_mapping[3] = 0x35, //MODIFIED
.dq_mapping[4] = 0x16, //MODIFIED
.dq_mapping[5] = 0x36, //MODIFIED
.dq_mapping[6] = 0x08, //MODIFIED
.dq_mapping[7] = 0x36, //MODIFIED
.dq_mapping[8] = 0x0,
.dq_mapping[9] = 0x0,
.dq_mapping[10] = 0x0,
.dq_mapping[11] = 0x0,
.dq_mapping[12] = 0x0,
.dq_mapping[13] = 0x0,
.dq_mapping[14] = 0x0,
.dq_mapping[15] = 0x0,
.dq_mapping[16] = 0x0,
.dq_mapping[17] = 0x0,
.dq_mapping_ors = 0,
.taa_ps = 14250, //MODIFIED
.trcd_ps = 14250, //MODIFIED
.trp_ps = 14250, //MODIFIED
.tras_ps = 32000, //MODIFIED
.trc_ps = 46250, //MODIFIED
.twr_ps = 15000,
.trfc1_ps = 350000, //MODIFIED
.trfc2_ps = 260000, //MODIFIED
.trfc4_ps = 160000, //MODIFIED
.tfaw_ps = 25000, //MODIFIED
.trrds_ps = 5000, //MODIFIED
.trrdl_ps = 5000, //MODIFIED
.tccdl_ps = 5000, //MODIFIED
.refresh_rate_ps = 7800000,
.rc = 0x1f,
};
static const struct rc_timing rcz[] = { //NOT MODIFIED FROM RDB
{1600, 12, 7},
{}
};
static const struct board_timing ram[] = { //NOT MODIFIED FROM RDB
{0x1f, rcz, 0x00020100, 0},
};
int ddr_board_options(struct ddr_info *priv) //NOT MODIFIED FROM RDB
{
int ret;
struct memctl_opt *popts = &priv->opt;
ret = cal_board_params(priv, ram, ARRAY_SIZE(ram));
if (ret)
return ret;
popts->cpo_sample = 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% */
return 0;
}
RCW settings
SYS_PLL_RAT=4
MEM_PLL_RAT=16
CGA_PLL1_RAT=16
CGA_PLL2_RAT=10
SRDS_PRTCL_S1=13144
FM1_MAC_RAT=1
SRDS_PLL_REF_CLK_SEL_S1=0
SRDS_DIV_PEX=1
DDR_FDBK_MULT=2
DDR_REFCLK_SEL=1
PBI_src=6
IFC_MODE=37
HWA_CGA_M1_CLK_SEL=6
DRAM_LAT=1
SYS_PLL_SPD=1
UART_EXT=0
IRQ_EXT=0
SPI_EXT=0
SDHC_EXT=0
UART_BASE=5
SDHC_BASE=0
IRQ_OUT=1
IRQ_BASE=1
SPI_BASE=0
EC1=0
EC2=0
EM1=0
EM2=0
EMI2_DMODE=1
EMI2_CMODE=1
TVDD_VSEL=1
DVDD_VSEL=2
QE_CLK_OVRRIDE=0
EMI1_DMODE=1
EVDD_VSEL=2
IIC2_BASE=0
EMI1_CMODE=1
IIC2_EXT=0
SYSCLK_FREQ=600
HWA_CGA_M2_CLK_SEL=1
=====================================
Boot Console Log: (Hangs before loading next stage)
=====================================
INFO: SoC workaround for Errata A008850 Early-Phase was applied
INFO: SoC workaround for Errata A009660 was applied
INFO: SoC workaround for Errata A010539 was applied
INFO: RCW BOOT SRC is SD/EMMC
INFO: SoC workaround for DDR Errata A009942 was applied
INFO: SoC workaround for DDR Errata A009663 was applied
NOTICE: platform clock 400000000
NOTICE: DDR PLL1 1600000000
NOTICE: DDR PLL2 400000000
INFO: time base 8 ms
INFO: Parse DIMM SPD(s)
INFO: cs_in_use = 1
INFO: cs_on_dimm[0] = 1
NOTICE: Fixed DDR on board
INFO: Time after parsing SPD 14 ms
INFO: Synthesize configurations
INFO: cs 0
INFO: odt_rd_cfg 0x0
INFO: odt_wr_cfg 0x4
INFO: odt_rtt_norm 0x3
INFO: odt_rtt_wr 0x0
INFO: auto_precharge 0
INFO: cs 1
INFO: odt_rd_cfg 0x0
INFO: odt_wr_cfg 0x0
INFO: odt_rtt_norm 0x0
INFO: odt_rtt_wr 0x0
INFO: auto_precharge 0
INFO: cs 2
INFO: odt_rd_cfg 0x0
INFO: odt_wr_cfg 0x0
INFO: odt_rtt_norm 0x0
INFO: odt_rtt_wr 0x0
INFO: auto_precharge 0
INFO: cs 3
INFO: odt_rd_cfg 0x0
INFO: odt_wr_cfg 0x0
INFO: odt_rtt_norm 0x0
INFO: odt_rtt_wr 0x0
INFO: auto_precharge 0
INFO: ctlr_init_ecc 0
INFO: x4_en 0
INFO: ap_en 0
INFO: ctlr_intlv 0
INFO: ctlr_intlv_mode 0
INFO: ba_intlv 0x0
INFO: data_bus_used 1
INFO: otf_burst_chop_en 0
INFO: burst_length 0x8
INFO: dbw_cap_shift 0
INFO: Assign binding addresses
INFO: ctlr_intlv 0
INFO: rank density 0x100000000
INFO: CS 0
INFO: base_addr 0x0
INFO: size 0x100000000
INFO: base 0x0
INFO: Total mem by assignment is 0x100000000
INFO: Calculate controller registers
INFO: Skip CL mask for this speed 0x0
INFO: Skip caslat 0x0
INFO: cal cs
INFO: cs_in_use = 0x1
INFO: cs0
INFO: _config = 0x80040322
INFO: cs[0].bnds = 0xff
INFO: sdram_cfg[0] = 0xc50c0000
INFO: sdram_cfg[1] = 0x401100
INFO: sdram_cfg[2] = 0x0
INFO: timing_cfg[0] = 0x91550018
INFO: timing_cfg[1] = 0xcac60c42
INFO: timing_cfg[2] = 0x48c114
INFO: timing_cfg[3] = 0x1111000
INFO: timing_cfg[4] = 0x2
INFO: timing_cfg[5] = 0x4401400
INFO: timing_cfg[6] = 0x0
INFO: timing_cfg[7] = 0x23300000
INFO: timing_cfg[8] = 0x3114600
INFO: timing_cfg[9] = 0x0
INFO: dq_map[0] = 0x215b558
INFO: dq_map[1] = 0xd88d8000
INFO: dq_map[2] = 0x0
INFO: dq_map[3] = 0x0
INFO: sdram_mode[0] = 0x3010214
INFO: sdram_mode[1] = 0x0
INFO: sdram_mode[9] = 0x4000000
INFO: sdram_mode[8] = 0x500
INFO: sdram_mode[2] = 0x10214
INFO: sdram_mode[3] = 0x0
INFO: sdram_mode[10] = 0x400
INFO: sdram_mode[11] = 0x4000000
INFO: sdram_mode[4] = 0x10214
INFO: sdram_mode[5] = 0x0
INFO: sdram_mode[12] = 0x400
INFO: sdram_mode[13] = 0x4000000
INFO: sdram_mode[6] = 0x10214
INFO: sdram_mode[7] = 0x0
INFO: sdram_mode[14] = 0x400
INFO: sdram_mode[15] = 0x4000000
INFO: interval = 0x18600618
INFO: zq_cntl = 0x8a090705
INFO: ddr_sr_cntr = 0x0
INFO: clk_cntl = 0x2000000
INFO: cdr[0] = 0x80040000
INFO: cdr[1] = 0xa181
INFO: wrlvl_cntl[0] = 0x8675f605
INFO: wrlvl_cntl[1] = 0x6070705
INFO: wrlvl_cntl[2] = 0x5050508
INFO: debug[28] = 0x46
INFO: Time before programming controller 262 ms
INFO: Program controller registers
INFO: Reading debug[9] as 0x16001600
INFO: Reading debug[10] as 0x1a001c00
INFO: cpo_min 0x16
INFO: cpo_max 0x1c
INFO: debug[28] 0x700046
INFO: Optimal cpo_sample 0x40
INFO: Running built-in self test ...
INFO: Wait up to 3300 ms
ERROR: Timeout
NOTICE: Build-in self test passed
INFO: *0x1080000 = 0xff
INFO: *0x1080080 = 0x80040322
INFO: *0x1080100 = 0x1111000
INFO: *0x1080104 = 0x91550018
INFO: *0x1080108 = 0xcac60c42
INFO: *0x108010c = 0x48c114
INFO: *0x1080110 = 0xc50c0000
INFO: *0x1080114 = 0x401100
INFO: *0x1080118 = 0x3010214
INFO: *0x1080124 = 0x18600618
INFO: *0x1080128 = 0xdeadbeef
INFO: *0x1080130 = 0x2000000
INFO: *0x1080160 = 0x2
INFO: *0x1080164 = 0x4401400
INFO: *0x108016c = 0x23300000
INFO: *0x1080170 = 0x8a090705
INFO: *0x1080174 = 0xc675f605
INFO: *0x1080190 = 0x6070705
INFO: *0x1080194 = 0x5050508
INFO: *0x1080200 = 0x10214
INFO: *0x1080208 = 0x10214
INFO: *0x1080210 = 0x10214
INFO: *0x1080220 = 0x500
INFO: *0x1080224 = 0x4000000
INFO: *0x1080228 = 0x400
INFO: *0x108022c = 0x4000000
INFO: *0x1080230 = 0x400
INFO: *0x1080234 = 0x4000000
INFO: *0x1080238 = 0x400
INFO: *0x108023c = 0x4000000
INFO: *0x1080250 = 0x3114600
INFO: *0x1080270 = 0x80000000
INFO: *0x1080280 = 0xffffffff
INFO: *0x1080284 = 0x77edeebe
INFO: *0x1080288 = 0xff0000
INFO: *0x108028c = 0xffffffff
INFO: *0x1080290 = 0xffff0001
INFO: *0x1080400 = 0x215b558
INFO: *0x1080404 = 0xd88d8000
INFO: *0x1080b20 = 0x8080
INFO: *0x1080b24 = 0x80000000
INFO: *0x1080b28 = 0x80040000
INFO: *0x1080b2c = 0xa181
INFO: *0x1080bf8 = 0x20501
INFO: *0x1080bfc = 0x200
INFO: *0x1080d00 = 0x80060000
INFO: *0x1080d20 = 0xffffffff
INFO: *0x1080d28 = 0xaaaaaaaa
INFO: *0x1080d2c = 0x55555555
INFO: *0x1080d30 = 0xcccccccc
INFO: *0x1080d34 = 0x33333333
INFO: *0x1080d38 = 0x12345678
INFO: *0x1080d3c = 0xabcdef01
INFO: *0x1080d40 = 0xaa55aa55
INFO: *0x1080d44 = 0x55aa55aa
INFO: *0x1080f08 = 0xc
INFO: *0x1080f0c = 0x14000c20
INFO: *0x1080f24 = 0x16001600
INFO: *0x1080f28 = 0x1a001c00
INFO: *0x1080f34 = 0x3000
INFO: *0x1080f48 = 0x1
INFO: *0x1080f4c = 0x11000000
INFO: *0x1080f50 = 0x6000500
INFO: *0x1080f54 = 0xe000f00
INFO: *0x1080f58 = 0xa000a00
INFO: *0x1080f5c = 0xa000a00
INFO: *0x1080f60 = 0x10000000
INFO: *0x1080f70 = 0x700046
NOTICE: 4 GB DDR4, 32-bit, CL=12, ECC off
INFO: Time used by DDR driver 4208 ms
INFO: SoC workaround for Errata A008850 Post-Phase was applied
INFO: RCW BOOT SRC is SD/EMMC
INFO: esdhc_emmc_init
INFO: Card detected successfully
INFO: init done:
NOTICE: BL2: v2.4(release):LSDK-21.08-0-g340b20bcb-dirty
NOTICE: BL2: Built : 17:29:40, Jun 15 2022
NOTICE: BL2D:1
INFO: Configuring TrustZone Controller tzc380
NOTICE: BL2D:2
INFO: BL2: Doing platform setup
INFO: BL2: Loading image id 3
INFO: sd-mmc read done.
You could use QCVS DDRv tool to assist you to do validation and optimization.
Please refer to the attached user manual.
Please download CW4NET_v2020.06 from the following link and install it on your PC.
https://drive.google.com/file/d/1Kjq1nLYrtIfWAHYrup5Cf-TTEJI9iWiu/view?usp=sharing
Please download armv8 11.5.5 pack form the
following link and open CodeWarrior IDE to install it from Help->Install New
Software->Add->Archive.
https://drive.google.com/file/d/1ZHiYWDOhb27o0oD5Brqjn4_vJzRUCKoY/view?usp=sharing
Please use "read from SPD" method to create a QCVS DDR project, then connect to the target board to do validation.