Skip to content

Commit ca407ea

Browse files
committed
Fixes for boot
1 parent c684d48 commit ca407ea

3 files changed

Lines changed: 139 additions & 28 deletions

File tree

hal/nxp_ppc.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,11 @@
118118
#define ENABLE_INTERRUPTS
119119

120120
/* T1040 has a 256KB CPC (CoreNet Platform Cache), not PSRAM.
121-
* Use L1 locked dcache (16KB) as initial stack, same as T2080.
122-
* CPC SRAM is configured but not used for stack to avoid
123-
* cold power cycle reliability issues via CoreNet. */
121+
* Stage1: Use L1 locked dcache (16KB) as initial stack before DDR.
122+
* wolfBoot main: DDR already initialized by stage1, use DDR stack. */
123+
#ifdef BUILD_LOADER_STAGE1
124124
#define L1_CACHE_ADDR (0xFDFC0000UL)
125+
#endif
125126

126127
#define L2SRAM_ADDR (0xFDFE0000UL) /* CPC as SRAM (256KB) */
127128
#define L2SRAM_SIZE (256UL * 1024UL)

hal/nxp_t10xx.c

Lines changed: 131 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,23 @@
6464
#endif
6565
#endif
6666

67-
#define USE_ERRATA_DDRA008378
6867
#define USE_ERRATA_DDRA009663
69-
#define USE_ERRATA_DDRA009942
68+
/* A-008378: DDR4 write leveling fix — must set DEBUG_29[8:11]=0x9 before
69+
* controller enable. Required for all DDR4 targets (T1024 and T1040).
70+
* Without this, write leveling fails: DEBUG_10-13 stuck at 0x10101010
71+
* and ERR_DETECT shows ACE (Automatic Calibration Error). */
72+
#define USE_ERRATA_DDRA008378
7073
#ifdef TARGET_nxp_t1024
7174
/* A-008109: T1024 rev 1.0 specific - DDR controller init failure */
7275
#define USE_ERRATA_DDRA008109
76+
/* A-009942: CPO non-optimal - T1024 pre-enable path */
77+
#define USE_ERRATA_DDRA009942
78+
#endif
79+
#ifdef TARGET_nxp_t1040
80+
/* A-009942: applied post-D_INIT per U-Boot fsl_ddr_gen4.c.
81+
* A-008378 sets DEBUG_29 bits [8:11] for training; A-009942 then
82+
* adjusts CPO after training completes. */
83+
#define USE_ERRATA_DDRA009942_T1040
7384
#endif
7485

