/* * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Board specific setup info * ****************************************************************************** * ASPEED Technology Inc. * AST26x0 DDR3/DDR4 SDRAM controller initialization sequence for FPGA * * Version : 2 * Release date: 2019.02.19 * * Priority of fix item: * [P1] = critical * [P2] = nice to have * [P3] = minor * * Change List : * V0 |2018.03.28 : 1.[P1] Initial release for simulation * * Optional define variable * 1. ECC Function enable * ASTMMC_DRAM_ECC // define to enable ECC function * ASTMMC_DRAM_ECC_SIZE // define the ECC protected memory size * 2. UART5 message output // * ASTMMC_UART_BASE // select UART port base * 3. DRAM Type * ASTMMC_DDR4_8GX8 // DDR4 (16Gb) 8Gbit X8 stacked part ****************************************************************************** */ #include #include #include #include #ifdef CONFIG_CPU_ARM1176 #define ASTMMC_DDR_DDR3 #else #define ASTMMC_READ_TRAINING #endif /****************************************************************************** Calibration Macro Start Usable registers: r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, r11 ******************************************************************************/ #define ASTMMC_INIT_VER 0x02 // 8bit verison number #define ASTMMC_INIT_DATE 0x20190219 // Release date /* PATTERN_TABLE, init_delay_timer, check_delay_timer, clear_delay_timer, print_hex_char, print_hex_byte, print_hex_word, print_hex_dword, are for DRAM calibration */ #define ASTMMC_UART_BASE 0x1E784000 #ifdef CONFIG_DRAM_ECC #define ASTMMC_DRAM_ECC #define ASTMMC_DRAM_ECC_SIZE CONFIG_DRAM_ECC_SIZE #else #define ASTMMC_DRAM_ECC_SIZE 0x0 #endif #define ASTMMC_REG_MCR10 0x00 #define ASTMMC_REG_MCR14 0x04 #define ASTMMC_REG_MCR18 0x08 #define ASTMMC_REG_MCR1C 0x0C #define ASTMMC_REG_MCR20 0x10 #define ASTMMC_REG_MCR24 0x14 #define ASTMMC_REG_MCR28 0x18 #define ASTMMC_REG_MCR2C 0x1C #define ASTMMC_REG_RFC 0x20 TIME_TABLE_DDR3: .word 0x02070306 // MCR10 .word 0x05021133 // MCR14 .word 0x06010200 // MCR18 .word 0x00000020 // MCR1C .word 0x00071320 // MCR20 .word 0x00000200 // MCR24 .word 0x00000000 // MCR28 .word 0x00000000 // MCR2C .word 0x17263434 // MCRFC TIME_TABLE_DDR4: .word 0x030C0207 // MCR10 .word 0x04451133 // MCR14 .word 0x0E010200 // MCR18 .word 0x00000140 // MCR1C .word 0x03010100 // MCR20 .word 0x00000000 // MCR24 .word 0x04C00000 // MCR28 .word 0x00000050 // MCR2C .word 0x17263434 // MCRFC PATTERN_TABLE: .word 0xff00ff00 .word 0xcc33cc33 .word 0xaa55aa55 .word 0x88778877 .word 0x92cc4d6e // 5 .word 0x543d3cde .word 0xf1e843c7 .word 0x7c61d253 .word 0x00000000 // 8 .macro init_delay_timer ldr r0, =0x1e782024 // Set Timer3 Reload str r2, [r0] ldr r0, =0x1e782034 // Clear Timer3 ISR ldr r1, =0x00000004 str r1, [r0] ldr r0, =0x1e782030 // Enable Timer3 mov r2, #7 mov r1, r2, lsl #8 str r1, [r0] ldr r0, =0x1e782034 // Check ISR for Timer3 timeout .endm .macro check_delay_timer ldr r1, [r0] bic r1, r1, #0xFFFFFFFB mov r2, r1, lsr #2 cmp r2, #0x01 .endm .macro clear_delay_timer ldr r0, =0x1e78203C // Disable Timer3 mov r2, #0xF mov r1, r2, lsl #8 str r1, [r0] ldr r0, =0x1e782034 // Clear Timer3 ISR ldr r1, =0x00000004 str r1, [r0] .endm .macro print_hex_char and r1, r1, #0xF cmp r1, #9 addgt r1, r1, #0x37 addle r1, r1, #0x30 str r1, [r0] .endm .macro print_hex_byte ldr r0, =ASTMMC_UART_BASE mov r1, r2, lsr #4 print_hex_char mov r1, r2 print_hex_char .endm .macro print_hex_word ldr r0, =ASTMMC_UART_BASE mov r1, r2, lsr #12 print_hex_char mov r1, r2, lsr #8 print_hex_char mov r1, r2, lsr #4 print_hex_char mov r1, r2 print_hex_char .endm .macro print_hex_dword ldr r0, =ASTMMC_UART_BASE mov r1, r2, lsr #28 print_hex_char mov r1, r2, lsr #24 print_hex_char mov r1, r2, lsr #20 print_hex_char mov r1, r2, lsr #16 print_hex_char mov r1, r2, lsr #12 print_hex_char mov r1, r2, lsr #8 print_hex_char mov r1, r2, lsr #4 print_hex_char mov r1, r2 print_hex_char .endm /****************************************************************************** Calibration Macro End ******************************************************************************/ .globl lowlevel_init lowlevel_init: #ifndef CONFIG_CPU_ARM1176 /* Put secondary core to sleep */ mrc p15, 0, r0, c0, c0, 5 @; Read CPU ID register ands r0, r0, #0x03 @; Mask off, leaving the CPU ID field #ifdef CONFIG_ASPEED_NONSECUR_MODE blne secondary_cpu_init #else blne relocate @blne wait_for_kickup b init_uart #endif #if 1 relocate: adrl r0, wait_for_kickup ldr r1, =0x1000f000 // ; r1 = pointer to destination block mov r2, #0x20 // ; r2 = number of words to copy wordcopy: ldr r3, [r0], #4 // ; load a word from the source and str r3, [r1], #4 // ; store it to the destination subs r2, r2, #1 // ; decrement the counter bne wordcopy //1 ; ... copy more ldr r0, =0x1E6E2180 LDR r1, =0x1e784000 ldr r4, =0xABBAADDA ldr r3, =0x1E6E2184 ldr r5, =0x10000000 ldr r6, =0x1000f000 str r6, [r5] mov lr, r6 mov pc, lr #endif #endif init_uart: /* save lr */ mov r4, lr /*Initialize the Debug UART here*/ ldr r0, =(ASTMMC_UART_BASE | 0x0c) mov r1, #0x83 str r1, [r0] ldr r0, =(ASTMMC_UART_BASE | 0x00) mov r1, #0x01 str r1, [r0] ldr r0, =(ASTMMC_UART_BASE | 0x04) mov r1, #0x00 str r1, [r0] ldr r0, =(ASTMMC_UART_BASE | 0x0c) mov r1, #0x03 str r1, [r0] ldr r0, =(ASTMMC_UART_BASE | 0x08) mov r1, #0x07 str r1, [r0] init_dram: /* Test - DRAM initial time */ ldr r0, =0x1e78203c ldr r1, =0x0000F000 str r1, [r0] ldr r0, =0x1e782044 ldr r1, =0xFFFFFFFF str r1, [r0] ldr r0, =0x1e782030 ldr r1, =0x00003000 str r1, [r0] /* Test - DRAM initial time */ /*Set Scratch register Bit 7 before initialize*/ ldr r0, =0x1e6e2000 ldr r1, =0x1688a8a8 str r1, [r0] ldr r0, =0x1e6e2010 str r1, [r0] /* ldr r0, =0x1e6e2100 ldr r1, [r0] orr r1, r1, #0x80 str r1, [r0] */ /****************************************************************************** Disable WDT for SPI Address mode detection function ******************************************************************************/ ldr r0, =0x1e620060 mov r1, #0 str r1, [r0] ldr r0, =0x1e620064 mov r1, #0 str r1, [r0] ldr r0, =0x1e78500c mov r1, #0 str r1, [r0] ldr r0, =0x1e78504c str r1, [r0] ldr r0, =0x1e78508c str r1, [r0] ldr r0, =0x1e7850cc str r1, [r0] #ifdef CONFIG_CPU_ARM1176 /* Enable AXI_P */ /* ldr r0, =0x00000016 mrc p15, 0, r1, c15, c2, 4 mcr p15, 0, r0, c15, c2, 4 */ init_arm11: /* Start of ES40004A PLL init */ /* Step 1. Program PLL_config and keep power down */ ldr r0, =0x33000000 ldr r1, =0x01000000 str r1, [r0] ldr r1, =0x0102001A @ 324 MHz str r1, [r0] /* Step 2. Wait 1us for PLL initialization */ ldr r2, =0x00000100 delay_ES40004A_pll_init: subs r2, r2, #1 bne delay_ES40004A_pll_init /* Step 3. Program PLL_config to exit Power down */ ldr r1, =0x0002001A str r1, [r0] /* Step 4. Check pll_ld = 1?. Read PLL_config, check bit 27. */ ldr r2, =0x08000000 @ bit[27] PLL lock detection check_pll_ld: ldr r1, [r0] tst r1, r2 beq check_pll_ld /* Step 5. Program aclk_div */ ldr r0, =0x33000004 ldr r1, =0x00000007 @ CPU/AXI = 8/1 str r1, [r0] /* Step 6. Program set_pll */ ldr r1, =0x00010007 str r1, [r0] /* End of ES40004A PLL init */ #endif /* Check Scratch Register Bit 6 */ ldr r0, =0x1e6e2100 ldr r1, [r0] bic r1, r1, #0xFFFFFFBF mov r2, r1, lsr #6 cmp r2, #0x01 beq platform_exit ddr_init_start: /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] mov r1, #'D' // 'D' str r1, [r0] mov r1, #'R' // 'R' str r1, [r0] mov r1, #'A' // 'A' str r1, [r0] mov r1, #'M' // 'M' str r1, [r0] mov r1, #' ' // ' ' str r1, [r0] mov r1, #'I' // 'I' str r1, [r0] mov r1, #'n' // 'n' str r1, [r0] mov r1, #'i' // 'i' str r1, [r0] mov r1, #'t' // 't' str r1, [r0] mov r1, #'-' // '-' str r1, [r0] mov r1, #'V' // 'V' str r1, [r0] mov r2, #ASTMMC_INIT_VER print_hex_byte ldr r0, =(ASTMMC_UART_BASE | 0x14) wait_print: ldr r1, [r0] tst r1, #0x40 beq wait_print ldr r0, =ASTMMC_UART_BASE mov r1, #'-' // '-' str r1, [r0] mov r1, #'D' // 'D' str r1, [r0] mov r1, #'D' // 'D' str r1, [r0] mov r1, #'R' // 'R' str r1, [r0] /* Debug - UART console message */ clear_delay_timer /* Delay about 5us */ ldr r2, =0x00000005 // Set Timer3 Reload = 5 us init_delay_timer delay_0: check_delay_timer bne delay_0 clear_delay_timer /* end delay 5us */ /****************************************************************************** Init DRAM common registers ******************************************************************************/ ldr r0, =0x1e6e0000 ldr r1, =0xFC600309 str r1, [r0] ldr r0, =0x1e6e0034 // disable SDRAM reset ldr r1, =0x000000C0 str r1, [r0] ldr r0, =0x1e6e0008 ldr r1, =0x0044000B /* VGA */ str r1, [r0] ldr r0, =0x1e6e0038 ldr r1, =0x00100000 str r1, [r0] ldr r0, =0x1e6e003c ldr r1, =0xFFFFFFFF str r1, [r0] ldr r0, =0x1e6e0040 ldr r1, =0x88888888 str r1, [r0] ldr r0, =0x1e6e0044 ldr r1, =0x88888888 str r1, [r0] ldr r0, =0x1e6e0048 ldr r1, =0x88888888 str r1, [r0] ldr r0, =0x1e6e004c ldr r1, =0x88888888 str r1, [r0] ldr r0, =0x1e6e0050 ldr r1, =0x80000000 str r1, [r0] ldr r0, =0x1e6e0054 ldr r1, =ASTMMC_DRAM_ECC_SIZE str r1, [r0] ldr r0, =0x1e6e0070 ldr r1, =0x00000000 str r1, [r0] add r0, #0x4 str r1, [r0] add r0, #0x4 str r1, [r0] add r0, #0x4 str r1, [r0] ldr r0, =0x1e6e0080 ldr r1, =0xFFFFFFFF str r1, [r0] ldr r0, =0x1e6e0084 ldr r1, =0x00000000 str r1, [r0] ldr r0, =0x1e6e0100 ldr r1, =0x000000FF str r1, [r0] /* Delay about 500us */ ldr r2, =0x000001F4 // Set Timer3 Reload = 500 us init_delay_timer ddr3_delay_poweron: check_delay_timer bne ddr3_delay_poweron clear_delay_timer /* end delay 500us */ /* Check DRAM Type by H/W Trapping */ #ifdef ASTMMC_DDR_DDR3 b ddr3_init #else ldr r0, =0x1e6e2500 ldr r1, [r0] tst r1, #0x20 // bit[5]=1 => DDR3 beq ddr4_init b ddr3_init #endif .LTORG /****************************************************************************** DDR3 Init ******************************************************************************/ ddr3_init: /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'3' // '3' str r1, [r0] mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] /* Debug - UART console message */ adrl r5, TIME_TABLE_DDR3 // Init DRAM parameter table ldr r0, =0x1e6e0004 ldr r1, =0x00000006 // 8Gb str r1, [r0] ldr r0, =0x1e6e0010 mov r2, #0x0 // init loop counter mov r3, r5 ddr3_init_param: ldr r1, [r3] str r1, [r0] add r0, #0x4 add r3, #0x4 add r2, #0x1 cmp r2, #0x8 blt ddr3_init_param ldr r0, =0x1e6e0034 // PWRCTL, first time enable CKE, wait at least 200 us ldr r1, =0x000000C1 str r1, [r0] /* Delay about 500us */ ldr r2, =0x000001F4 // Set Timer3 Reload = 500 us init_delay_timer ddr3_delay_cke_on: check_delay_timer bne ddr3_delay_cke_on clear_delay_timer /* end delay 500us */ ldr r0, =0x1e6e000c ldr r1, =0x00000040 str r1, [r0] ldr r0, =0x1e6e0030 ldr r1, =0x00000005 // MR2 str r1, [r0] ldr r1, =0x00000007 // MR3 str r1, [r0] ldr r1, =0x00000003 // MR1 str r1, [r0] ldr r1, =0x00000011 // MR0 + DLL_RESET str r1, [r0] ldr r0, =0x1e6e000c // REFSET ldr r1, =0x00005D41 str r1, [r0] ldr r0, =0x1e6e0034 ldr r2, =0x70000000 ddr3_check_dllrdy: ldr r1, [r0] tst r1, r2 bne ddr3_check_dllrdy ldr r0, =0x1e6e000c ldr r1, =0x40005DA1 str r1, [r0] ldr r0, =0x1e6e0034 ldr r1, =0x000001A3 str r1, [r0] b Calibration_End .LTORG /****************************************************************************** End DDR3 Init ******************************************************************************/ /****************************************************************************** DDR4 Init ******************************************************************************/ ddr4_init: /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'4' // '4' str r1, [r0] mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] /* Debug - UART console message */ adrl r5, TIME_TABLE_DDR4 // Init DRAM parameter table ldr r0, =0x1e6e0004 #ifdef ASTMMC_DDR4_8GX8 ldr r1, =0x00000037 // Init to 16GB #else ldr r1, =0x00000017 // Init to 16GB #endif str r1, [r0] ldr r0, =0x1e6e0010 mov r2, #0x0 // init loop counter mov r3, r5 ddr4_init_param: ldr r1, [r3] str r1, [r0] add r0, #0x4 add r3, #0x4 add r2, #0x1 cmp r2, #0x8 blt ddr4_init_param ldr r0, =0x1e6e0034 // PWRCTL, 1st enable CKE, wait at least 200 us ldr r1, =0x000000C1 str r1, [r0] /* Delay about 500us */ ldr r2, =0x000001F4 // Set Timer3 Reload = 500 us init_delay_timer ddr4_delay_cke_on: check_delay_timer bne ddr4_delay_cke_on clear_delay_timer /* end delay 500us */ ldr r0, =0x1e6e000c ldr r1, =0x00000040 str r1, [r0] ldr r0, =0x1e6e0030 ldr r1, =0x00000007 // MR3 str r1, [r0] ldr r1, =0x0000000D // MR6 str r1, [r0] ldr r1, =0x0000000B // MR5 str r1, [r0] ldr r1, =0x00000009 // MR4 str r1, [r0] ldr r1, =0x00000005 // MR2 str r1, [r0] ldr r1, =0x00000003 // MR1 str r1, [r0] ldr r1, =0x00000011 // MR0 + DLL_RESET str r1, [r0] ldr r0, =0x1e6e000c // REFSET ldr r1, =0x00005D41 str r1, [r0] ldr r0, =0x1e6e0034 ldr r2, =0x70000000 ddr4_check_dllrdy: ldr r1, [r0] tst r1, r2 bne ddr4_check_dllrdy ldr r0, =0x1e6e000c ldr r1, =0x40005DA1 str r1, [r0] ldr r0, =0x1e6e0034 ldr r1, =0x000001A3 str r1, [r0] /* Set DDR Vref */ ldr r0, =0x1e6e002c ldr r2, [r0] orr r1, r2, #0x80 str r1, [r0] ldr r0, =0x1e6e0030 mov r1, #0x1d str r1, [r0] ldr r0, =0x1e6e002c str r2, [r0] ldr r0, =0x1e6e0030 mov r1, #0x1d str r1, [r0] b Calibration_End .LTORG /****************************************************************************** Common Process *****************************************************************************/ /****************************************************************************** Other features configuration *****************************************************************************/ Calibration_End: mov r10,#0x0 // jump indication #ifdef ASTMMC_READ_TRAINING /*************************************** Finetune PLL to search the read window Use register r0, r1, r2, r3, r6, r7, r8 r9, r10,r11 ****************************************/ ldr r0, =0x80000000 ldr r1, =0x12345678 str r1, [r0] ldr r0, =0x80000004 ldr r1, =0xaabbccdd str r1, [r0] mov r9, #0x3 // win mov r10,#0x0 // gwin mov r11,#0x0 // gwin PLL margin ddr_gate_win_main: tst r9, #0x80 bne ddr_gate_win_end ldr r0, =0x1e6e0100 str r9, [r0] /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] mov r2, r9 print_hex_byte mov r1, #'-' // '-' str r1, [r0] /* Debug - UART console message */ b search_read_bypass_head ddr_gate_win_next: mov r9, r9, lsl #1 cmp r10,#0x0 beq ddr_gate_win_main cmp r7, #0x0 bne ddr_gate_win_main ddr_gate_win_end: mov r9, #0x7 // big win cmp r10,#0x0 beq ddr_gate_win_main ldr r0, =0x1e6e0100 str r10,[r0] mov r2, r10 /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] mov r1, #'G' // 'G' str r1, [r0] mov r1, #'W' // 'W' str r1, [r0] mov r1, #'i' // 'i' str r1, [r0] mov r1, #'n' // 'n' str r1, [r0] mov r1, #'=' // '=' str r1, [r0] print_hex_byte mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] ldr r0, =(ASTMMC_UART_BASE | 0x14) wait_print_6: ldr r1, [r0] tst r1, #0x40 beq wait_print_6 /* Debug - UART console message */ mov r9, #0x0 // jump indication search_read_bypass_head: ldr r0, =0x80000000 ldr r1, [r0] add r0, r0, #0x4 ldr r2, [r0] add r2, r1, r2 ldr r1, =0xBCF02355 cmp r1, r2 bne search_read_bypass_end ldr r0, =0x1e6e2400 ldr r1, =0x303 str r1, [r0] ldr r0, =0x1e6e2004 ldr r2, =0x00000100 check_mpll_done_0: ldr r1, [r0] tst r1, r2 beq check_mpll_done_0 ldr r0, =0x1e6e2400 ldr r1, =0x103 str r1, [r0] b search_read_bypass_head search_read_bypass_end: ldr r6, =0xFFF // PLL_min ldr r7, =0x0 // PLL_max ldr r3, =0x0 // pll counter search_read_main: ldr r0, =0x1e6e2400 ldr r1, =0x301 str r1, [r0] ldr r0, =0x1e6e2004 ldr r2, =0x00000100 check_mpll_done_1: ldr r1, [r0] tst r1, r2 beq check_mpll_done_1 ldr r0, =0x1e6e2400 ldr r1, =0x101 str r1, [r0] add r3, r3, #0x1 ldr r0, =0x80000000 ldr r1, [r0] add r0, r0, #0x4 ldr r2, [r0] add r2, r1, r2 ldr r1, =0xBCF02355 cmp r1, r2 bne search_read_main_fail cmp r6, r3 movgt r6, r3 cmp r7, r3 movlt r7, r3 /* Debug - UART console message */ ldr r0, =(ASTMMC_UART_BASE | 0x14) wait_print_3: ldr r1, [r0] tst r1, #0x40 beq wait_print_3 ldr r0, =ASTMMC_UART_BASE mov r1, #'*' // '*' str r1, [r0] /* Debug - UART console message */ b search_read_main search_read_main_fail: cmp r9, #0x0 bne search_read_main_fail_for_gatewin cmp r7, #0x0 beq search_read_main sub r2, r7, r6 /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'E' // 'E' str r1, [r0] print_hex_byte mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] /* Debug - UART console message */ cmp r2, #30 bgt search_read_main_pass ldr r6, =0xFFF ldr r7, =0x0 b search_read_main search_read_main_fail_for_gatewin: add r0, r7, #0xFF cmp r3, r0 bge ddr_gate_win_next cmp r7, #0x0 beq search_read_main sub r2, r7, r6 cmp r2, r11 movgt r11,r2 movgt r10,r9 orreq r10,r9, r10 /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'M' // 'M' str r1, [r0] print_hex_byte /* Debug - UART console message */ b ddr_gate_win_next search_read_main_pass: sub r8, r7, r6 mov r8, r8, lsr #1 ldr r6, =0xFFF // PLL_min ldr r7, =0x0 // PLL_max ldr r3, =0x0 // pll counter search_read_main2: add r1, r6, r8 cmp r3, r1 bge search_read_end ldr r0, =0x1e6e2400 ldr r1, =0x301 str r1, [r0] ldr r0, =0x1e6e2004 ldr r2, =0x00000100 check_mpll_done_2: ldr r1, [r0] tst r1, r2 beq check_mpll_done_2 ldr r0, =0x1e6e2400 ldr r1, =0x101 str r1, [r0] add r3, r3, #0x1 ldr r0, =0x80000000 ldr r1, [r0] add r0, r0, #0x4 ldr r2, [r0] add r2, r1, r2 ldr r1, =0xBCF02355 cmp r1, r2 bne search_read_main2_fail cmp r6, r3 movgt r6, r3 cmp r7, r3 movlt r7, r3 /* Debug - UART console message */ ldr r0, =(ASTMMC_UART_BASE | 0x14) wait_print_4: ldr r1, [r0] tst r1, #0x40 beq wait_print_4 ldr r0, =ASTMMC_UART_BASE mov r1, #'#' // '#' str r1, [r0] /* Debug - UART console message */ b search_read_main2 search_read_main2_fail: cmp r7, #0x0 beq search_read_main2 /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'E' // 'E' str r1, [r0] mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] /* Debug - UART console message */ ldr r6, =0xFFF ldr r7, =0x0 b search_read_main2 search_read_end: /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] /* Debug - UART console message */ #endif /******************************* Check DRAM Size 2Gb : 0x80000000 ~ 0x8FFFFFFF 4Gb : 0x80000000 ~ 0x9FFFFFFF 8Gb : 0x80000000 ~ 0xBFFFFFFF 16Gb: 0x80000000 ~ 0xFFFFFFFF *******************************/ ldr r0, =0x1e6e0004 ldr r6, [r0] bic r6, r6, #0x00000003 // record MCR04 ldr r7, [r5, #ASTMMC_REG_RFC] check_dram_size: ldr r0, =0xC0100000 ldr r1, =0xC1C2C3C4 str r1, [r0] ldr r0, =0xA0100000 ldr r1, =0xA1A2A3A4 str r1, [r0] ldr r0, =0x90100000 ldr r1, =0x91929394 str r1, [r0] ldr r0, =0x80100000 ldr r1, =0x81828384 str r1, [r0] ldr r0, =0xC0100000 ldr r1, =0xC1C2C3C4 ldr r2, [r0] mov r3, #0x16 // '16' cmp r2, r1 // == 16Gbit orreq r6, r6, #0x03 beq check_dram_size_end mov r7, r7, lsr #8 ldr r0, =0xA0100000 ldr r1, =0xA1A2A3A4 ldr r2, [r0] mov r3, #0x08 // '8' cmp r2, r1 // == 8Gbit orreq r6, r6, #0x02 beq check_dram_size_end mov r7, r7, lsr #8 ldr r0, =0x90100000 ldr r1, =0x91929394 ldr r2, [r0] mov r3, #0x04 // '4' cmp r2, r1 // == 4Gbit orreq r6, r6, #0x01 beq check_dram_size_end mov r7, r7, lsr #8 // == 2Gbit mov r3, #0x02 // '2' check_dram_size_end: ldr r0, =0x1e6e0004 str r6, [r0] ldr r0, =0x1e6e0014 ldr r1, [r0] bic r1, r1, #0x000000FF and r7, r7, #0xFF orr r1, r1, r7 str r1, [r0] /* Version Number */ ldr r0, =0x1e6e0004 ldr r1, [r0] mov r2, #ASTMMC_INIT_VER orr r1, r1, r2, lsl #20 str r1, [r0] ldr r0, =0x1e6e0088 ldr r1, =ASTMMC_INIT_DATE str r1, [r0] /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'S' // 'S' str r1, [r0] mov r1, #'i' // 'i' str r1, [r0] mov r1, #'z' // 'z' str r1, [r0] mov r1, #'e' // 'e' str r1, [r0] mov r1, #'-' // '-' str r1, [r0] mov r2, r3 print_hex_byte mov r1, #'G' // 'G' str r1, [r0] mov r1, #'b' // 'b' str r1, [r0] mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] ldr r0, =(ASTMMC_UART_BASE | 0x14) wait_print_2: ldr r1, [r0] tst r1, #0x40 beq wait_print_2 /* Debug - UART console message */ mov r9, #0x1 // jump indication /*************************************** Search read gating window Use r7, r8, r9 ****************************************/ mov r7, #0x3 // win mov r8, #0x0 // gwin mov r9, #0x0 // jump indication ddr_gate_train_main: tst r7, #0x80 bne ddr_gate_train_end ldr r0, =0x1e6e0100 str r7, [r0] /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r2, r7 print_hex_byte mov r1, #'-' // '-' str r1, [r0] /* Debug - UART console message */ b ddr_test_start ddr_gate_train_pass: /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'P' // 'P' str r1, [r0] mov r1, #'a' // 'a' str r1, [r0] mov r1, #'s' // 's' str r1, [r0] mov r1, #'s' // 's' str r1, [r0] mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] ldr r0, =(ASTMMC_UART_BASE | 0x14) wait_print_5: ldr r1, [r0] tst r1, #0x40 beq wait_print_5 /* Debug - UART console message */ orr r8, r7, r8 mov r7, r7, lsl #1 b ddr_gate_train_main ddr_gate_train_fail: mov r7, r7, lsl #1 cmp r8, #0x0 beq ddr_gate_train_main ddr_gate_train_end: mov r7, #0x7 // big win cmp r8, #0x0 beq ddr_gate_train_main ldr r0, =0x1e6e0100 str r8, [r0] /******************************************** DDRTest Use r0, r1, r2, r3, r6, r11 ********************************************/ mov r9, #0x1 // jump indication ddr_test_start: ldr r0, =0x1e6e0074 ldr r1, =0x0000FFFF // test size = 64KB str r1, [r0] ldr r0, =0x1e6e007c ldr r1, =0xFF00FF00 str r1, [r0] ddr_test_single: mov r6, #0x00 // initialize loop index, r1 is loop index ddr_test_single_loop: /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, r6 print_hex_char /* Debug - UART console message */ ldr r0, =0x1e6e0070 ldr r2, =0x00000000 str r2, [r0] mov r2, r6, lsl #3 orr r2, r2, #0x85 // test command = 0x85 | (datagen << 3) str r2, [r0] ldr r3, =0x3000 ldr r11, =0x500000 ddr_wait_engine_idle_0: subs r11, r11, #1 beq ddr_test_fail ldr r2, [r0] tst r2, r3 // D[12] = idle bit beq ddr_wait_engine_idle_0 ldr r0, =0x1e6e0070 // read fail bit status ldr r3, =0x2000 ldr r2, [r0] tst r2, r3 // D[13] = fail bit bne ddr_test_fail add r6, r6, #1 // increase the test mode index cmp r6, #0x08 // test 8 modes bne ddr_test_single_loop ddr_test_burst: mov r6, #0x00 // initialize loop index, r1 is loop index ddr_test_burst_loop: /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, r6 print_hex_char /* Debug - UART console message */ ldr r0, =0x1e6e0070 ldr r2, =0x00000000 str r2, [r0] mov r2, r6, lsl #3 orr r2, r2, #0xC1 // test command = 0xC1 | (datagen << 3) str r2, [r0] ldr r3, =0x3000 ldr r11, =0x500000 ddr_wait_engine_idle_1: subs r11, r11, #1 beq ddr_test_fail ldr r2, [r0] tst r2, r3 // D[12] = idle bit beq ddr_wait_engine_idle_1 ldr r0, =0x1e6e0070 // read fail bit status ldr r3, =0x2000 ldr r2, [r0] tst r2, r3 // D[13] = fail bit bne ddr_test_fail add r6, r6, #1 // increase the test mode index cmp r6, #0x08 // test 8 modes bne ddr_test_burst_loop ldr r0, =0x1e6e0070 ldr r1, =0x00000000 str r1, [r0] cmp r9, #0x0 beq ddr_gate_train_pass b set_scratch // CBRTest() return(1) ddr_test_fail: /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'F' // 'F' str r1, [r0] mov r1, #'a' // 'a' str r1, [r0] mov r1, #'i' // 'i' str r1, [r0] mov r1, #'l' // 'l' str r1, [r0] mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] ldr r0, =(ASTMMC_UART_BASE | 0x14) wait_print_1: ldr r1, [r0] tst r1, #0x40 beq wait_print_1 /* Debug - UART console message */ cmp r9, #0x0 beq ddr_gate_train_fail b ddr_init_start set_scratch: /*Set Scratch register Bit 6 after ddr initial finished */ /* ldr r0, =0x1e6e2100 ldr r1, [r0] orr r1, r1, #0x41 str r1, [r0] */ /* Debug - UART console message */ ldr r0, =ASTMMC_UART_BASE mov r1, #'D' // 'D' str r1, [r0] mov r1, #'o' // 'o' str r1, [r0] mov r1, #'n' // 'n' str r1, [r0] mov r1, #'e' // 'e' str r1, [r0] mov r1, #'\r' // '\r' str r1, [r0] mov r1, #'\n' // '\n' str r1, [r0] /* Debug - UART console message */ #ifdef CONFIG_ASPEED_NONSECUR_MODE mov r6,pc bl start_sec #endif platform_exit: #ifdef ASTMMC_DRAM_ECC ldr r0, =0x1e6e0004 ldr r2, =0x00000280 ldr r1, [r0] orr r1, r1, r2 str r1, [r0] ldr r0, =0x1e6e007C ldr r1, =0x00000000 str r1, [r0] ldr r0, =0x1e6e0074 str r1, [r0] ldr r0, =0x1e6e0070 ldr r1, =0x00000221 str r1, [r0] ldr r2, =0x00001000 ECC_Init_Flag: ldr r1, [r0] tst r1, r2 @ D[12] = 1, Done beq ECC_Init_Flag ldr r1, =0x00000000 str r1, [r0] ldr r0, =0x1e6e0050 ldr r1, =0x80000000 str r1, [r0] ldr r0, =0x1e6e0050 ldr r1, =0x40000000 str r1, [r0] #endif /* restore lr */ mov lr, r4 /* back to arch calling code */ mov pc, lr secondary_cpu_init: #ifdef CONFIG_ASPEED_NONSECUR_MODE mov r6,pc bl start_sec #endif wait_for_kickup: wfe ldr r2,[r3] cmp r2,r4 bne wait_for_kickup MOV r2,#'[' STR r2,[r1] MOV r2,#'1' STR r2,[r1] MOV r2,#'C' STR r2,[r1] MOV r2,#'P' STR r2,[r1] MOV r2,#'U' STR r2,[r1] MOV r2,#']' STR r2,[r1] MOV r2,#'\n' STR r2,[r1] MOV r2,#'\r' STR r2,[r1] ldr pc, [r0] ldr pc, [r0] b wait_for_kickup