@@ -230,7 +230,8 @@ void hal_ddr_init(void)
230230 set_law (4 , 0 , DDR_ADDRESS , LAW_TRGT_DDR_1 , LAW_SIZE_2GB , 0 );
231231
232232 /* If DDR is already enabled then just return */
233- if (get32 (DDR_SDRAM_CFG ) & DDR_SDRAM_CFG_MEM_EN ) {
233+ reg = get32 (DDR_SDRAM_CFG );
234+ if (reg & DDR_SDRAM_CFG_MEM_EN ) {
234235 return ;
235236 }
236237
@@ -369,6 +370,129 @@ static void hal_cpld_init(void)
369370#endif
370371}
371372
373+ #if defined(DEBUG_UART ) && defined(ENABLE_DDR )
374+ /* DDR memory test - writes patterns and verifies readback */
375+ static int hal_ddr_test (void )
376+ {
377+ volatile uint32_t * ddr = (volatile uint32_t * )DDR_ADDRESS ;
378+ uint32_t patterns [] = {0x55555555 , 0xAAAAAAAA , 0x12345678 , 0xDEADBEEF };
379+ uint32_t test_offsets [] = {0 , 0x100 , 0x1000 , 0x10000 , 0x100000 , 0x1000000 };
380+ int i , j ;
381+ int errors = 0 ;
382+ uint32_t reg ;
383+
384+ /* Show DDR controller status */
385+ reg = get32 (DDR_SDRAM_CFG );
386+ wolfBoot_printf ("DDR: SDRAM_CFG=0x%x (MEM_EN=%d)\n" , reg ,
387+ (reg & DDR_SDRAM_CFG_MEM_EN ) ? 1 : 0 );
388+ reg = get32 (DDR_SDRAM_CFG_2 );
389+ wolfBoot_printf ("DDR: SDRAM_CFG_2=0x%x (D_INIT=%d)\n" , reg ,
390+ (reg & DDR_SDRAM_CFG_2_D_INIT ) ? 1 : 0 );
391+
392+ /* Show DDR LAW configuration (LAW 4) */
393+ wolfBoot_printf ("DDR LAW4: H=0x%x L=0x%x AR=0x%x\n" ,
394+ get32 (LAWBARH (4 )), get32 (LAWBARL (4 )), get32 (LAWAR (4 )));
395+
396+ /* Read DDR TLB entry 12 using tlbre */
397+ {
398+ uint32_t mas0 , mas1 , mas2 , mas3 , mas7 ;
399+ /* Select TLB1, entry 12 */
400+ mas0 = (1 << 28 ) | (12 << 16 ); /* TLBSEL=1, ESEL=12 */
401+ mtspr (MAS0 , mas0 );
402+ __asm__ __volatile__("isync; tlbre; isync" );
403+ mas1 = mfspr (MAS1 );
404+ mas2 = mfspr (MAS2 );
405+ mas3 = mfspr (MAS3 );
406+ mas7 = mfspr (MAS7 );
407+ wolfBoot_printf ("DDR TLB12: MAS1=0x%x MAS2=0x%x MAS3=0x%x MAS7=0x%x\n" ,
408+ mas1 , mas2 , mas3 , mas7 );
409+ /* Check if TLB entry is valid */
410+ if (!(mas1 & 0x80000000 )) {
411+ wolfBoot_printf ("DDR: ERROR - TLB12 not valid!\n" );
412+ return -1 ;
413+ }
414+ }
415+
416+ /* Check if DDR is enabled */
417+ if (!(get32 (DDR_SDRAM_CFG ) & DDR_SDRAM_CFG_MEM_EN )) {
418+ wolfBoot_printf ("DDR: ERROR - Memory not enabled!\n" );
419+ return -1 ;
420+ }
421+
422+ /* Check if DDR LAW is enabled */
423+ reg = get32 (LAWAR (4 ));
424+ if (!(reg & LAWAR_ENABLE )) {
425+ wolfBoot_printf ("DDR: ERROR - LAW4 not enabled!\n" );
426+ return -1 ;
427+ }
428+
429+ /* Show DDR chip select configuration */
430+ wolfBoot_printf ("DDR CS0: BNDS=0x%x CFG=0x%x\n" ,
431+ get32 (DDR_CS_BNDS (0 )), get32 (DDR_CS_CONFIG (0 )));
432+ wolfBoot_printf ("DDR CS1: BNDS=0x%x CFG=0x%x\n" ,
433+ get32 (DDR_CS_BNDS (1 )), get32 (DDR_CS_CONFIG (1 )));
434+
435+ /* Show DDR debug status registers */
436+ wolfBoot_printf ("DDR DDRDSR_1=0x%x DDRDSR_2=0x%x\n" ,
437+ get32 (DDR_DDRDSR_1 ), get32 (DDR_DDRDSR_2 ));
438+ wolfBoot_printf ("DDR DDRCDR_1=0x%x DDRCDR_2=0x%x\n" ,
439+ get32 (DDR_DDRCDR_1 ), get32 (DDR_DDRCDR_2 ));
440+
441+ /* Check for pre-existing DDR errors */
442+ reg = get32 (DDR_ERR_DETECT );
443+ wolfBoot_printf ("DDR ERR_DETECT=0x%x\n" , reg );
444+ if (reg != 0 ) {
445+ wolfBoot_printf ("DDR: ERROR - Pre-existing DDR errors!\n" );
446+ wolfBoot_printf (" Bit 31 (MME): %d - Multiple errors\n" , (reg >> 31 ) & 1 );
447+ wolfBoot_printf (" Bit 7 (APE): %d - Address parity\n" , (reg >> 7 ) & 1 );
448+ wolfBoot_printf (" Bit 3 (ACE): %d - Auto calibration\n" , (reg >> 3 ) & 1 );
449+ wolfBoot_printf (" Bit 2 (CDE): %d - Correctable data\n" , (reg >> 2 ) & 1 );
450+ wolfBoot_printf ("DDR: Skipping memory test due to errors\n" );
451+ return -1 ;
452+ }
453+
454+ wolfBoot_printf ("DDR Test: base=0x%x\n" , DDR_ADDRESS );
455+ wolfBoot_printf ("DDR: Attempting simple read at 0x%x...\n" , DDR_ADDRESS );
456+
457+ /* First just try to read - don't write yet */
458+ {
459+ volatile uint32_t val = * ddr ;
460+ wolfBoot_printf ("DDR: Read returned 0x%x\n" , val );
461+ }
462+
463+ for (i = 0 ; i < (int )(sizeof (test_offsets )/sizeof (test_offsets [0 ])); i ++ ) {
464+ uint32_t offset = test_offsets [i ];
465+ volatile uint32_t * addr = ddr + (offset / sizeof (uint32_t ));
466+
467+ for (j = 0 ; j < (int )(sizeof (patterns )/sizeof (patterns [0 ])); j ++ ) {
468+ uint32_t pattern = patterns [j ];
469+ uint32_t readback ;
470+
471+ /* Write pattern */
472+ * addr = pattern ;
473+ __asm__ __volatile__("sync" ::: "memory" );
474+
475+ /* Read back */
476+ readback = * addr ;
477+
478+ if (readback != pattern ) {
479+ wolfBoot_printf (" FAIL: @0x%x wrote 0x%x read 0x%x\n" ,
480+ (uint32_t )addr , pattern , readback );
481+ errors ++ ;
482+ }
483+ }
484+ }
485+
486+ if (errors == 0 ) {
487+ wolfBoot_printf ("DDR Test: PASSED\n" );
488+ } else {
489+ wolfBoot_printf ("DDR Test: FAILED (%d errors)\n" , errors );
490+ }
491+
492+ return errors ;
493+ }
494+ #endif /* DEBUG_UART && ENABLE_DDR */
495+
372496void hal_init (void )
373497{
374498#if defined(DEBUG_UART ) && defined(ENABLE_CPLD )
@@ -401,6 +525,10 @@ void hal_init(void)
401525#ifdef ENABLE_MP
402526 hal_mp_init ();
403527#endif
528+
529+ #if defined(DEBUG_UART ) && defined(ENABLE_DDR )
530+ hal_ddr_test ();
531+ #endif
404532}
405533
406534static void hal_flash_unlock_sector (uint32_t sector )
0 commit comments