7586
/* Forward declarations */
@@ -766,7 +777,11 @@ enum ifc_amask_sizes {
766777
* WRTORD_BG [20-23]: 1000: Last write data pair to read command issue interval for the same bank group(tWTR_L)
767778
* PRE_ALL_REC [27-31]: 00000: Precharge all-to-activate interval
768779
*/
780+
#ifdef TARGET_nxp_t1040
781+
#define DDR_TIMING_CFG_8_VAL 0x01004600
782+
#else
769783
#define DDR_TIMING_CFG_8_VAL 0x03115800
784+
#endif
770785

771786
/* MR1 | MR0
772787
* MR0 0x0215
@@ -818,30 +833,64 @@ enum ifc_amask_sizes {
818833
*/
819834
#define DDR_SDRAM_MODE_2_VAL 0x00000000
820835

821-
/* Not applicable (reuse other MRs) */
822-
#define DDR_SDRAM_MODE_3_8_VAL 0x00000000
836+
/* MODE_3 through MODE_8: Per-CS mode register values.
837+
* For T1040 (dual-rank interleaved), CS1 gets same MR values as CS0.
838+
* MODE_3 = CS1 MR1|MR0, MODE_5 = CS1 MR2|MR3, etc.
839+
* For T1024, these are unused (single CS per rank). */
840+
#ifdef TARGET_nxp_t1040
841+
#define DDR_SDRAM_MODE_3_VAL 0x00010210 /* CS1: MR1|MR0 (same as MODE) */
842+
#define DDR_SDRAM_MODE_4_8_VAL 0x00000000 /* CS1: remaining MRs */
843+
#else
844+
#define DDR_SDRAM_MODE_3_VAL 0x00000000
845+
#define DDR_SDRAM_MODE_4_8_VAL 0x00000000
846+
#endif
823847

824848
/* MR4 | MR5
825849
* MR4: 0x0100
826850
* MR5: 0x013F: RTT_PARK=000 disabled, CA Parity Latency=010 (5 clocks) */
827851
#ifdef TARGET_nxp_t1040
828-
#define DDR_SDRAM_MODE_9_VAL 0x00010210
852+
#define DDR_SDRAM_MODE_9_VAL 0x00000500
829853
#else
830854
#define DDR_SDRAM_MODE_9_VAL 0x00000500
831855
#endif
832856

833857
/* MR6 | MR7:
834858
* MR7: CCD_L 010=6 clocks, VREF Range 1 */
835859
#ifdef TARGET_nxp_t1040
836-
#define DDR_SDRAM_MODE_10_VAL 0x00000500
860+
#define DDR_SDRAM_MODE_10_VAL 0x00000000
837861
#else
838862
#define DDR_SDRAM_MODE_10_VAL 0x04000000
839863
#endif
840864

865+
/* MODE_11/12: CS1 MR4|MR5 and MR6|MR7 */
866+
#ifdef TARGET_nxp_t1040
867+
#define DDR_SDRAM_MODE_11_VAL 0x00000400
868+
#else
869+
#define DDR_SDRAM_MODE_11_VAL 0x00000000
870+
#endif
871+
872+
/* DQ Map: Board-specific physical-to-logical DQ lane mapping.
873+
* Required for DDR4 training (write leveling, read gate, DQ centering).
874+
* Without correct DQ mapping, ALL training fails with ACE error.
875+
* Values from U-Boot T1040D4RDB board file. */
876+
#ifdef TARGET_nxp_t1040
877+
#define DDR_DQ_MAP_0_VAL 0x32C57554
878+
#define DDR_DQ_MAP_1_VAL 0xD4BB0BD4
879+
#define DDR_DQ_MAP_2_VAL 0x2EC2F554
880+
#define DDR_DQ_MAP_3_VAL 0xD95D4001
881+
#else
882+
#define DDR_DQ_MAP_0_VAL 0x00000000
883+
#define DDR_DQ_MAP_1_VAL 0x00000000
884+
#define DDR_DQ_MAP_2_VAL 0x00000000
885+
#define DDR_DQ_MAP_3_VAL 0x00000000
886+
#endif
887+
841888
#define DDR_SDRAM_MD_CNTL_VAL 0x03001000
842889

843890
#ifdef TARGET_nxp_t1040
844-
#define DDR_SDRAM_CFG_VAL 0xE5044008 /* DDR4 w/ECC */
891+
/* TODO: Re-enable ECC after DDR debug. Disabling ECC+D_INIT to isolate
892+
* DDR training from D_INIT hang issue. 0xE5044008 -> 0xC5044008 (clear ECC_EN) */
893+
#define DDR_SDRAM_CFG_VAL 0xC5044008 /* DDR4 w/o ECC (debug) */
845894
#else
846895
#define DDR_SDRAM_CFG_VAL 0xE5200000 /* DDR4 w/ECC */
847896
#endif
@@ -924,13 +973,22 @@ enum ifc_amask_sizes {
924973
#define DDR_SDRAM_RCW_2_VAL 0x00000000
925974

926975

927-
/* DHC_EN[0]=1, ODT[12-13]=120 Ohms, VREF_OVRD 37% */
976+
/* DDR_DDRCDR_1: DHC_EN (bit 31) | ODT impedance
977+
* T1040 DDR4: DHC_EN | ODT=120Ohm -> 0x80000000 | (0x2 << 17) = 0x80040000
978+
* T1024 DDR3: DHC_EN only -> 0x80000000 */
928979
#ifdef TARGET_nxp_t1040
929-
#define DDR_DDRCDR_1_VAL 0x01004600
980+
#define DDR_DDRCDR_1_VAL 0x80040000
930981
#else
931-
#define DDR_DDRCDR_1_VAL 0x80000000 /* was 0x80080000 */
982+
#define DDR_DDRCDR_1_VAL 0x80000000
932983
#endif
984+
/* DDR_DDRCDR_2: Vref override and ODT
985+
* T1040 DDR4: VREF_OVRD(70%) | VREF_TRAIN_EN = 0x0000A180
986+
* T1024 DDR3: no Vref training -> 0x00000000 */
987+
#ifdef TARGET_nxp_t1040
988+
#define DDR_DDRCDR_2_VAL 0x0000A180
989+
#else
933990
#define DDR_DDRCDR_2_VAL 0x00000000
991+
#endif
934992

935993
#define DDR_ERR_INT_EN_VAL 0x0000001D
936994
#define DDR_ERR_SBE_VAL 0x00000000
@@ -973,6 +1031,7 @@ enum ifc_amask_sizes {
9731031
#define DDR_DDRCDR_2 ((volatile uint32_t*)(DDR_BASE + 0xB2C)) /* DDR Control Driver Register 2 */
9741032
#define DDR_DDRDSR_1 ((volatile uint32_t*)(DDR_BASE + 0xB20)) /* DDR Debug Status Register 1 */
9751033
#define DDR_DDRDSR_2 ((volatile uint32_t*)(DDR_BASE + 0xB24)) /* DDR Debug Status Register 2 */
1034+
#define DDR_ERR_DETECT ((volatile uint32_t*)(DDR_BASE + 0xE40)) /* Memory error detect (W1C) */
9761035
#define DDR_ERR_DISABLE ((volatile uint32_t*)(DDR_BASE + 0xE44)) /* Memory error disable */
9771036
#define DDR_ERR_INT_EN ((volatile uint32_t*)(DDR_BASE + 0xE48)) /* Memory error interrupt enable */
9781037
#define DDR_ERR_SBE ((volatile uint32_t*)(DDR_BASE + 0xE58)) /* Single-Bit ECC memory error management */
@@ -986,9 +1045,15 @@ enum ifc_amask_sizes {
9861045
#define DDR_SDRAM_MODE_8 ((volatile uint32_t*)(DDR_BASE + 0x214)) /* DDR SDRAM mode configuration 8 */
9871046
#define DDR_SDRAM_MODE_9 ((volatile uint32_t*)(DDR_BASE + 0x220)) /* DDR SDRAM mode configuration 9 */
9881047
#define DDR_SDRAM_MODE_10 ((volatile uint32_t*)(DDR_BASE + 0x224)) /* DDR SDRAM mode configuration 10 */
1048+
#define DDR_SDRAM_MODE_11 ((volatile uint32_t*)(DDR_BASE + 0x228)) /* DDR SDRAM mode configuration 11 */
9891049
#define DDR_SDRAM_MD_CNTL ((volatile uint32_t*)(DDR_BASE + 0x120)) /* DDR SDRAM mode control */
9901050
#define DDR_SDRAM_CLK_CNTL ((volatile uint32_t*)(DDR_BASE + 0x130)) /* DDR SDRAM clock control */
9911051

1052+
#define DDR_DQ_MAP_0 ((volatile uint32_t*)(DDR_BASE + 0x400)) /* DDR DQ Map 0 */
1053+
#define DDR_DQ_MAP_1 ((volatile uint32_t*)(DDR_BASE + 0x404)) /* DDR DQ Map 1 */
1054+
#define DDR_DQ_MAP_2 ((volatile uint32_t*)(DDR_BASE + 0x408)) /* DDR DQ Map 2 */
1055+
#define DDR_DQ_MAP_3 ((volatile uint32_t*)(DDR_BASE + 0x40C)) /* DDR DQ Map 3 */
1056+
9921057
#define DDR_DEBUG_9 ((volatile uint32_t*)(DDR_BASE + 0xF20))
9931058
#define DDR_DEBUG_10 ((volatile uint32_t*)(DDR_BASE + 0xF24))
9941059
#define DDR_DEBUG_11 ((volatile uint32_t*)(DDR_BASE + 0xF28))
@@ -1336,6 +1401,11 @@ static void hal_ddr_init(void)
13361401
return;
13371402
}
13381403

1404+
/* Ensure DDR controller is in clean state (debug session may leave stale config) */
1405+
set32(DDR_SDRAM_CFG, 0);
1406+
set32(DDR_SDRAM_CFG_2, 0);
1407+
__asm__ __volatile__("sync;isync");
1408+
13391409
/* Set early for clock / pin */
13401410
set32(DDR_SDRAM_CLK_CNTL, DDR_SDRAM_CLK_CNTL_VAL);
13411411

@@ -1370,16 +1440,23 @@ static void hal_ddr_init(void)
13701440
/* DDR SDRAM mode configuration */
13711441
set32(DDR_SDRAM_MODE, DDR_SDRAM_MODE_VAL);
13721442
set32(DDR_SDRAM_MODE_2, DDR_SDRAM_MODE_2_VAL);
1373-
set32(DDR_SDRAM_MODE_3, DDR_SDRAM_MODE_3_8_VAL);
1374-
set32(DDR_SDRAM_MODE_4, DDR_SDRAM_MODE_3_8_VAL);
1375-
set32(DDR_SDRAM_MODE_5, DDR_SDRAM_MODE_3_8_VAL);
1376-
set32(DDR_SDRAM_MODE_6, DDR_SDRAM_MODE_3_8_VAL);
1377-
set32(DDR_SDRAM_MODE_7, DDR_SDRAM_MODE_3_8_VAL);
1378-
set32(DDR_SDRAM_MODE_8, DDR_SDRAM_MODE_3_8_VAL);
1443+
set32(DDR_SDRAM_MODE_3, DDR_SDRAM_MODE_3_VAL);
1444+
set32(DDR_SDRAM_MODE_4, DDR_SDRAM_MODE_4_8_VAL);
1445+
set32(DDR_SDRAM_MODE_5, DDR_SDRAM_MODE_4_8_VAL);
1446+
set32(DDR_SDRAM_MODE_6, DDR_SDRAM_MODE_4_8_VAL);
1447+
set32(DDR_SDRAM_MODE_7, DDR_SDRAM_MODE_4_8_VAL);
1448+
set32(DDR_SDRAM_MODE_8, DDR_SDRAM_MODE_4_8_VAL);
13791449
set32(DDR_SDRAM_MODE_9, DDR_SDRAM_MODE_9_VAL);
13801450
set32(DDR_SDRAM_MODE_10, DDR_SDRAM_MODE_10_VAL);
1451+
set32(DDR_SDRAM_MODE_11, DDR_SDRAM_MODE_11_VAL);
13811452
set32(DDR_SDRAM_MD_CNTL, DDR_SDRAM_MD_CNTL_VAL);
13821453

1454+
/* DQ Map: physical-to-logical DQ lane mapping (board-specific) */
1455+
set32(DDR_DQ_MAP_0, DDR_DQ_MAP_0_VAL);
1456+
set32(DDR_DQ_MAP_1, DDR_DQ_MAP_1_VAL);
1457+
set32(DDR_DQ_MAP_2, DDR_DQ_MAP_2_VAL);
1458+
set32(DDR_DQ_MAP_3, DDR_DQ_MAP_3_VAL);
1459+
13831460
/* DDR Configuration */
13841461
#ifdef USE_ERRATA_DDRA009663
13851462
/* Errata A-009663 - DRAM VRef training (do not set precharge interval till after enable) */
@@ -1399,14 +1476,19 @@ static void hal_ddr_init(void)
13991476
set32(DDR_SDRAM_RCW_5, 0);
14001477
set32(DDR_SDRAM_RCW_6, 0);
14011478
set32(DDR_DDRCDR_1, DDR_DDRCDR_1_VAL);
1402-
set32(DDR_SDRAM_CFG_2, (DDR_SDRAM_CFG_2_VAL | DDR_SDRAM_CFG_2_D_INIT));
1479+
/* TODO: Re-enable D_INIT after DDR debug.
1480+
* Skip D_INIT when ECC is disabled — not needed without ECC. */
1481+
set32(DDR_SDRAM_CFG_2, DDR_SDRAM_CFG_2_VAL);
14031482
set32(DDR_INIT_ADDR, 0);
14041483
set32(DDR_INIT_EXT_ADDR, 0);
14051484
set32(DDR_DDRCDR_2, DDR_DDRCDR_2_VAL);
14061485
set32(DDR_ERR_DISABLE, 0);
14071486
set32(DDR_ERR_INT_EN, DDR_ERR_INT_EN_VAL);
14081487
set32(DDR_ERR_SBE, DDR_ERR_SBE_VAL);
14091488

1489+
/* Clear any stale error flags from previous boot attempt */
1490+
set32(DDR_ERR_DETECT, 0xFFFFFFFF);
1491+
14101492
/* Set values, but do not enable the DDR yet */
14111493
set32(DDR_SDRAM_CFG, DDR_SDRAM_CFG_VAL & ~DDR_SDRAM_CFG_MEM_EN);
14121494
__asm__ __volatile__("sync;isync");
@@ -1449,19 +1531,44 @@ static void hal_ddr_init(void)
14491531
set32(DDR_DEBUG_29, reg);
14501532
#endif
14511533

1452-
/* Wait for data initialization to complete.
1453-
* Use simple delay loop instead of udelay() — timebase may not be
1454-
* running yet during early stage1 init (RCPM clock distribution). */
1455-
while (get32(DDR_SDRAM_CFG_2) & DDR_SDRAM_CFG_2_D_INIT) {
1456-
volatile int i;
1457-
for (i = 0; i < 1000; i++)
1458-
;
1534+
/* Wait for data initialization to complete (with timeout).
1535+
* D_INIT is only set when ECC is enabled. */
1536+
{
1537+
volatile uint32_t timeout = 0;
1538+
while (get32(DDR_SDRAM_CFG_2) & DDR_SDRAM_CFG_2_D_INIT) {
1539+
volatile int i;
1540+
for (i = 0; i < 1000; i++)
1541+
;
1542+
if (++timeout > 100000)
1543+
break; /* timeout — continue anyway for debugging */
1544+
}
14591545
}
14601546

14611547
#ifdef USE_ERRATA_DDRA009663
14621548
/* Errata A-009663 - Write real precharge interval */
14631549
set32(DDR_SDRAM_INTERVAL, DDR_SDRAM_INTERVAL_VAL);
14641550
#endif
1551+
1552+
#ifdef USE_ERRATA_DDRA009942_T1040
1553+
/* Errata A-009942: DDR controller can train to non-optimal CPO setting.
1554+
* Applied post-D_INIT per U-Boot fsl_ddr_gen4.c.
1555+
* Mask clears bits [23:20] (A-008378 field) and bits [7:0] (old CPO),
1556+
* then sets CPO=0x6F and bits [22:20]=0x7 for <=1600MHz. */
1557+
reg = get32(DDR_DEBUG_29);
1558+
reg &= 0xFF0FFF00;
1559+
reg |= 0x0070006F;
1560+
set32(DDR_DEBUG_29, reg);
1561+
#endif
1562+
1563+
/* Wait for DDR training to complete after enable.
1564+
* DDR4 write leveling + read gate + DQ centering takes several ms.
1565+
* Must delay before first DDR access. */
1566+
{
1567+
volatile int d;
1568+
for (d = 0; d < 500000; d++)
1569+
;
1570+
}
1571+
__asm__ __volatile__("sync;isync");
14651572
#endif
14661573
}
14671574

stage1/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ endif
8484
MAIN_TARGET=loader_stage1.bin
8585
TARGET_H_TEMPLATE:=../include/target.h.in
8686

87-
ASFLAGS:=$(CFLAGS)
8887
BOOTLOADER_PARTITION_SIZE?=$$(( $(WOLFBOOT_PARTITION_BOOT_ADDRESS) - $(ARCH_FLASH_OFFSET)))
8988

9089
ifeq ($(WOLFBOOT_STAGE1_SIZE),)
@@ -99,6 +98,10 @@ CFLAGS+=\
9998
-DWOLFBOOT_STAGE1_FLASH_ADDR=$(WOLFBOOT_STAGE1_FLASH_ADDR) \
10099
-DWOLFBOOT_STAGE1_BASE_ADDR=$(WOLFBOOT_STAGE1_BASE_ADDR)
101100

101+
# ASFLAGS must be set after BUILD_LOADER_STAGE1 is added to CFLAGS,
102+
# so assembly files see the same defines as C files.
103+
ASFLAGS:=$(CFLAGS)
104+
102105
# For printf support (disable NO_PRINTF_UART) and increase WOLFBOOT_STAGE1_SIZE
103106
ifeq ($(ARCH),PPC)
104107
CFLAGS+=-g -gdwarf-4

0 commit comments

Comments
 (0)