summaryrefslogtreecommitdiff
path: root/board/aspeed/ast2400/platform.S
diff options
context:
space:
mode:
Diffstat (limited to 'board/aspeed/ast2400/platform.S')
-rw-r--r--board/aspeed/ast2400/platform.S3089
1 files changed, 3089 insertions, 0 deletions
diff --git a/board/aspeed/ast2400/platform.S b/board/aspeed/ast2400/platform.S
new file mode 100644
index 0000000000..27e8f26311
--- /dev/null
+++ b/board/aspeed/ast2400/platform.S
@@ -0,0 +1,3089 @@
+/*
+ * 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.
+ * AST2300/AST2400 DDR2/DDR3 SDRAM controller initialization and calibration sequence
+ *
+ * Gary Hsu, <gary_hsu@aspeedtech.com>
+ *
+ * Release date: 2014.12.29 formal release for SDK0.60
+ *
+ * Modified list from v0.23
+ * EC1. Modify DQIDLY and DQSI-MCLK2X calibration algorithm
+ * EC2. Remove pass 2 DQIDLY finetune process
+ * EC3. Modify ECC code
+ * EC4. Add AST2400 supporting
+ * EC5. Add SPI timing calibration for AST2400
+ * EC6. Remove AST2300-A0 PCI-e workaround
+ * EC7. Add CK duty calibration for AST2400
+ * EC8. Remove #define CONFIG_DRAM_UART_OUT, default has message output to UART5
+ * EC9. Add DRAM size auto-detection
+ * EC10. Add GPIO register clear when watchdog reboot (only for AST2400)
+ * EC11. Move the "Solve ASPM" code position of AST2300 to avoid watchdog reset
+ *
+ * Modified list from v0.53
+ * EC1. Add solution of LPC lock issue due to watchdog reset. (AP note A2300-11)
+ *
+ * Modified list from v0.56
+ * EC1. Fix read DQS input mask window too late issue if DRAM's t_DQSCK is earlier too much
+ * (ex. Nanya NT5CB64M16FP)
+ * 1. Change init value of MCR18[4] from '1' to '0'
+ * 2. Add CBR4 code to finetune MCR18[4]
+ *
+ * Modified list from v0.59
+ * EC1. Add DQS input gating window delay tuning (1/2 T) when CBR retry
+ * EC2. Modify DLL1 MAdj = 0x4C
+ *
+ * Optional define variable
+ * 1. DRAM Speed //
+ * CONFIG_DRAM_336 // 336MHz (DDR-667)
+ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
+ * 2. ECC Function enable
+ * CONFIG_DRAM_ECC // define to enable ECC function
+ * // when enabled, must define the ECC protected memory size at 0x1e6e0054
+ * 3. UART5 message output //
+ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
+ ******************************************************************************
+ */
+
+#include <config.h>
+#include <version.h>
+/******************************************************************************
+ Calibration Macro Start
+ Usable registers:
+ r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, r11
+ ******************************************************************************/
+/* PATTERN_TABLE,
+ init_delay_timer,
+ check_delay_timer,
+ clear_delay_timer,
+ record_dll2_pass_range,
+ record_dll2_pass_range_h,
+ are for DRAM calibration */
+
+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, =0x1e6c0038 @ Clear Timer3 ISR
+ ldr r1, =0x00040000
+ str r1, [r0]
+
+ ldr r0, =0x1e782030 @ Enable Timer3
+ ldr r1, [r0]
+ mov r2, #7
+ orr r1, r1, r2, lsl #8
+ str r1, [r0]
+
+ ldr r0, =0x1e6c0090 @ Check ISR for Timer3 timeout
+ .endm
+
+ .macro check_delay_timer
+ ldr r1, [r0]
+ bic r1, r1, #0xFFFBFFFF
+ mov r2, r1, lsr #18
+ cmp r2, #0x01
+ .endm
+
+ .macro clear_delay_timer
+ ldr r0, =0x1e782030 @ Disable Timer3
+ ldr r1, [r0]
+ bic r1, r1, #0x00000F00
+ str r1, [r0]
+
+ ldr r0, =0x1e6c0038 @ Clear Timer3 ISR
+ ldr r1, =0x00040000
+ str r1, [r0]
+ .endm
+
+ .macro record_dll2_pass_range
+ ldr r1, [r0]
+ bic r2, r1, #0xFFFFFF00
+ cmp r2, r3 @ record min
+ bicgt r1, r1, #0x000000FF
+ orrgt r1, r1, r3
+ bic r2, r1, #0xFFFF00FF
+ cmp r3, r2, lsr #8 @ record max
+ bicgt r1, r1, #0x0000FF00
+ orrgt r1, r1, r3, lsl #8
+ str r1, [r0]
+ .endm
+
+ .macro record_dll2_pass_range_h
+ ldr r1, [r0]
+ bic r2, r1, #0xFF00FFFF
+ mov r2, r2, lsr #16
+ cmp r2, r3 @ record min
+ bicgt r1, r1, #0x00FF0000
+ orrgt r1, r1, r3, lsl #16
+ bic r2, r1, #0x00FFFFFF
+ cmp r3, r2, lsr #24 @ record max
+ bicgt r1, r1, #0xFF000000
+ orrgt r1, r1, r3, lsl #24
+ str r1, [r0]
+ .endm
+
+ .macro init_spi_checksum
+ ldr r0, =0x1e620084
+ ldr r1, =0x20010000
+ str r1, [r0]
+ ldr r0, =0x1e62008C
+ ldr r1, =0x20000200
+ str r1, [r0]
+ ldr r0, =0x1e620080
+ ldr r1, =0x0000000D
+ orr r2, r2, r7
+ orr r1, r1, r2, lsl #8
+ and r2, r6, #0xF
+ orr r1, r1, r2, lsl #4
+ str r1, [r0]
+ ldr r0, =0x1e620008
+ ldr r2, =0x00000800
+ .endm
+
+/******************************************************************************
+ Calibration Macro End
+ ******************************************************************************/
+LPC_Patch: @ load to SRAM base 0x1e720400
+ str r1, [r0]
+ str r3, [r2]
+ bic r1, r1, #0xFF
+LPC_Patch_S1:
+ subs r5, r5, #0x01
+ moveq pc, r8
+ ldr r3, [r2]
+ tst r3, #0x01
+ movne pc, r8
+ mov pc, r7
+LPC_Patch_S2: @ load to SRAM base 0x1e720480
+ str r1, [r0]
+ mov pc, r9
+LPC_Patch_E:
+
+.globl lowlevel_init
+lowlevel_init:
+
+init_dram:
+ /* save lr */
+ mov r4, lr
+/* Test - DRAM initial time */
+ ldr r0, =0x1e782044
+ ldr r1, =0xFFFFFFFF
+ str r1, [r0]
+
+ ldr r0, =0x1e782030
+ ldr r1, [r0]
+ bic r1, r1, #0x0000F000
+ str r1, [r0]
+ mov r2, #3
+ orr r1, r1, r2, lsl #12
+ 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, =0x1e6e2040
+ ldr r1, [r0]
+ orr r1, r1, #0x80
+ str r1, [r0]
+
+ /* Fix LPC lock issue for AST2300 */
+ ldr r0, =0x1e6e207c @ Check AST2300
+ ldr r1, [r0]
+ mov r1, r1, lsr #24
+ cmp r1, #0x01
+ bne lpc_recover_end @ not match AST2300
+
+ mov r3, #0x0
+lpc_recover_check:
+ ldr r0, =0x1e78900c @ check HICR3[4]=0x1
+ ldr r1, [r0]
+ tst r1, #0x10
+ beq lpc_recover_end
+ ldr r0, =0x1e789004 @ check HICR1[7]=0x1
+ ldr r1, [r0]
+ tst r1, #0x80
+ beq lpc_recover_end
+ ldr r0, =0x1e7890a0 @ check LHCR0[27:24]=0x6
+ ldr r1, [r0]
+ mov r1, r1, lsr #24
+ and r1, r1, #0xF
+ cmp r1, #0x06
+ bne lpc_recover_end
+ add r3, r3, #0x01
+ cmp r3, #0x5 @ repeat 5 times
+ ble lpc_recover_check
+
+ mov r3, #0x0
+lpc_recover_init:
+ ldr r0, =0x1e7890a4 @ set LHCR1[1:0]=0x0
+ ldr r1, =0x00000000
+ str r1, [r0]
+ add r3, r3, #0x01
+ cmp r3, #0x20
+ bge lpc_recover_end
+ ldr r1, [r0]
+ tst r1, #0x01
+ bne lpc_recover_init
+
+ ldr r0, =0x1e7890b0 @ set LHCR4[7:0]=0xFF
+ ldr r1, =0x000000FF
+ str r1, [r0]
+ ldr r0, =0x1e7890b4 @ set LHCR5[31:0]=0xFFFFFFFF
+ ldr r1, =0xFFFFFFFF
+ str r1, [r0]
+ ldr r0, =0x1e7890b8 @ set LHCR6[31:0]=0xFFFFFFFF
+ str r1, [r0]
+
+ adr r6, LPC_Patch
+ adr r7, LPC_Patch_S2
+ ldr r0, =0x1e720400
+copy_lpc_patch_1:
+ ldr r1, [r6]
+ str r1, [r0]
+ add r6, r6, #0x4
+ add r0, r0, #0x4
+ cmp r6, r7
+ bne copy_lpc_patch_1
+
+ adr r6, LPC_Patch_S2
+ adr r7, LPC_Patch_E
+ ldr r0, =0x1e720480
+copy_lpc_patch_2:
+ ldr r1, [r6]
+ str r1, [r0]
+ add r6, r6, #0x4
+ add r0, r0, #0x4
+ cmp r6, r7
+ bne copy_lpc_patch_2
+
+ ldr r0, =0x1e7890a0 @ set LHCR0[31:0]=0xFFFFFF01
+ ldr r1, =0xFFFFFF01
+ add r2, r0, #0x4
+ mov r3, #0x01
+ mov r5, #0x10
+ adr r9, lpc_recover_end
+ adr r6, LPC_Patch
+ adr r7, LPC_Patch_S1
+ sub r6, r7, r6
+ ldr r7, =0x1e720400
+ add r7, r7, r6
+ ldr r8, =0x1e720480
+ ldr pc, =0x1e720400
+
+lpc_recover_end:
+ ldr r0, =0x1e7890a0 @ set LHCR0[31:0]=0xFFFFFF00
+ ldr r1, =0xFFFFFF00
+ str r1, [r0]
+ /* <END> Fix LPC lock issue for AST2300 */
+
+ /* Check Scratch Register Bit 6 */
+ ldr r0, =0x1e6e2040
+ ldr r1, [r0]
+ bic r1, r1, #0xFFFFFFBF
+ mov r2, r1, lsr #6
+ cmp r2, #0x01
+ beq platform_exit
+
+ ldr r2, =0x033103F1 @ load PLL parameter for 24Mhz CLKIN (396:324)
+/* ldr r2, =0x019001F0 @ load PLL parameter for 24Mhz CLKIN (408:336) */
+ ldr r0, =0x1e6e207c @ Check Revision ID
+ ldr r1, [r0]
+ mov r1, r1, lsr #24
+ cmp r1, #0x02
+ bne set_MPLL @ not match AST2400
+
+ ldr r0, =0x1e6e2070 @ Check CLKIN freq
+ ldr r1, [r0]
+ mov r1, r1, lsr #23
+ tst r1, #0x01
+ ldrne r2, =0x017001D0 @ load PLL parameter for 25Mhz CLKIN (400:325)
+
+set_MPLL:
+ ldr r0, =0x1e6e2020 @ M-PLL (DDR SDRAM) Frequency
+ ldr r1, =0xFFFF
+#if defined(CONFIG_DRAM_336)
+ mov r2, r2, lsr #16
+#endif
+ and r1, r2, r1
+ str r1, [r0]
+
+/* Debug - UART console message */
+ ldr r0, =0x1e78400c
+ mov r1, #0x83
+ str r1, [r0]
+
+ ldr r0, =0x1e6e202c
+ ldr r2, [r0]
+ mov r2, r2, lsr #12
+ tst r2, #0x01
+ ldr r0, =0x1e784000
+ moveq r1, #0x0D @ Baudrate 115200
+ movne r1, #0x01 @ Baudrate 115200, div13
+#if defined(CONFIG_DRAM_UART_38400)
+ moveq r1, #0x27 @ Baudrate 38400
+ movne r1, #0x03 @ Baudrate 38400 , div13
+#endif
+ str r1, [r0]
+
+ ldr r0, =0x1e784004
+ mov r1, #0x00
+ str r1, [r0]
+
+ ldr r0, =0x1e78400c
+ mov r1, #0x03
+ str r1, [r0]
+
+ ldr r0, =0x1e784008
+ mov r1, #0x07
+ str r1, [r0]
+
+ ldr r0, =0x1e784000
+ mov r1, #0x0D @ '\r'
+ str r1, [r0]
+ mov r1, #0x0A @ '\n'
+ str r1, [r0]
+ mov r1, #0x44 @ 'D'
+ str r1, [r0]
+ mov r1, #0x52 @ 'R'
+ str r1, [r0]
+ mov r1, #0x41 @ 'A'
+ str r1, [r0]
+ mov r1, #0x4D @ 'M'
+ str r1, [r0]
+ mov r1, #0x20 @ ' '
+ str r1, [r0]
+ mov r1, #0x49 @ 'I'
+ str r1, [r0]
+ mov r1, #0x6E @ 'n'
+ str r1, [r0]
+ mov r1, #0x69 @ 'i'
+ str r1, [r0]
+ mov r1, #0x74 @ 't'
+ str r1, [r0]
+ mov r1, #0x2D @ '-'
+ str r1, [r0]
+ mov r1, #0x44 @ 'D'
+ str r1, [r0]
+ mov r1, #0x44 @ 'D'
+ str r1, [r0]
+ mov r1, #0x52 @ 'R'
+ str r1, [r0]
+/* Debug - UART console message */
+
+ /* Delay about 100us */
+ ldr r0, =0x1e782030 @ Init Timer3 Control
+ ldr r1, [r0]
+ bic r1, r1, #0x00000F00
+ str r1, [r0]
+
+ ldr r2, =0x00000064 @ Set Timer3 Reload = 100 us
+ init_delay_timer
+delay_0:
+ check_delay_timer
+ bne delay_0
+ clear_delay_timer
+ /* end delay 100us */
+
+/******************************************************************************
+ Init DRAM common registers
+ ******************************************************************************/
+ ldr r0, =0x1e6e0000
+ ldr r1, =0xfc600309
+ str r1, [r0]
+
+ /* Reset MMC */
+ ldr r1, =0x00000000
+ ldr r0, =0x1e6e0034
+ str r1, [r0]
+ ldr r0, =0x1e6e0018
+ str r1, [r0]
+ ldr r0, =0x1e6e0024
+ str r1, [r0]
+ ldr r0, =0x1e6e0064 @ REG_MADJ, power down DLL
+ str r1, [r0]
+
+ ldr r1, =0x00034C4C @ REG_MADJ, reset DLL
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0068 @ REG_SADJ
+ ldr r1, =0x00001800
+ str r1, [r0]
+
+ /* Delay about 10us */
+ ldr r2, =0x0000000B @ Set Timer3 Reload = 10 us
+ init_delay_timer
+delay_1:
+ check_delay_timer
+ bne delay_1
+ clear_delay_timer
+ /* end delay 10us */
+
+ ldr r0, =0x1e6e0064 @ REG_MADJ | 0xC0000, enable DLL
+ ldr r1, [r0]
+ ldr r2, =0xC0000
+ orr r1, r1, r2
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0008
+ ldr r1, =0x0090040f /* VGA */
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0018
+ ldr r1, =0x4000A120
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0018
+ ldr r1, =0x00000120
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0038
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0040
+ ldr r1, =0xFF444444
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0044
+ ldr r1, =0x22222222
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0048
+ ldr r1, =0x22222222
+ str r1, [r0]
+
+ ldr r0, =0x1e6e004c
+ ldr r1, =0x22222222
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0050
+ ldr r1, =0x80000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0050
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0054
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0060 @ REG_DRV
+ ldr r1, =0x000000FA @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x000000FA
+#endif
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0070
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0074
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0078
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e007c
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0080
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0084
+ ldr r1, =0x00FFFFFF
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0088 @ REG_DQIDLY
+ ldr r1, =0x00000089 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00000074
+#endif
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0020 @ REG_DQSIC
+ ldr r1, =0x000000E2 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x000000BA
+#endif
+ str r1, [r0]
+
+ /* Delay about 10us */
+ ldr r2, =0x0000000B @ Set Timer3 Reload = 10 us
+ init_delay_timer
+delay_2:
+ check_delay_timer
+ bne delay_2
+ clear_delay_timer
+ /* end delay 10us */
+
+ /* Check DRAM Type by H/W Trapping */
+ ldr r0, =0x1e6e2070
+ ldr r1, [r0]
+ bic r1, r1, #0xFEFFFFFF @ bit[24]=1 => DDR2
+ mov r2, r1, lsr #24
+ cmp r2, #0x01
+ beq ddr2_init
+ b ddr3_init
+.LTORG
+
+/******************************************************************************
+ DDR3 Init
+
+ tRCD = 15 ns
+ tRAS = 37.5 ns
+ tRRD = max(4 CK,10 ns)
+ tRP = 15 ns
+ tRFC = 110ns/1Gbit, 160ns/2Gbit, 300ns/4Gbit
+ tRTP = max(4 CK,7.5 ns)
+ tWR = 15 ns
+ tXSNR = max(10 CK,200 ns)
+ tWTR = max(4 CK,7.5 ns)
+ tFAW = 50 ns
+ tMRD = max(15 CK,20 ns)
+ ******************************************************************************/
+ddr3_init:
+/* Debug - UART console message */
+ ldr r0, =0x1e784000
+ mov r1, #0x33 @ '3'
+ str r1, [r0]
+ mov r1, #0x0D @ '\r'
+ str r1, [r0]
+ mov r1, #0x0A @ '\n'
+ str r1, [r0]
+/* Debug - UART console message */
+
+ ldr r0, =0x1e6e0004
+ ldr r1, =0x00000531 @ Default set to 1Gbit
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0010 @ REG_AC1
+ ldr r1, =0x33302825 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x22202725
+#endif
+ str r1, [r0]
+
+ /* Check DRAM CL Timing by H/W Trapping */
+ ldr r0, =0x1e6e2070
+ ldr r1, [r0]
+ bic r1, r1, #0xF9FFFFFF
+ mov r2, r1, lsr #9 @ Set CL
+ ldr r1, =0x00020000
+ add r2, r2, r1
+ ldr r1, [r0]
+ bic r1, r1, #0xFBFFFFFF
+ mov r1, r1, lsr #6 @ Set CWL
+ orr r2, r2, r1
+ ldr r1, =0x00300000
+ add r2, r2, r1
+
+ ldr r0, =0x1e6e0014 @ REG_AC2
+ ldr r1, =0xCC00963F @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0xAA007636
+#endif
+ orr r1, r1, r2
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0004 @ check 2400 mode
+ ldr r2, [r0]
+ mov r2, r2, lsr #10
+
+ ldr r0, =0x1e6e006c @ REG_IOZ
+ ldr r1, =0x00002312 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00002312
+#endif
+ tst r2, #0x01
+ moveq r1, r1, lsr #8
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0120
+ mov r1, #0
+ str r1, [r0]
+ tst r2, #0x01 @ check AST2300
+ beq CBRDLL1_2300_Start
+ ldr r0, =0x1e6e207c @ check AST2400 revision A0
+ ldr r1, [r0]
+ mov r1, r1, lsr #16
+ and r1, r1, #0xFF
+ cmp r1, #0x0
+ beq CBRDLL1_2300_Start
+ b CBRDLL1_2400_Start
+MCLK2X_Phase_CBR_Done_DDR3:
+ ldr r0, =0x1e6e0018
+ ldr r1, [r0]
+ orr r1, r1, #0x40
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0034
+ ldr r1, =0x00000001
+ str r1, [r0]
+
+ ldr r0, =0x1e6e000c
+ ldr r1, =0x00000040
+ str r1, [r0]
+
+ /* Delay about 400us */
+ ldr r2, =0x00000190 @ Set Timer3 Reload = 400 us
+ init_delay_timer
+delay3_4:
+ check_delay_timer
+ bne delay3_4
+ clear_delay_timer
+ /* end delay 400us */
+
+ /* Check DRAM CL Timing by H/W Trapping */
+ ldr r0, =0x1e6e2070
+ ldr r1, [r0]
+ bic r1, r1, #0xF9FFFFFF
+ mov r2, r1, lsr #21 @ Set CL
+ ldr r1, =0x00000010
+ add r2, r2, r1
+ ldr r1, [r0]
+ bic r1, r1, #0xFBFFFFFF
+ mov r1, r1, lsr #7 @ Set CWL
+ orr r2, r2, r1
+
+ ldr r0, =0x1e6e002c @ REG_MRS
+ ldr r1, =0x04001700 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x04001500
+#endif
+ orr r1, r1, r2
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0030 @ REG_EMRS
+ ldr r1, =0x00000000 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00000000
+#endif
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set EMRS2
+ ldr r1, =0x00000005
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set EMRS3
+ ldr r1, =0x00000007
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set EMRS
+ ldr r1, =0x00000003
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set MRS
+ ldr r1, =0x00000001
+ str r1, [r0]
+
+ ldr r0, =0x1e6e002c @ REG_MRS
+ ldr r1, =0x04001600 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x04001400
+#endif
+ orr r1, r1, r2
+ str r1, [r0]
+
+ ldr r0, =0x1e6e000c @ Refresh 8 times
+ ldr r1, =0x00005C48
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set MRS
+ ldr r1, =0x00000001
+ str r1, [r0]
+
+ ldr r0, =0x1e6e000c @ Set refresh cycle
+ ldr r1, =0x00002001
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0014
+ ldr r1, [r0]
+ bic r1, r1, #0xFFF9FFFF
+ mov r2, r1, lsr #3 @ get CL
+
+ ldr r0, =0x1e6e0034 @ REG_PWC
+ ldr r1, =0x00000303 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00000303
+#endif
+ orr r1, r1, r2
+ str r1, [r0]
+
+ b Calibration_Start
+.LTORG
+/******************************************************************************
+ End DDR3 Init
+ ******************************************************************************/
+
+/******************************************************************************
+ DDR2 Init
+
+ tRCD = 15 ns
+ tRAS = 45 ns
+ tRRD = 10 ns
+ tRP = 15 ns
+ tRFC = 105ns/512Mbit, 127.5ns/1Gbit, 197.5ns/2Gbit, 327.5ns/4Gbit
+ tRTP = 7.5 ns
+ tWR = 15 ns
+ tXSNR = 200 ns
+ tWTR = 7.5 ns
+ tFAW = 50 ns
+ tMRD = 4 CK
+ ******************************************************************************/
+ddr2_init:
+/* Debug - UART console message */
+ ldr r0, =0x1e784000
+ mov r1, #0x32 @ '2'
+ str r1, [r0]
+ mov r1, #0x0D @ '\r'
+ str r1, [r0]
+ mov r1, #0x0A @ '\n'
+ str r1, [r0]
+/* Debug - UART console message */
+
+ ldr r0, =0x1e6e0004
+ ldr r1, =0x00000510 @ Default set to 512Mbit
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0010 @ REG_AC1
+ ldr r1, =0x33302714 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x22201613
+#endif
+ str r1, [r0]
+
+ /* Check DRAM CL Timing by H/W Trapping */
+ ldr r0, =0x1e6e2070
+ ldr r1, [r0]
+ bic r1, r1, #0xF9FFFFFF
+ mov r2, r1, lsr #5 @ Set CL
+ mov r1, r2, lsr #4 @ Set CWL
+ orr r2, r2, r1
+ ldr r1, =0x00110000
+ add r2, r2, r1
+
+ ldr r0, =0x1e6e0014 @ REG_AC2
+ ldr r1, =0xCC00B03F @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0xAA00903B
+#endif
+ orr r1, r1, r2
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0004 @ check 2400 mode
+ ldr r2, [r0]
+ mov r2, r2, lsr #10
+
+ ldr r0, =0x1e6e006c @ REG_IOZ
+ ldr r1, =0x00002312 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00002312
+#endif
+ tst r2, #0x01
+ moveq r1, r1, lsr #8
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0120
+ mov r1, #1
+ str r1, [r0]
+ tst r2, #0x01 @ check AST2300
+ beq CBRDLL1_2300_Start
+ ldr r0, =0x1e6e207c @ check AST2400 revision A0
+ ldr r1, [r0]
+ mov r1, r1, lsr #16
+ and r1, r1, #0xFF
+ cmp r1, #0x0
+ beq CBRDLL1_2300_Start
+ b CBRDLL1_2400_Start
+MCLK2X_Phase_CBR_Done_DDR2:
+
+ ldr r0, =0x1e6e0034
+ ldr r1, =0x00000001
+ str r1, [r0]
+
+ ldr r0, =0x1e6e000c
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ /* Delay about 400us */
+ ldr r2, =0x00000190 @ Set Timer3 Reload = 400 us
+ init_delay_timer
+delay2_4:
+ check_delay_timer
+ bne delay2_4
+ clear_delay_timer
+ /* end delay 400us */
+
+ /* Check DRAM CL Timing by H/W Trapping */
+ ldr r0, =0x1e6e2070
+ ldr r1, [r0]
+ bic r1, r1, #0xF9FFFFFF
+ mov r2, r1, lsr #21 @ Set CL
+ ldr r1, =0x00000040
+ orr r2, r2, r1
+
+ ldr r0, =0x1e6e002c @ REG_MRS
+ ldr r1, =0x00000D03 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00000B03
+#endif
+ orr r1, r1, r2
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0030 @ REG_EMRS
+ ldr r1, =0x00000040 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00000040
+#endif
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set EMRS2
+ ldr r1, =0x00000005
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set EMRS3
+ ldr r1, =0x00000007
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set EMRS
+ ldr r1, =0x00000003
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set MRS
+ ldr r1, =0x00000001
+ str r1, [r0]
+
+ ldr r0, =0x1e6e000c @ Refresh 8 times
+ ldr r1, =0x00005C08
+ str r1, [r0]
+
+ ldr r0, =0x1e6e002c @ REG_MRS
+ ldr r1, =0x00000C03 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00000A03
+#endif
+ orr r1, r1, r2
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set MRS
+ ldr r1, =0x00000001
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0030 @ REG_EMRS
+ ldr r1, =0x000003C0 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x000003C0
+#endif
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set EMRS
+ ldr r1, =0x00000003
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0030 @ REG_EMRS
+ ldr r1, =0x00000040 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00000040
+#endif
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0028 @ Set EMRS
+ ldr r1, =0x00000003
+ str r1, [r0]
+
+ ldr r0, =0x1e6e000c @ Set refresh cycle
+ ldr r1, =0x00002001
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0014
+ ldr r1, [r0]
+ bic r1, r1, #0xFFF9FFFF
+ mov r2, r1, lsr #3 @ get CL
+
+ ldr r0, =0x1e6e0034 @ REG_PWC
+ ldr r1, =0x00000503 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00000503
+#endif
+ orr r1, r1, r2
+ str r1, [r0]
+
+ b Calibration_Start
+.LTORG
+/******************************************************************************
+ End DDR2 Init
+ ******************************************************************************/
+/******************************************************************************
+ DDR CK duty finetune program
+ SRAM buffer definition
+ 0x1E720204 : gdll golden DLL1 record
+ 0x1E720208 : gduty golden duty setting record
+ 0x1E72020C : gdutysum golden duty data record
+ 0x1E720210 : duty record of delay 0 invert
+ 0x1E720214 : duty record of delay 1 invert
+ ....
+ 0x1E72024C : duty record of delay 15 invert
+ 0x1E720250 : duty record of delay 0
+ 0x1E720254 : duty record of delay 1
+ ....
+ 0x1E72028C : duty record of delay 15
+
+ Register usage
+ r0 - r3 = free
+ r4 = record the return pc value, do not use
+ r5 = free
+ r6 = free
+ r7 = duty count
+ r8 = gdll
+ r9 = gduty
+ r10 = gdutysum
+ ******************************************************************************/
+CBRDLL1_2400_Start:
+ ldr r0, =0x1e6e0120
+ ldr r1, [r0]
+ orr r1, r1, #0x02
+ str r1, [r0]
+
+ ldr r1, =0x00000000
+ ldr r0, =0x1e720204
+ ldr r2, =0x1e7202a0
+init_sram_start0:
+ str r1, [r0]
+ add r0, r0, #4
+ cmp r0, r2
+ blt init_sram_start0
+
+ ldr r0, =0x1e6e0034
+ mov r1, #0x20
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0060
+ ldr r1, [r0]
+ mov r2, #0x01
+ orr r1, r1, r2, lsl #13
+ str r1, [r0]
+
+ mov r7, #0x0 @ init duty count
+ mov r8, #0x0 @ init gdll
+ mov r9, #0x0 @ init gduty
+ mov r10, #0x0 @ init gdutysum
+cbrdll1_duty_start:
+ cmp r7, #32
+ bge cbrdll1_duty_end
+
+ ldr r0, =0x1e6e0018
+ ldr r1, =0x00008120
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0060
+ ldr r1, [r0]
+ bic r1, r1, #0x00001F00
+ orr r1, r1, r7, lsl #8
+ mov r2, #0x10
+ eor r1, r1, r2, lsl #8
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0000 @ dummy read
+ ldr r1, [r0]
+
+ b CBRDLL1_2300_Start
+CBRDLL1_2400_Call:
+
+ mov r5, #0x01 @ init dqidly count
+ mov r6, #0x00 @ init duty sum
+cbrdll1_duty_cal_start:
+ cmp r5, #0x05
+ bge cbrdll1_duty_cal_end
+
+ ldr r0, =0x1e6e0018
+ ldr r1, =0x00200120
+ orr r1, r1, r5, lsl #16
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0000
+ ldr r1, [r0]
+
+ ldr r0, =0x1e6e0018
+ ldr r1, [r0]
+ mov r2, #0x10
+ orr r1, r1, r2, lsl #24
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0080
+ ldr r1, =0x80000000 @ init duty cal waiting
+cbrdll1_duty_cal_wait:
+ ldr r2, [r0]
+ tst r2, r1
+ beq cbrdll1_duty_cal_wait
+
+ ldr r0, =0x1e6e008c
+ ldr r2, [r0]
+
+ ldr r0, =0x1e720210
+ add r0, r0, r7, lsl #2
+ str r2, [r0]
+
+ ldr r1, =0xFFFF
+ and r3, r1, r2
+ cmp r3, r1
+ moveq r2, r2, lsr #16
+ and r3, r1, r2
+ add r6, r6, r3
+ ldr r1, =0xF000
+ cmp r3, r1
+ blt cbrdll1_duty_cal_end
+ add r5, r5, #0x01
+ b cbrdll1_duty_cal_start
+
+cbrdll1_duty_cal_end:
+ mov r6, r6, lsr #2 @ get dutysum
+ cmp r6, r10 @ check dutysum > gdutysum
+ ble cbrdll1_duty_next
+ ldr r0, =0x1e6e0068
+ ldr r8, [r0]
+ eor r9, r7, #0x10
+ mov r10, r6
+
+cbrdll1_duty_next:
+ add r7, r7, #0x01
+ cmp r7, #16 @ check duty >= 15
+ blt cbrdll1_duty_start
+ ldr r0, =0xFA00 @ check gdutysum > 0xFA00
+ cmp r10, r0
+ blt cbrdll1_duty_start
+
+cbrdll1_duty_end:
+ ldr r0, =0x1e6e0060
+ ldr r1, [r0]
+ bic r1, r1, #0x00001F00
+ orr r1, r1, r9, lsl #8
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0068
+ bic r8, r8, #0xFF000000
+ bic r8, r8, #0x00FF0000
+ str r8, [r0]
+
+ ldr r0, =0x1e720204 @ record result
+ str r8, [r0]
+ add r0, r0, #0x04
+ str r9, [r0]
+ add r0, r0, #0x04
+ str r10, [r0]
+
+ ldr r0, =0x1e6e0018
+ ldr r1, =0x00008120
+ str r1, [r0]
+ ldr r0, =0x1e6e0000 @ dummy read
+ ldr r1, [r0]
+ ldr r0, =0x1e6e0018
+ ldr r1, =0x00000120
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0120
+ ldr r1, [r0]
+ cmp r1, #0x3
+ beq MCLK2X_Phase_CBR_Done_DDR2
+ b MCLK2X_Phase_CBR_Done_DDR3
+
+/******************************************************************************
+ MCLK2X lock to MCLK program
+ r0 - r3 = free
+ r5 = madjmax
+ r6 = dllend
+ 0x1E720200 = 0x96cnt:failcnt:dllmax:dllmin
+ ******************************************************************************/
+CBRDLL1_2300_Start:
+ ldr r0, =0x1e6e0064
+ ldr r5, [r0]
+ and r5, r5, #0xFF @ init madjmax
+ mov r6, r5 @ init dllend
+
+ ldr r1, =0x000000ff
+ ldr r0, =0x1e720200
+ str r1, [r0] @ init dllcnt2:dllmax:dllmin
+
+ mov r3, #0x0 @ init loop count
+cbrdll1_scan_start:
+ cmp r3, r6
+ bge cbrdll1_scan_end
+
+ ldr r0, =0x1e6e0018
+ ldr r1, =0x00008120
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0068
+ mov r1, r3
+ cmp r1, r5
+ subge r1, r1, r5
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0000 @ dummy read
+ ldr r1, [r0]
+
+ ldr r0, =0x1e6e0018
+ ldr r1, =0x00000120
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0000 @ dummy read
+ ldr r1, [r0]
+ ldr r0, =0x1e6e0000 @ dummy read
+ ldr r1, [r0]
+
+ ldr r0, =0x1e6e001c
+ ldr r1, [r0]
+ mov r1, r1, lsr #16
+ and r1, r1, #0xFF
+
+ and r2, r1, #0x96
+ cmp r2, #0x96
+ beq cbrdll1_scan_pass @ if (mclk2x_phase & 0x96) == 0x96
+ ldr r0, =0x1e720200
+ ldr r1, [r0]
+ mov r2, r1, lsr #8
+ ands r2, r2, #0xFF @ get dllmax
+ beq cbrdll1_scan_next @ if dllmax == 0
+ mov r2, r1, lsr #16
+ and r2, r2, #0xFF
+ add r2, r2, #0x01
+ cmp r2, #0x02
+ movge r6, r3
+ bic r1, r1, #0x00FF0000
+ orr r1, r1, r2, lsl #16
+ str r1, [r0]
+ b cbrdll1_scan_next
+
+cbrdll1_scan_pass:
+ cmp r3, #0x0 @ if dll = 0
+ moveq r3, #0x0F
+ addeq r6, r6, #0x10
+ beq cbrdll1_scan_next
+ ldr r0, =0x1e720200
+ ldr r2, [r0]
+ cmp r1, #0x96
+ bne cbrdll1_scan_pass2
+ mov r1, r2, lsr #24
+ add r1, r1, #0x01
+ bic r2, r2, #0xFF000000
+ orr r2, r2, r1, lsl #24
+ cmp r1, #0x03 @ check (phase == 0x96) count == 3
+ bicge r2, r2, #0x0000FF00
+ bicge r2, r2, #0x000000FF
+ orrge r2, r2, r3, lsl #8
+ orrge r2, r2, r3
+ str r2, [r0]
+ bge cbrdll1_scan_end
+
+cbrdll1_scan_pass2:
+ and r1, r2, #0xFF @ if(dllmin > dll)
+ cmp r1, r3
+ bicgt r2, r2, #0x000000FF
+ orrgt r2, r2, r3
+
+ mov r1, r2, lsr #8 @ if(dllmax < dll)
+ and r1, r1, #0xFF
+ cmp r1, r3
+ biclt r2, r2, #0x0000FF00
+ orrlt r2, r2, r3, lsl #8
+
+ bic r2, r2, #0x00FF0000
+ str r2, [r0]
+
+cbrdll1_scan_next:
+ add r3, r3, #0x01
+ b cbrdll1_scan_start
+
+cbrdll1_scan_end:
+ ldr r0, =0x1e720200
+ ldr r1, [r0]
+ mov r2, r1, lsr #8 @ get dllmax
+ ands r2, r2, #0xFF
+ bne cbrdll1_scan_done @ if(dllmax != 0)
+ ldr r0, =0x1e6e0064
+ ldr r3, [r0]
+ bic r1, r3, #0x000C0000
+ str r1, [r0]
+ add r0, r0, #0x04
+ mov r1, #0x0
+ str r1, [r0]
+
+ /* Delay about 10us */
+ ldr r2, =0x0000000A @ Set Timer3 Reload = 10 us
+ init_delay_timer
+delay0_1:
+ check_delay_timer
+ bne delay0_1
+ clear_delay_timer
+ /* end delay 10us */
+
+ ldr r0, =0x1e6e0064
+ str r3, [r0]
+
+ /* Delay about 10us */
+ ldr r2, =0x0000000A @ Set Timer3 Reload = 10 us
+ init_delay_timer
+delay0_2:
+ check_delay_timer
+ bne delay0_2
+ clear_delay_timer
+ /* end delay 10us */
+
+ b CBRDLL1_2300_Start
+
+cbrdll1_scan_done:
+ and r1, r1, #0xFF
+ add r1, r1, r2
+ mov r6, r1, lsr #1 @ dll1.0 = (dllmin + dllmax) >> 1
+ cmp r6, r5
+ subge r6, r6, r5
+ add r3, r6, r5, lsr #2 @ dll1.1 = dll1.0 + (MADJ >> 2)
+
+ ldr r0, =0x1e6e0004
+ ldr r1, [r0]
+ mov r1, r1, lsr #10
+ tst r1, #0x1
+ bne cbrdll1_scan_set_2400
+ cmp r3, r5
+ subge r3, r3, r5
+ mov r2, #0x0
+ tst r3, #0x08
+ beq cbrdll1_scan_set_2300_2 @ if !(dll & 8)
+cbrdll1_scan_set_2300_1: @ if (dll & 8)
+ mov r1, #0x0
+ tst r3, #0x08
+ addeq r1, r1, #0x01
+ cmp r2, #0x05
+ addge r1, r1, #0x01
+ cmp r1, #0x02
+ beq cbrdll1_scan_set
+ add r2, r2, #0x01
+ add r3, r3, #0x01
+ cmp r3, r5
+ subge r3, r3, r5
+ b cbrdll1_scan_set_2300_1
+
+cbrdll1_scan_set_2300_2:
+ and r1, r3, #0x07
+ cmp r1, #0x07
+ beq cbrdll1_scan_set
+ cmp r2, #0x05
+ bge cbrdll1_scan_set
+ add r2, r2, #0x01
+ add r3, r3, #0x01
+ cmp r3, r5
+ subge r3, r3, r5
+ b cbrdll1_scan_set_2300_2
+
+cbrdll1_scan_set_2400:
+ add r3, r3, #0x05 @ dll1.1 = dll1.0 + (MADJ >> 2) + 5
+ cmp r3, r5
+ subge r3, r3, r5
+
+cbrdll1_scan_set:
+ orr r1, r6, r3, lsl #8
+ ldr r0, =0x1e6e0068
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0120
+ ldr r1, [r0]
+ cmp r1, #0x0
+ beq MCLK2X_Phase_CBR_Done_DDR3
+ cmp r1, #0x1
+ beq MCLK2X_Phase_CBR_Done_DDR2
+ b CBRDLL1_2400_Call
+
+.LTORG
+
+/******************************************************************************
+ Calibration Code Start
+ SRAM buffer definition
+ 0x1E720000 : Pass 1, DLLI MIN value range
+ 0x1E720008 : DQS0 DLL valid range, 2nd time CBR
+ 0x1E72000C : DQS1 DLL valid range, 2nd time CBR
+ 0x1E720010 : DQ0 DLL valid range, Pass 1
+ 0x1E720014 : DQ1 DLL valid range, Pass 1
+ ....
+ 0x1E720048 : DQ14 DLL valid range, Pass 1
+ 0x1E72004C : DQ15 DLL valid range, Pass 1
+ 0x1E720090 : DLL1 SAdj record
+ 0x1E720094 : DQL Pass1 finetune result
+ 0x1E720098 : DQH Pass1 finetune result
+ 0x1E72009C : DRAM initial time, (us)
+ 0x1E7200A0 : CBR3 retry counter
+ 0x1E7200A4 : DRAM initial time, (us)
+ 0x1E7200A8 : Released date
+ 0x1E7200AC : Released SDK version
+ 0x1E7200B0 : DQS input mask window for MCR18[4] = 0
+ 0x1E7200B4 : DQS input mask window for MCR18[4] = 1
+ 0x1E720100 : DQIDLY=00, DLL valid range
+ 0x1E720104 : DQIDLY=01, DLL valid range
+ ....
+ 0x1E720178 : DQIDLY=30, DLL valid range
+ 0x1E72017C : DQIDLY=31, DLL valid range
+ 0x1E720180 : DQSI-MCLK2X P-phase pass record DLL2= 0-31
+ 0x1E720184 : DQSI-MCLK2X P-phase pass record DLL2=32-63
+ 0x1E720188 : DQSI-MCLK2X N-phase pass record DLL2= 0-31
+ 0x1E72018C : DQSI-MCLK2X N-phase pass record DLL2=32-63
+ ******************************************************************************/
+Calibration_Start_pre: @ Toggle DQSI mask delay
+ ldr r0, =0x1e6e0018
+ ldr r1, [r0]
+ eor r1, r1, #0x10
+ str r1, [r0]
+
+Calibration_Start:
+/* Init SRAM buffer */
+ ldr r1, =0x000000ff
+ ldr r0, =0x1e720000
+ ldr r2, =0x1e720100
+init_sram_start:
+ str r1, [r0]
+ add r0, r0, #4
+ cmp r0, r2
+ blt init_sram_start
+
+ ldr r1, =0x00ff00ff
+ ldr r0, =0x1e720100
+ ldr r2, =0x1e720180
+init_sram_start2:
+ str r1, [r0]
+ add r0, r0, #4
+ cmp r0, r2
+ blt init_sram_start2
+
+ ldr r1, =0x00000000
+ ldr r0, =0x1e720180
+ ldr r2, =0x1e720200
+init_sram_start3:
+ str r1, [r0]
+ add r0, r0, #4
+ cmp r0, r2
+ blt init_sram_start3
+
+ ldr r0, =0x1e6e0068 @ save the DLL1 SAdj initial value
+ ldr r1, [r0]
+ ldr r0, =0x1e720090
+ str r1, [r0]
+
+/* Start
+ r0 = free
+ r1 = free
+ r2 = free
+ r3 = free
+ r4 = record the return pc value, do not use
+ r5 = pattern table index
+ r6 = pass count
+ r7 = dram DLL2 parameter index (0x1e6e0068), max is 0x4C
+*/
+/******************************************************************************
+ Fine DQI delay and DQSI-MCLK phase
+ r8 = DQIDLY count
+ r9 = DQSI-MCLK2X phase count
+ r10 = pattern fail retry counter, initialize to 2 (fail 2 times)
+ r11 = passcnt accumulator for each DQIDLY
+ *****************************************************************************/
+CBR0_START:
+/* Debug - UART console message */
+ ldr r0, =0x1e784000
+ mov r1, #0x43 @ 'C'
+ str r1, [r0]
+ mov r1, #0x42 @ 'B'
+ str r1, [r0]
+ mov r1, #0x52 @ 'R'
+ str r1, [r0]
+ mov r1, #0x30 @ '0'
+ str r1, [r0]
+ mov r1, #0x2D @ '-'
+ str r1, [r0]
+/* Debug - UART console message */
+
+ ldr r0, =0x1e6e0018
+ ldr r1, [r0]
+ bic r1, r1, #0xFF000000
+ bic r1, r1, #0x00FF0000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 1KB
+ ldr r1, =0x000003FF
+ str r1, [r0]
+
+ mov r8, #0x00 @ init DQIDLY
+ mov r9, #0x00 @ init DQSI-MCLK2X phase
+ mov r11, #0x01 @ init passcnt accumulator
+
+cbr0_next_dqidly:
+ cmp r9, #0x00
+ bne cbr0_next_dqsiphase
+ cmp r11, #0x00
+ addeq r8, r8, #0x01 @ jump 1 stage if no pass at previous stage
+ mov r11, #0x00
+ add r8, r8, #0x01
+ cmp r8, #0x1F @ max DQIDLY = 31
+ bgt CBR0_END
+
+/* Debug - UART console message */
+ ldr r0, =0x1e784000
+ and r1, r8, #0x07
+ add r1, r1, #0x30 @ '0-7'
+ str r1, [r0]
+/* Debug - UART console message */
+
+ ldr r0, =0x1e6e0018
+ ldr r1, [r0]
+ bic r1, r1, #0x00FF0000
+ orr r1, r1, r8, lsl #16
+ str r1, [r0]
+ mov r9, #0x01 @ '1':p_phase, '0':n_phase
+
+ /* Delay about 3us */ @ wait DQIDLY load
+ ldr r2, =0x00000003 @ Set Timer4 Reload = 3 us
+ init_delay_timer
+delay_4:
+ check_delay_timer
+ bne delay_4
+ clear_delay_timer
+ /* end delay 3us */
+
+ b cbr0_dll2_scan_start
+
+cbr0_next_dqsiphase:
+ ldr r0, =0x1e6e0018
+ ldr r1, [r0]
+ orr r1, r1, r9, lsl #23 @ set DQSI-MCLK2X phase
+ str r1, [r0]
+ mov r9, #0x00
+
+cbr0_dll2_scan_start:
+ mov r6, #0x00 @ init pass count
+ mov r7, #0x00 @ init DLL2 parameter index
+
+/****************************
+ DLL2 delay margin test loop
+ ***************************/
+cbr0_next_dll2_parameter:
+ ldr r0, =0x1e6e0068 @ load DLL2 parameter
+ ldr r1, [r0]
+ bic r1, r1, #0x00FF0000
+ bic r1, r1, #0xFF000000
+ orr r1, r1, r7, lsl #16
+ str r1, [r0]
+ ldr r2, =0x40404040 @ DLL2 max is 0x40404040
+ cmp r7, r2
+ bge cbr0_next_dqidly
+ ldr r2, =0x01010101
+ add r7, r7, r2
+
+/* CBRScan3() start */
+ adrl r5, PATTERN_TABLE @ init pattern table index
+/****************************
+ Test pattern iteration loop
+ ***************************/
+cbr0_next_test_pattern:
+ mov r10, #2 @ set the retry loop = 2 of each pattern
+ ldr r1, [r5] @ load test pattern
+ ldr r0, =0x1e6e007c
+ str r1, [r0]
+ cmp r1, #0x00 @ the last data in pattern is 0x00
+ bne cbr0_test_burst
+
+ and r3, r7, #0xFF
+ sub r3, r3, #0x01 @ we add 1 after loop check so we need to decrease 1
+ cmp r3, #0x00
+ beq cbr0_next_dqidly @ pass at dlli = 0, invalid
+ add r6, r6, #0x01 @ increment pass count
+ add r11, r11, #0x01 @ increment pass count
+
+ ldr r0, =0x1e720180 @ record DLL2 pass window
+ cmp r9, #0x00 @ DQSI-MCLK2X phase check
+ addeq r0, r0, #0x08
+ cmp r3, #32
+ addge r0, r0, #0x4
+ and r1, r3, #0x1F
+ mov r2, #0x1
+ mov r2, r2, lsl r1
+ ldr r1, [r0]
+ orr r1, r1, r2
+ str r1, [r0]
+
+ ldr r0, =0x1e720100 @ record DLL2 min:max value for each DQIDLY
+ add r0, r0, r8, lsl #2
+ cmp r9, #0x00 @ DQSI-MCLK2X phase check
+ beq cbr0_test_pass_dqsin
+ record_dll2_pass_range
+ b cbr0_next_dll2_parameter
+
+cbr0_test_pass_dqsin:
+ record_dll2_pass_range_h
+ b cbr0_next_dll2_parameter
+
+cbr0_test_pattern_fail:
+ cmp r6, #5 @ passcnt >= 5
+ bge cbr0_next_dqidly
+ ldr r0, =0x1e720100 @ reset DLL2 min:max value
+ add r0, r0, r8, lsl #2
+ ldr r1, [r0]
+ ldr r2, =0xFFFF0000
+ ldr r3, =0x000000FF
+ cmp r9, #0x00
+ moveq r2, r2, lsr #16
+ moveq r3, r3, lsl #16
+ and r1, r1, r2
+ orr r1, r1, r3
+ str r1, [r0]
+ b cbr0_next_dll2_parameter @ CBRScan3() end and test result fail, go to next step
+
+/****************************
+ Test fail retry loop
+ ***************************/
+cbr0_pattern_fail_retry:
+
+/* CBRTest3() start */
+cbr0_test_burst:
+ ldr r0, =0x1e6e0070
+ ldr r1, =0x00000000
+ str r1, [r0]
+ ldr r1, =0x000000C1
+ str r1, [r0]
+ ldr r3, =0x3000
+cbr0_wait_engine_idle_0:
+ ldr r2, [r0]
+ tst r2, r3 @ D[12] = idle bit
+ beq cbr0_wait_engine_idle_0
+
+ ldr r2, [r0] @ read fail bit status
+ mov r1, #0x0
+ str r1, [r0]
+ mov r2, r2, lsr #13 @ D[13] = fail bit
+ cmp r2, #0x00
+ bne cbr0_test_fail
+
+cbr0_test_single:
+ ldr r0, =0x1e6e0070
+ ldr r1, =0x00000000
+ str r1, [r0]
+ ldr r1, =0x00000085
+ str r1, [r0]
+ ldr r3, =0x3000
+cbr0_wait_engine_idle_1:
+ ldr r2, [r0]
+ tst r2, r3 @ D[12] = idle bit
+ beq cbr0_wait_engine_idle_1
+
+ ldr r2, [r0] @ read fail bit status
+ mov r1, #0x0
+ str r1, [r0]
+ mov r2, r2, lsr #13 @ D[13] = fail bit
+ cmp r2, #0x00
+ beq cbr0_test_pass
+
+/* CBRTest3() end */
+
+cbr0_test_fail:
+ subs r10, r10, #1
+ bne cbr0_pattern_fail_retry
+ b cbr0_test_pattern_fail @ CBRScan3() return(0)
+
+cbr0_test_pass:
+ add r5, r5, #0x04 @ increase the test pattern index
+ b cbr0_next_test_pattern
+
+CBR0_END:
+ mov r5, #0x0 @ init DQIDLY search count
+ mov r6, #0x0 @ init max_margin:g_margin
+ mov r8, #0x0 @ init g_side
+ mov r7, #0x0 @ init maximum margin DQIDLY,DQSI-MCLK2X phase
+cbr0_search_dll_margin_s:
+ ldr r0, =0x1e720100
+ add r0, r0, r5, lsl #2
+ ldr r1, [r0]
+ and r2, r1, #0xFF @ get dllmin_p
+ mov r1, r1, lsr #8
+ and r3, r1, #0xFF @ get dllmax_p
+ subs r2, r3, r2 @ get margin-P
+ movmi r2, #0x0
+ mov r1, r1, lsr #8
+ and r3, r1, #0xFF @ get dllmin_n
+ mov r1, r1, lsr #8
+ and r1, r1, #0xFF @ get dllmax_n
+ subs r3, r1, r3 @ get margin-N
+ movmi r3, #0x0
+ add r1, r2, r3
+ cmp r1, #0x0
+ beq cbr0_search_dll_margin_e @ if margin-P = 0 && margin-N = 0
+
+ ldr r9, [r0]
+ ldr r0, =0x1e720180
+ cmp r2, r3
+ orrlt r5, r5, #0x80 @ margin-N > margin-P
+ addlt r0, r0, #0x08
+ movlt r9, r9, lsr #16
+ movge r3, r2 @ max(margin-P/N)
+ add r2, r3, #0x2 @ define +/- 2 steps of variation
+ mov r1, r6, lsr #16
+ cmp r2, r1
+ blt cbr0_search_dll_margin_e @ if max(margin-P/N) + 2 < max_margin
+
+ and r1, r9, #0xFF @ r1 = dlli counter
+ cmp r1, #32
+ ldrge r2, [r0, #0x4] @ load pass window
+ ldrlt r2, [r0]
+ and r1, r1, #0x1F
+ mov r10, #0x1 @ init test bit mask
+ mov r10, r10, lsl r1
+ and r1, r9, #0xFF
+cbr0_search_dllmin_margin_s:
+ tst r2, r10
+ beq cbr0_search_dllmin_margin_e
+ mov r10, r10, lsr #1
+ cmp r1, #32
+ ldreq r2, [r0]
+ ldreq r10, =0x80000000
+ subs r1, r1, #0x1
+ bne cbr0_search_dllmin_margin_s
+
+cbr0_search_dllmin_margin_e:
+ and r2, r9, #0xFF
+ sub r11, r2, r1 @ get dllmin side margin
+
+ mov r9, r9, lsr #8
+ and r1, r9, #0xFF @ r1 = dlli counter
+ cmp r1, #32
+ ldrge r2, [r0, #0x4] @ load pass window
+ ldrlt r2, [r0]
+ and r1, r1, #0x1F
+ mov r10, #0x1 @ init test bit mask
+ mov r10, r10, lsl r1
+ and r1, r9, #0xFF
+cbr0_search_dllmax_margin_s:
+ tst r2, r10
+ beq cbr0_search_dllmax_margin_e
+ mov r10, r10, lsl #1
+ cmp r1, #31
+ ldreq r2, [r0, #0x4]
+ ldreq r10, =0x00000001
+ add r1, r1, #0x1
+ cmp r1, #64
+ bne cbr0_search_dllmax_margin_s
+
+cbr0_search_dllmax_margin_e:
+ and r2, r9, #0xFF
+ sub r1, r1, r2 @ get dllmax side margin
+ cmp r1, r11
+ movlt r11, r1 @ get side_margin
+
+cbr0_check_dll_margin: @ if max(margin-P/N) > g_margin && side_margin >= g_side && dqidly <= 20
+ cmp r5, #20
+ bgt cbr0_check_dll_margin2
+ and r1, r6, #0xFF
+ cmp r3, r1
+ ble cbr0_check_dll_margin3
+ cmp r11, r8
+ bge cbr0_set_dll_margin
+
+cbr0_check_dll_margin2: @ if max(margin-P/N) > g_margin+1 && side_margin >= g_side)
+ and r1, r6, #0xFF
+ add r2, r1, #0x1
+ cmp r3, r2
+ ble cbr0_check_dll_margin3
+ cmp r11, r8
+ bge cbr0_set_dll_margin
+
+cbr0_check_dll_margin3: @ if side_margin > g_side && g_side < 8
+ cmp r8, #8
+ bge cbr0_search_dll_margin_e
+ cmp r11, r8
+ ble cbr0_search_dll_margin_e
+
+cbr0_set_dll_margin:
+ mov r1, r6, lsr #16
+ cmp r3, r1
+ bicgt r6, r6, #0x00FF0000
+ orrgt r6, r6, r3, lsl #16
+ bic r6, r6, #0x000000FF
+ orr r6, r6, r3
+ mov r7, r5
+ mov r8, r11
+
+cbr0_search_dll_margin_e:
+ and r5, r5, #0x7F
+ add r5, r5, #0x01
+ cmp r5, #0x20 @ last DQIDLY
+ blt cbr0_search_dll_margin_s
+
+ ldr r0, =0x1e6e0018
+ ldr r1, [r0]
+ bic r1, r1, #0x00FF0000
+ orr r1, r1, r7, lsl #16
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0068
+ ldr r1, [r0]
+ bic r1, r1, #0x00FF0000
+ bic r1, r1, #0xFF000000
+ str r1, [r0]
+
+ /* Delay about 5us */
+ ldr r2, =0x00000005 @ Set Timer5 Reload = 5 us
+ init_delay_timer
+delay_5:
+ check_delay_timer
+ bne delay_5
+ clear_delay_timer
+ /* end delay 5us */
+
+ ldr r0, =0x1e6e000c @ Set refresh cycle
+ ldr r1, =0x00005C01
+ str r1, [r0]
+
+/******************************************************************************
+ Fine tune per bit DQ input delay -- Pass 1, left edge align
+ r8 = free
+ r9 = DQ fail bit accumulator
+ r10 = pattern fail counter, initialize to 5 (fail 5 times)
+ r11 = free
+ *****************************************************************************/
+CBR1_START:
+/* Debug - UART console message */
+ ldr r0, =0x1e784000
+ mov r1, #0x0D @ '\r'
+ str r1, [r0]
+ mov r1, #0x0A @ '\n'
+ str r1, [r0]
+ mov r1, #0x43 @ 'C'
+ str r1, [r0]
+ mov r1, #0x42 @ 'B'
+ str r1, [r0]
+ mov r1, #0x52 @ 'R'
+ str r1, [r0]
+ mov r1, #0x31 @ '1'
+ str r1, [r0]
+/* Debug - UART console message */
+
+ mov r6, #0x00 @ init pass count
+ mov r7, #0x00 @ init DLL2 parameter index
+
+/****************************
+ DLL2 delay margin test loop
+ ***************************/
+cbr1_next_dll2_parameter:
+ ldr r0, =0x1e6e0068 @ load DLL2 parameter
+ ldr r1, [r0]
+ bic r1, r1, #0x00FF0000
+ bic r1, r1, #0xFF000000
+ orr r1, r1, r7, lsl #16
+ str r1, [r0]
+ ldr r2, =0x40404040 @ parameter's max is to 0x40404040
+ cmp r7, r2
+ bge CBR1_END
+ ldr r2, =0x01010101
+ add r7, r7, r2
+
+ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 4KB
+ ldr r1, =0x00000FFF
+ str r1, [r0]
+
+/* CBRScan2() start */
+ ldr r9, =0xFFFF @ init test status
+ adrl r5, PATTERN_TABLE @ init pattern table index
+/****************************
+ Test pattern iteration loop
+ ***************************/
+cbr1_next_test_pattern:
+ mov r10, #5 @ set the retry loop of each pattern
+ ldr r1, [r5] @ load test pattern
+ ldr r0, =0x1e6e007c
+ str r1, [r0]
+ cmp r1, #0x00 @ the last data in pattern is 0x00
+ bne cbr1_test_single
+
+cbr1_test_pattern_end:
+ cmp r9, #0x00
+ bne cbr1_test_pass_dqi
+ cmp r6, #10
+ bge CBR1_END
+ b cbr1_next_dll2_parameter @ CBRScan2() end and test result fail, go to next step
+
+cbr1_test_pass_dqi:
+ and r3, r7, #0xFF
+ sub r3, r3, #0x01 @ we add 1 after loop check so we need to decrease 1
+ add r6, r6, #0x01 @ increment pass count
+ ldr r0, =0x1e720010
+ mov r8, #0x01
+cbr1_test_pass_dqi_loop_s:
+ tst r9, r8
+ beq cbr1_test_pass_dqi_loop_e
+ record_dll2_pass_range
+
+cbr1_test_pass_dqi_loop_e:
+ add r0, r0, #0x04
+ mov r8, r8, lsl #1
+ ldr r1, =0xFFFF
+ tst r8, r1
+ bne cbr1_test_pass_dqi_loop_s
+ b cbr1_next_dll2_parameter
+
+/****************************
+ Test fail retry loop
+ ***************************/
+cbr1_pattern_fail_retry:
+
+/* CBRTest2() start */
+cbr1_test_single:
+ ldr r0, =0x1e6e0070
+ ldr r1, =0x00000000
+ str r1, [r0]
+ ldr r1, =0x00000005
+ str r1, [r0]
+ ldr r3, =0x1000
+ ldr r1, =0x1000
+cbr1_wait_engine_idle_0:
+ subs r1, r1, #1
+ beq cbr1_test_single_end
+ ldr r2, [r0]
+ tst r2, r3 @ D[12] = idle bit
+ beq cbr1_wait_engine_idle_0
+
+cbr1_test_single_end:
+ ldr r0, =0x1e6e0078 @ read fail bit status
+ ldr r11, [r0]
+ orr r11, r11, r11, lsr #16
+ bic r11, r11, #0xFF000000
+ bic r11, r11, #0x00FF0000
+
+ ldr r1, =0xFFFF
+ cmp r11, r1
+ beq cbr1_test_fail
+
+cbr1_test_burst:
+ ldr r0, =0x1e6e0070
+ ldr r2, =0x00000000
+ str r2, [r0]
+ ldr r2, =0x00000041
+ str r2, [r0]
+ ldr r3, =0x1000
+ ldr r1, =0x1000
+cbr1_wait_engine_idle_1:
+ subs r1, r1, #1
+ beq cbr1_test_burst_end
+ ldr r2, [r0]
+ tst r2, r3 @ D[12] = idle bit
+ beq cbr1_wait_engine_idle_1
+
+cbr1_test_burst_end:
+ ldr r0, =0x1e6e0078 @ read fail bit status
+ ldr r2, [r0]
+ orr r2, r2, r2, lsr #16
+ bic r2, r2, #0xFF000000
+ bic r2, r2, #0x00FF0000
+ orr r11, r11, r2
+
+ ldr r2, =0xFFFF
+ cmp r11, r2
+ bne cbr1_test_pass
+/* CBRTest2() end */
+
+cbr1_test_fail:
+ subs r10, r10, #1
+ bne cbr1_pattern_fail_retry
+ mov r9, #0x00
+ b cbr1_test_pattern_end @ CBRScan2() return(0)
+
+cbr1_test_pass:
+ ldr r1, =0xFFFF @ record the pass bit
+ eor r11, r11, r1
+ and r9, r9, r11 @ DQ pass bit
+ cmp r9, #0x00
+ beq cbr1_test_pattern_end @ CBRScan2() return(0)
+
+ add r5, r5, #0x04 @ increase the test pattern index
+ b cbr1_next_test_pattern
+
+CBR1_END:
+ mov r5, #0x0 @ init DQ DLL_min sum
+ mov r6, #0x0 @ init DQ DLL_min valid count
+ ldr r0, =0x1e72000c
+ ldr r3, =0x1e720050
+cbr1_search_dllmin_s:
+ add r0, r0, #0x04
+ cmp r0, r3
+ beq cbr1_search_dllmin_e
+ ldr r1, [r0]
+ mov r2, r1, lsr #8
+ and r2, r2, #0xFF @ get dllmax
+ and r1, r1, #0xFF @ get dllmin
+ subs r2, r2, r1 @ dllmax - dllmin
+ bmi cbr1_search_dllmin_s @ no valid margin found, bypass fine tune
+ cmp r2, #10 @ (dllmax - dllmin) < 10
+ blt cbr1_search_dllmin_s @ no enough margin found, bypass fine tune
+ add r5, r5, r1
+ add r6, r6, #1
+ b cbr1_search_dllmin_s
+
+cbr1_search_dllmin_e:
+ cmp r6, #16
+ bne Calibration_Start_pre @ not all bits valid, retry again
+
+ mov r5, r5, lsr #4
+ ldr r0, =0x1e720000
+ str r5, [r0]
+
+ mov r6, #0x00 @ init DQL CBR value
+ ldr r0, =0x1e720030
+ ldr r7, =0x1e72000c
+cbr1_set_result_dql:
+ sub r0, r0, #4
+ cmp r0, r7
+ beq cbr1_set_result_next
+ mov r6, r6, lsl #3
+ ldr r1, [r0]
+ mov r2, r1, lsr #8
+ and r2, r2, #0xFF @ get dllmax
+ and r1, r1, #0xFF @ get dllmin
+ mov r3, r1 @ dll = dllmin
+ cmp r5, r3
+ blt cbr1_set_result_dql_neg
+ sub r1, r5, r3
+ mov r2, #19
+ mul r1, r2, r1
+ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
+ cmp r1, #2 @ dqi_tune max = 2
+ movgt r1, #2
+ orr r6, r6, r1
+ b cbr1_set_result_dql
+
+cbr1_set_result_dql_neg:
+ sub r1, r3, r5
+ mov r2, #19
+ mul r1, r2, r1
+ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
+ cmp r1, #2 @ dqi_tune max = -2
+ movgt r1, #2
+ mov r2, #8
+ sub r1, r2, r1
+ and r1, r1, #7
+ orr r6, r6, r1
+ b cbr1_set_result_dql
+
+cbr1_set_result_next:
+ ldr r0, =0x1e6e0080 @ save DQL fine tune result
+ str r6, [r0]
+ ldr r0, =0x1e720094
+ str r6, [r0]
+
+ mov r6, #0x00 @ init DQH CBR value
+ ldr r0, =0x1e720050
+ ldr r7, =0x1e72002c
+cbr1_set_result_dqh:
+ sub r0, r0, #4
+ cmp r0, r7
+ beq cbr1_set_result_end
+ mov r6, r6, lsl #3
+ ldr r1, [r0]
+ mov r2, r1, lsr #8
+ and r2, r2, #0xFF @ get dllmax
+ and r1, r1, #0xFF @ get dllmin
+ mov r3, r1 @ dll = dllmin
+ cmp r5, r3
+ blt cbr1_set_result_dqh_neg
+ sub r1, r5, r3
+ mov r2, #19
+ mul r1, r2, r1
+ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
+ cmp r1, #3 @ dqi_tune max = 2
+ movgt r1, #3
+ subs r1, r1, #1
+ movmi r1, #7
+ orr r6, r6, r1
+ b cbr1_set_result_dqh
+
+cbr1_set_result_dqh_neg:
+ sub r1, r3, r5
+ mov r2, #19
+ mul r1, r2, r1
+ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
+ add r1, r1, #1
+ cmp r1, #2 @ dqi_tune max = -2
+ movgt r1, #2
+ mov r2, #8
+ sub r1, r2, r1
+ and r1, r1, #7
+ orr r6, r6, r1
+ b cbr1_set_result_dqh
+
+cbr1_set_result_end:
+ ldr r0, =0x1e6e0084 @ save DQH fine tune result
+ str r6, [r0]
+ ldr r0, =0x1e720098
+ str r6, [r0]
+
+/******************************************************************************
+ Search the DLL2 detail margin
+ *****************************************************************************/
+ ldr r0, =0x1e7200a0
+ mov r1, #0
+ str r1, [r0]
+
+CBR3_START:
+/* Debug - UART console message */
+ ldr r0, =0x1e784000
+ mov r1, #0x33 @ '3'
+ str r1, [r0]
+/* Debug - UART console message */
+
+ mov r6, #0x00 @ init pass count
+ mov r7, #0x00 @ init DLL2 parameter index
+ ldr r1, =0x000000ff
+ ldr r0, =0x1e720008 @ init DQL dllmax,dllmin
+ str r1, [r0]
+ ldr r0, =0x1e72000c @ init DQH dllmax,dllmin
+ str r1, [r0]
+
+ ldr r0, =0x1e7200a0 @ CBR3 iteration counter
+ ldr r1, [r0]
+ add r1, r1, #1
+ str r1, [r0]
+
+/****************************
+ DLL2 delay margin test loop
+ ***************************/
+cbr3_next_dll2_parameter:
+ ldr r0, =0x1e6e0068 @ load DLL2 parameter
+ ldr r1, [r0]
+ bic r1, r1, #0x00FF0000
+ bic r1, r1, #0xFF000000
+ orr r1, r1, r7, lsl #16
+ str r1, [r0]
+ ldr r2, =0x40404040 @ parameter's max is to 0x40404040
+ cmp r7, r2
+ bge CBR3_END
+ ldr r2, =0x01010101
+ add r7, r7, r2
+
+ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 64KB
+ ldr r1, =0x0000FFFF
+ str r1, [r0]
+
+/* CBRScan() start */
+ mov r9, #0x03 @ init test status
+ adrl r5, PATTERN_TABLE @ init pattern table index
+/****************************
+ Test pattern iteration loop
+ ***************************/
+cbr3_next_test_pattern:
+ mov r10, #5 @ set the retry loop of each pattern
+ ldr r1, [r5] @ load test pattern
+ ldr r0, =0x1e6e007c
+ str r1, [r0]
+ cmp r1, #0x00 @ the last data in pattern is 0x00
+ bne cbr3_test_single
+
+cbr3_test_pattern_end:
+ cmp r9, #0x00
+ bne cbr3_test_pass_dql
+ cmp r6, #10
+ bge CBR3_END
+ b cbr3_next_dll2_parameter @ CBRScan() end and test result fail, go to next step
+
+cbr3_test_pass_dql:
+ and r3, r7, #0xFF
+ sub r3, r3, #0x01 @ we add one after loop check so we need to decrease 1
+ add r6, r6, #0x01 @ increment pass count
+ tst r9, #0x01
+ beq cbr3_test_pass_dqh
+
+ ldr r0, =0x1E720008
+ record_dll2_pass_range
+
+cbr3_test_pass_dqh:
+ tst r9, #0x02
+ beq cbr3_next_dll2_parameter
+ ldr r0, =0x1E72000c
+ record_dll2_pass_range
+ b cbr3_next_dll2_parameter
+
+/****************************
+ Test fail retry loop
+ ***************************/
+cbr3_pattern_fail_retry:
+
+/* CBRTest() start */
+cbr3_test_single:
+ ldr r0, =0x1e6e0070
+ ldr r1, =0x00000000
+ str r1, [r0]
+ ldr r1, =0x00000005
+ str r1, [r0]
+ ldr r3, =0x1000
+ ldr r8, =0x10000
+cbr3_wait_engine_idle_0:
+ subs r8, r8, #1
+ beq cbr3_test_single_end
+ ldr r2, [r0]
+ tst r2, r3 @ D[12] = idle bit
+ beq cbr3_wait_engine_idle_0
+
+cbr3_test_single_end:
+ ldr r0, =0x1e6e0078 @ read fail bit status
+ ldr r11, [r0]
+ orr r11, r11, r11, lsr #16
+ bic r11, r11, #0xFF000000
+ bic r11, r11, #0x00FF0000
+
+ ldr r1, =0xFF
+ tst r11, r1
+ beq cbr3_test_burst
+ tst r11, r1, lsl #8
+ bne cbr3_test_fail
+
+cbr3_test_burst:
+ mov r1, #0x00 @ initialize loop index, r1 is loop's index
+cbr3_test_burst_loop:
+ ldr r0, =0x1e6e0070
+ ldr r2, =0x00000000
+ str r2, [r0]
+ mov r2, r1, lsl #3
+ orr r2, r2, #0x41 @ test command = 0x41 | (datagen << 3)
+ str r2, [r0]
+ ldr r3, =0x1000
+ ldr r8, =0x10000
+cbr3_wait_engine_idle_1:
+ subs r8, r8, #1
+ beq cbr3_test_burst_end
+ ldr r2, [r0]
+ tst r2, r3 @ D[12] = idle bit
+ beq cbr3_wait_engine_idle_1
+
+cbr3_test_burst_end:
+ ldr r0, =0x1e6e0078 @ read fail bit status
+ ldr r2, [r0]
+ orr r2, r2, r2, lsr #16
+ bic r2, r2, #0xFF000000
+ bic r2, r2, #0x00FF0000
+ orr r11, r11, r2
+
+ ldr r2, =0xFF
+ tst r11, r2
+ beq cbr3_next_test_burst_mode
+ tst r11, r2, lsl #8
+ beq cbr3_next_test_burst_mode
+/* CBRTest() end */
+
+cbr3_test_fail:
+ subs r10, r10, #1
+ bne cbr3_pattern_fail_retry
+ mov r9, #0x00
+ b cbr3_test_pattern_end @ CBRScan() return(0)
+
+cbr3_next_test_burst_mode:
+ add r1, r1, #1 @ increase the test mode index
+ cmp r1, #0x08 @ there are 8 modes
+ bne cbr3_test_burst_loop
+
+ ldr r1, =0xFF @ record the pass byte
+ tst r11, r1
+ andne r9, r9, #0x02 @ DQL fail
+ tst r11, r1, lsl #8
+ andne r9, r9, #0x01 @ DQH fail
+ cmp r9, #0x00
+ beq cbr3_test_pattern_end @ CBRScan() return(0)
+
+ add r5, r5, #0x04 @ increase the test pattern index
+ b cbr3_next_test_pattern
+
+CBR3_END:
+ ldr r0, =0x1e72000c @ check DQH margin
+ ldr r1, [r0]
+ mov r2, r1, lsr #8
+ and r2, r2, #0xFF @ get dllmax
+ and r1, r1, #0xFF @ get dllmin
+ subs r5, r2, r1 @ dllmax - dllmin
+ bmi CBR3_START @ no valid margin found, retry again
+ cmp r5, #10 @ (dllmax - dllmin) < 10
+ blt CBR3_START @ no enough margin found, retry again
+ add r2, r1, r2 @ (dllmin[1] + dllmax[1] + 1) >> 1
+ add r2, r2, #0x01
+ mov r1, r2, lsr #1
+ mov r3, r1, lsl #8
+ ldr r1, [r0] @ store the dll search result
+ bic r1, r1, #0xFF000000
+ bic r1, r1, #0x00FF0000
+ orr r1, r1, r3, lsl #8
+ str r1, [r0]
+
+ ldr r0, =0x1e720008 @ check DQL margin
+ ldr r1, [r0]
+ mov r2, r1, lsr #8
+ and r2, r2, #0xFF @ get dllmax
+ and r1, r1, #0xFF @ get dllmin
+ subs r5, r2, r1 @ dllmax - dllmin
+ bmi CBR3_START @ no valid margin found, retry again
+ cmp r5, #10 @ (dllmax - dllmin) < 10
+ blt CBR3_START @ no enough margin found, retry again
+ add r2, r1, r2 @ (dllmin[0] + dllmax[0] + 1) >> 1
+ add r2, r2, #0x01
+ mov r1, r2, lsr #1
+ ldr r2, [r0] @ store the dll search result
+ bic r2, r2, #0xFF000000
+ bic r2, r2, #0x00FF0000
+ orr r2, r2, r1, lsl #16
+ str r2, [r0]
+ orr r3, r3, r1
+
+ ldr r0, =0x1e6e0068 @ save the result dll value
+ ldr r1, [r0]
+ bic r1, r1, #0xFF000000
+ bic r1, r1, #0x00FF0000
+ orr r1, r1, r3, lsl #16
+ str r1, [r0]
+ b CBR4_START
+
+.LTORG
+
+/******************************************************************************
+ Search the DQS input mask margin
+ *****************************************************************************/
+CBR4_START:
+/* Debug - UART console message */
+ ldr r0, =0x1e784000
+ mov r1, #0x34 @ '4'
+ str r1, [r0]
+/* Debug - UART console message */
+
+ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 4KB
+ ldr r1, =0x00000FFF
+ str r1, [r0]
+
+ mov r8, #0x00 @ init MCR18[4]
+ ldr r1, =0x000000ff
+ ldr r0, =0x1e7200b0 @ init MCR18[4]=0 max,min
+ str r1, [r0]
+ ldr r0, =0x1e7200b4 @ init MCR18[4]=1 max,min
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0018
+ ldr r1, [r0]
+ bic r1, r1, #0x0000001F
+ str r1, [r0]
+
+ b cbr4_scan_start
+
+cbr4_next_maskdly:
+ add r8, r8, #0x01
+ and r2, r8, #0x01
+ ldr r0, =0x1e6e0018
+ ldr r1, [r0]
+ bic r1, r1, #0x0000001F
+ orr r1, r1, r2, lsl #4
+ str r1, [r0]
+ cmp r8, #0x02
+ bge CBR4_END
+
+cbr4_scan_start:
+ mov r6, #0x00 @ init pass count
+ mov r7, #0x00 @ init mask delay
+
+/****************************
+ DQS Mask delay margin test loop
+ ***************************/
+cbr4_next_parameter:
+ cmp r7, #0x10 @ max delay = 0xF
+ bge cbr4_next_maskdly
+ ldr r0, =0x1e6e0018 @ load MCR18 parameter
+ ldr r1, [r0]
+ bic r1, r1, #0x0000000F
+ orr r1, r1, r7
+ str r1, [r0]
+ add r7, r7, #0x01
+
+/* CBRScan3() start */
+ adrl r5, PATTERN_TABLE @ init pattern table index
+/****************************
+ Test pattern iteration loop
+ ***************************/
+cbr4_next_test_pattern:
+ mov r10, #2 @ set the retry loop = 2 of each pattern
+ ldr r1, [r5] @ load test pattern
+ ldr r0, =0x1e6e007c
+ str r1, [r0]
+ cmp r1, #0x00 @ the last data in pattern is 0x00
+ bne cbr4_test_burst
+
+ and r3, r7, #0xFF
+ sub r3, r3, #0x01 @ we add 1 after loop check so we need to decrease 1
+ add r6, r6, #0x01 @ increment pass count
+
+ ldr r0, =0x1e7200b0 @ record pass window
+ add r0, r0, r8, lsl #2
+ record_dll2_pass_range
+ mov r2, #0x01
+ add r1, r1, r2, lsl #16
+ str r1, [r0]
+ b cbr4_next_parameter
+
+cbr4_test_pattern_fail:
+ cmp r6, #5 @ passcnt >= 5
+ bge cbr4_next_maskdly
+ b cbr4_next_parameter
+
+/****************************
+ Test fail retry loop
+ ***************************/
+cbr4_pattern_fail_retry:
+
+/* CBRTest3() start */
+cbr4_test_burst:
+ ldr r0, =0x1e6e0070
+ ldr r1, =0x00000000
+ str r1, [r0]
+ ldr r1, =0x000000C1
+ str r1, [r0]
+ ldr r3, =0x3000
+cbr4_wait_engine_idle_0:
+ ldr r2, [r0]
+ tst r2, r3 @ D[12] = idle bit
+ beq cbr4_wait_engine_idle_0
+
+ ldr r2, [r0] @ read fail bit status
+ mov r1, #0x0
+ str r1, [r0]
+ mov r2, r2, lsr #13 @ D[13] = fail bit
+ cmp r2, #0x00
+ bne cbr4_test_fail
+
+cbr4_test_single:
+ ldr r0, =0x1e6e0070
+ ldr r1, =0x00000000
+ str r1, [r0]
+ ldr r1, =0x00000085
+ str r1, [r0]
+ ldr r3, =0x3000
+cbr4_wait_engine_idle_1:
+ ldr r2, [r0]
+ tst r2, r3 @ D[12] = idle bit
+ beq cbr4_wait_engine_idle_1
+
+ ldr r2, [r0] @ read fail bit status
+ mov r1, #0x0
+ str r1, [r0]
+ mov r2, r2, lsr #13 @ D[13] = fail bit
+ cmp r2, #0x00
+ beq cbr4_test_pass
+
+/* CBRTest3() end */
+
+cbr4_test_fail:
+ subs r10, r10, #1
+ bne cbr4_pattern_fail_retry
+ b cbr4_test_pattern_fail @ CBRScan3() return(0)
+
+cbr4_test_pass:
+ add r5, r5, #0x04 @ increase the test pattern index
+ b cbr4_next_test_pattern
+
+CBR4_END:
+ ldr r0, =0x1e7200b0 @ check mask margin
+ ldr r1, [r0]
+ add r0, r0, #0x04
+ ldr r2, [r0]
+ ands r6, r2, #0xFF @ get min of MCR18[4] = 1
+ bne cbr4_noset_delay
+ ands r5, r1, #0xFF @ get min of MCR18[4] = 0
+ bne cbr4_set_delay
+ mov r1, r1, lsr #8 @ get max of MCR18[4] = 0
+ and r1, r1, #0xFF
+ mov r2, r2, lsr #8 @ get max of MCR18[4] = 1
+ and r2, r2, #0xFF
+ sub r1, r1, r5
+ sub r2, r2, r6
+ cmp r1, r2
+ bge cbr4_noset_delay
+
+cbr4_set_delay:
+ ldr r0, =0x1e6e0018
+ ldr r1, [r0]
+ orr r1, r1, #0x10
+ str r1, [r0]
+
+cbr4_noset_delay:
+ ldr r0, =0x1e6e0070
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+/******************************************************************************
+ CBR Finish
+ *****************************************************************************/
+/******************************************************************************
+ Check DRAM Size
+ *****************************************************************************/
+ ldr r0, =0x1e6e2070
+ ldr r1, [r0]
+ bic r1, r1, #0xFEFFFFFF @ bit[24]=1 => DDR2
+ mov r2, r1, lsr #24
+ cmp r2, #0x01
+ beq check_ddr2_size
+
+ ldr r0, =0x1e6e0004
+ ldr r5, [r0]
+ bic r5, r5, #0x00000003 @ record MCR04
+ orr r1, r5, #0x3
+ str r1, [r0] @ set to 4Gbit
+ ldr r6, =0x003F2217
+#if defined(CONFIG_DRAM_336)
+ ldr r6, =0x00361C13
+#endif
+ b check_dram_size
+
+check_ddr2_size:
+ ldr r0, =0x1e6e0004
+ ldr r5, [r0]
+ bic r5, r5, #0x00000023 @ record MCR04
+ orr r1, r5, #0x23
+ str r1, [r0] @ set to 4Gbit
+ ldr r6, =0x3F2B1B16
+#if defined(CONFIG_DRAM_336)
+ ldr r6, =0x3B231612
+#endif
+
+ ldr r0, =0x40000000
+ ldr r1, =0x1817191A
+ str r1, [r0]
+ ldr r0, =0x40002000
+ ldr r1, =0x73616532
+ str r1, [r0]
+ ldr r0, =0x40000000
+ ldr r1, =0x1817191A
+ ldr r2, [r0]
+ cmp r1, r2
+ bne check_dram_size_end @ == 512Mbit
+ orr r5, r5, #0x20 @ >= 1Gbit
+ mov r6, r6, lsr #8
+
+check_dram_size:
+ ldr r0, =0x50100000
+ ldr r1, =0x41424344
+ str r1, [r0]
+ ldr r0, =0x48100000
+ ldr r1, =0x25262728
+ str r1, [r0]
+ ldr r0, =0x40100000
+ ldr r1, =0x191A1B1C
+ str r1, [r0]
+ ldr r0, =0x50100000
+ ldr r1, =0x41424344
+ ldr r2, [r0]
+ cmp r2, r1 @ == 4Gbit
+ orreq r5, r5, #0x03
+ moveq r6, r6, lsr #16
+ beq check_dram_size_end
+ ldr r0, =0x48100000
+ ldr r1, =0x25262728
+ ldr r2, [r0]
+ cmp r2, r1 @ == 2Gbit
+ orreq r5, r5, #0x02
+ moveq r6, r6, lsr #8
+ beq check_dram_size_end
+ orr r5, r5, #0x01 @ == 1Gbit
+
+check_dram_size_end:
+ ldr r0, =0x1e6e0004
+ str r5, [r0]
+ ldr r0, =0x1e6e0014
+ ldr r1, [r0]
+ bic r1, r1, #0x000000FF
+ and r6, r6, #0xFF
+ orr r1, r1, r6
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0120 @ VGA Compatible Mode
+ ldr r1, =0x000050C0 @ 408 MHz
+#if defined(CONFIG_DRAM_336)
+ ldr r1, =0x00004DC0
+#endif
+ str r1, [r0]
+
+/******************************************************************************
+ Version Number
+ *****************************************************************************/
+ ldr r0, =0x1e7200a8
+ ldr r1, =0x20141229 @ released date
+ str r1, [r0]
+
+ add r0, r0, #4
+ ldr r1, =0x00000060 @ released SDK version
+ str r1, [r0]
+
+/******************************************************************************
+ Calibration Code End
+ ******************************************************************************/
+
+set_scratch:
+ /*Set Scratch register Bit 6 after ddr initial finished */
+ ldr r0, =0x1e6e2040
+ ldr r1, [r0]
+ orr r1, r1, #0x40
+ str r1, [r0]
+
+/* Debug - UART console message */
+ ldr r0, =0x1e784000
+ mov r1, #0x44 @ 'D'
+ str r1, [r0]
+ mov r1, #0x6F @ 'o'
+ str r1, [r0]
+ mov r1, #0x6E @ 'n'
+ str r1, [r0]
+ mov r1, #0x65 @ 'e'
+ str r1, [r0]
+ mov r1, #0x0D @ '\r'
+ str r1, [r0]
+ mov r1, #0x0A @ '\n'
+ str r1, [r0]
+/* Debug - UART console message */
+
+/******************************************************************************
+ Solve PCIe ASPM issue, only applied to AST2300 series
+ ******************************************************************************/
+ ldr r0, =0x1e6e207c @ Check bounding for AST1150 existence
+ ldr r1, [r0]
+ mov r2, r1, lsr #24
+ cmp r2, #0x01
+ bne platform_exit @ not match AST2300
+ bic r1, r1, #0xFFFFFCFF
+ mov r1, r1, lsr #8
+ cmp r1, #0x02
+ beq platform_exit @ match AST1050
+
+ ldr r0, =0x1e6e2004 @ Disable I2C controller reset
+ ldr r1, [r0]
+ orr r1, r1, #0x04
+ str r1, [r0]
+ bic r1, r1, #0x04
+ str r1, [r0]
+
+ ldr r0, =0x1e78a054 @ Check I2C bus state, if busy then quit
+ ldr r1, [r0]
+ mov r1, r1, lsr #17
+ and r1, r1, #0x03
+ cmp r1, #0x03
+ bne platform_exit
+
+ ldr r0, =0x1e78a040 @ Init I2C1 controller
+ mov r1, #0x01
+ orr r1, r1, r1, lsl #16
+ str r1, [r0]
+
+ ldr r0, =0x1e78a044
+ ldr r1, =0x77776704
+ str r1, [r0]
+
+ mov r1, #0x0
+ ldr r0, =0x1e78a048
+ str r1, [r0]
+ ldr r0, =0x1e78a04c
+ str r1, [r0]
+
+ ldr r0, =0x1e78a050
+ ldr r1, =0xFFFFFFFF
+ str r1, [r0]
+
+ ldr r0, =0x1e78a200 @ Set AST1150 I2C password
+ ldr r1, =0x00A88FA8
+ str r1, [r0]
+
+ ldr r0, =0x1e78a05c
+ ldr r1, =0x00000200 @ Enable buffer mode transfering 3 bytes
+ str r1, [r0]
+
+ ldr r0, =0x1e78a054
+ ldr r1, =0x00000063 @ Fire commmand
+ str r1, [r0]
+
+ ldr r0, =0x1e78a050
+i2c_wait_cmddone_1:
+ ldr r1, [r0]
+ tst r1, #0x38
+ beq i2c_wait_cmddone_1
+ tst r1, #0x2A @ transmit error
+ bne platform_exit2
+ ldr r1, =0xFFFFFFFF
+ str r1, [r0]
+
+ ldr r0, =0x1e78a200 @ Disable ASPM capability
+ ldr r1, =0x04005DA8
+ str r1, [r0]
+
+ ldr r0, =0x1e78a204
+ ldr r1, =0x00000024
+ str r1, [r0]
+
+ ldr r0, =0x1e78a05c
+ ldr r1, =0x00000200 @ Enable buffer mode transfering 3 bytes
+ str r1, [r0]
+
+ ldr r0, =0x1e78a054
+ ldr r1, =0x00000063 @ Fire commmand
+ str r1, [r0]
+
+ ldr r0, =0x1e78a050
+i2c_wait_cmddone_2:
+ ldr r1, [r0]
+ tst r1, #0x38
+ beq i2c_wait_cmddone_2
+ tst r1, #0x2A @ transmit error
+ bne platform_exit2
+ ldr r1, =0xFFFFFFFF
+ str r1, [r0]
+
+platform_exit2:
+ ldr r0, =0x1e78a040 @ Disable I2C1 controller
+ mov r1, #0x00
+ str r1, [r0]
+
+ b platform_exit
+.LTORG
+
+platform_exit:
+#ifdef CONFIG_DRAM_ECC
+ ldr r0, =0x1e6e0004
+ ldr r1, [r0]
+ orr r1, r1, #0x80
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0054
+ ldr r1, =0x05000000 /* ECC protected memory size, default set at 80M */
+ 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 r0, =0x1e6e0070
+ ldr r2, =0x00001000
+ECC_Init_Flag:
+ ldr r1, [r0]
+ tst r1, r2 @ D[12] = 1, Done
+ beq ECC_Init_Flag
+
+ ldr r0, =0x1e6e0070
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0050
+ ldr r1, =0x80000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0050
+ ldr r1, =0x00000000
+ str r1, [r0]
+
+ ldr r0, =0x1e6e0070
+ ldr r1, =0x00000400
+ str r1, [r0]
+#endif
+ ldr r0, =0x1e6e2008 @ Set Video ECLK phase
+ ldr r1, [r0]
+ ldr r2, =0xfffffff3
+ and r1, r1, r2
+ orr r1, r1, #0x08
+ str r1, [r0]
+
+ ldr r0, =0x1e6e2004
+ ldr r1, [r0]
+ ldr r2, =0xFFBFFFFF @ Enable JTAG Master, solve ARM stucked by JTAG issue
+ and r1, r1, r2
+ str r1, [r0]
+
+ ldr r0, =0x1e6e2048 @ Set MAC interface delay timing
+ ldr r1, =0x2255
+ str r1, [r0]
+
+ ldr r0, =0x1e6e2070 @ Set MAC AHB bus clock
+ ldr r1, [r0]
+ mov r2, #0x04 @ Default RMII, set MHCLK = HPLL/10
+ tst r1, #0xC0
+ movne r2, #0x02 @ if RGMII, set MHCLK = HPLL/6
+ ldr r0, =0x1e6e2008
+ ldr r1, [r0]
+ bic r1, r1, #0x00070000
+ orr r1, r1, r2, lsl #16
+ str r1, [r0]
+
+/* Test - DRAM initial time */
+ ldr r0, =0x1e782040
+ ldr r1, [r0]
+ ldr r0, =0xFFFFFFFF
+ sub r1, r0, r1
+ ldr r0, =0x1e72009c
+ str r1, [r0]
+ ldr r0, =0x1e7200a4
+ str r1, [r0]
+ ldr r0, =0x1e782030
+ ldr r1, [r0]
+ bic r1, r1, #0x0000F000
+ str r1, [r0]
+/* Test - DRAM initial time */
+
+/******************************************************************************
+ Reset GPIO registers when watchdog reset
+ ******************************************************************************/
+ ldr r0, =0x1e6e207c @ Check Revision ID
+ ldr r1, [r0]
+ mov r1, r1, lsr #24
+ cmp r1, #0x02
+ bne platform_exit3 @ not match AST2400
+
+ ldr r0, =0x1e6e203c @ Check watchdog reset event
+ ldr r1, [r0]
+ and r1, r1, #0x06
+ cmp r1, #0x0
+ beq platform_exit3 @ no watchdog reset event
+
+ ldr r0, =0x1e6e209c @ Check watchdog GPIO selection
+ ldr r1, [r0]
+ mov r1, r1, lsr #21
+ tst r1, #0x01
+ beq platform_exit3 @ no watchdog reset selection
+
+ ldr r1, =0x00000000 @ clear GPIO register reset by PRST_N
+ ldr r2, =0xFFFFFFFF
+ ldr r0, =0x1e780008
+ str r1, [r0]
+ ldr r0, =0x1e78000c
+ str r1, [r0]
+ ldr r0, =0x1e780010
+ str r1, [r0]
+ ldr r0, =0x1e780014
+ str r1, [r0]
+ ldr r0, =0x1e780018
+ str r2, [r0]
+ ldr r0, =0x1e780028
+ str r1, [r0]
+ ldr r0, =0x1e78002c
+ str r1, [r0]
+ ldr r0, =0x1e780030
+ str r1, [r0]
+ ldr r0, =0x1e780034
+ str r1, [r0]
+ ldr r0, =0x1e780038
+ str r2, [r0]
+ ldr r0, =0x1e780040
+ str r1, [r0]
+ ldr r0, =0x1e780044
+ str r1, [r0]
+ ldr r0, =0x1e780048
+ str r1, [r0]
+ ldr r0, =0x1e78004c
+ str r1, [r0]
+ ldr r0, =0x1e780050
+ str r1, [r0]
+ ldr r0, =0x1e780054
+ str r1, [r0]
+ ldr r0, =0x1e780058
+ str r1, [r0]
+ ldr r0, =0x1e780060
+ str r1, [r0]
+ ldr r0, =0x1e780064
+ str r1, [r0]
+ ldr r0, =0x1e780068
+ str r1, [r0]
+ ldr r0, =0x1e78006c
+ str r1, [r0]
+ ldr r0, =0x1e780090
+ str r1, [r0]
+ ldr r0, =0x1e780094
+ str r1, [r0]
+ ldr r0, =0x1e780098
+ str r1, [r0]
+ ldr r0, =0x1e78009c
+ str r1, [r0]
+ ldr r0, =0x1e7800a0
+ str r1, [r0]
+ ldr r0, =0x1e7800a4
+ str r1, [r0]
+ ldr r0, =0x1e7800a8
+ str r2, [r0]
+ ldr r0, =0x1e7800b0
+ str r1, [r0]
+ ldr r0, =0x1e7800b4
+ str r1, [r0]
+ ldr r0, =0x1e7800b8
+ str r1, [r0]
+ ldr r0, =0x1e7800e0
+ str r1, [r0]
+ ldr r0, =0x1e7800e4
+ str r1, [r0]
+ ldr r0, =0x1e7800e8
+ str r1, [r0]
+ ldr r0, =0x1e7800ec
+ str r1, [r0]
+ ldr r0, =0x1e7800f0
+ str r1, [r0]
+ ldr r0, =0x1e7800f4
+ str r1, [r0]
+ ldr r0, =0x1e7800f8
+ str r2, [r0]
+ ldr r0, =0x1e780100
+ str r1, [r0]
+ ldr r0, =0x1e780104
+ str r1, [r0]
+ ldr r0, =0x1e780108
+ str r1, [r0]
+ ldr r0, =0x1e780110
+ str r1, [r0]
+ ldr r0, =0x1e780114
+ str r1, [r0]
+ ldr r0, =0x1e780118
+ str r1, [r0]
+ ldr r0, =0x1e78011c
+ str r1, [r0]
+ ldr r0, =0x1e780120
+ str r1, [r0]
+ ldr r0, =0x1e780124
+ str r1, [r0]
+ ldr r0, =0x1e780128
+ str r2, [r0]
+ ldr r0, =0x1e780130
+ str r1, [r0]
+ ldr r0, =0x1e780134
+ str r1, [r0]
+ ldr r0, =0x1e780138
+ str r1, [r0]
+ ldr r0, =0x1e780140
+ str r1, [r0]
+ ldr r0, =0x1e780144
+ str r1, [r0]
+ ldr r0, =0x1e780148
+ str r1, [r0]
+ ldr r0, =0x1e78014c
+ str r1, [r0]
+ ldr r0, =0x1e780150
+ str r1, [r0]
+ ldr r0, =0x1e780154
+ str r1, [r0]
+ ldr r0, =0x1e780158
+ str r2, [r0]
+ ldr r0, =0x1e780160
+ str r1, [r0]
+ ldr r0, =0x1e780164
+ str r1, [r0]
+ ldr r0, =0x1e780168
+ str r1, [r0]
+ ldr r0, =0x1e780170
+ str r1, [r0]
+ ldr r0, =0x1e780174
+ str r1, [r0]
+ ldr r0, =0x1e780178
+ str r1, [r0]
+ ldr r0, =0x1e78017c
+ str r1, [r0]
+ ldr r0, =0x1e780180
+ str r1, [r0]
+ ldr r0, =0x1e780184
+ str r1, [r0]
+ ldr r0, =0x1e780188
+ str r2, [r0]
+ ldr r0, =0x1e780190
+ str r1, [r0]
+ ldr r0, =0x1e780194
+ str r1, [r0]
+ ldr r0, =0x1e780198
+ str r1, [r0]
+ ldr r0, =0x1e7801d0
+ str r1, [r0]
+ ldr r0, =0x1e7801d4
+ str r1, [r0]
+
+ ldr r0, =0x1e780204 @ clear SGPIOM register reset by PRST_N
+ str r1, [r0]
+ ldr r0, =0x1e780208
+ str r1, [r0]
+ ldr r0, =0x1e78020c
+ str r1, [r0]
+ ldr r0, =0x1e780210
+ str r1, [r0]
+ ldr r0, =0x1e780214
+ str r2, [r0]
+ ldr r0, =0x1e780220
+ str r1, [r0]
+ ldr r0, =0x1e780224
+ str r1, [r0]
+ ldr r0, =0x1e780228
+ str r1, [r0]
+ ldr r0, =0x1e78022c
+ str r1, [r0]
+ ldr r0, =0x1e780230
+ str r2, [r0]
+ ldr r0, =0x1e78023c
+ str r1, [r0]
+ ldr r0, =0x1e780240
+ str r1, [r0]
+ ldr r0, =0x1e780244
+ str r1, [r0]
+ ldr r0, =0x1e780248
+ str r1, [r0]
+ ldr r0, =0x1e78024c
+ str r2, [r0]
+ ldr r0, =0x1e780254
+ ldr r3, =0x01000040
+ str r3, [r0]
+ ldr r0, =0x1e780258
+ str r1, [r0]
+ ldr r0, =0x1e78025c
+ str r1, [r0]
+ ldr r0, =0x1e780260
+ str r1, [r0]
+
+ ldr r0, =0x1e780300 @ clear SGPIOS register reset by PRST_N
+ str r1, [r0]
+ ldr r0, =0x1e780304
+ str r1, [r0]
+ ldr r0, =0x1e780308
+ str r1, [r0]
+ ldr r0, =0x1e78030c
+ str r1, [r0]
+ ldr r0, =0x1e780310
+ str r1, [r0]
+ ldr r0, =0x1e780314
+ str r1, [r0]
+ ldr r0, =0x1e780318
+ str r2, [r0]
+ ldr r0, =0x1e78031c
+ str r2, [r0]
+ ldr r0, =0x1e780320
+ str r2, [r0]
+
+platform_exit3:
+
+/******************************************************************************
+ SPI Timing Calibration, not applicable to AST2300 series
+ ******************************************************************************/
+ ldr r0, =0x1e6e207c @ Check Revision ID
+ ldr r1, [r0]
+ mov r1, r1, lsr #24
+ cmp r1, #0x02
+ blt platform_exit4 @ not match AST2400 or later
+
+ ldr r0, =0x1e6e2070 @ Check SPI flash
+ ldr r1, [r0]
+ and r1, r1, #0x03
+ cmp r1, #0x02
+ bne platform_exit4
+
+ mov r2, #0x0
+ mov r6, #0x0
+ mov r7, #0x0
+ init_spi_checksum
+spi_checksum_wait_0:
+ ldr r1, [r0]
+ tst r1, r2
+ beq spi_checksum_wait_0
+ ldr r0, =0x1e620090
+ ldr r5, [r0] @ record golden checksum
+ ldr r0, =0x1e620080
+ mov r1, #0x0
+ str r1, [r0]
+
+ ldr r0, =0x1e620010 @ set to fast read mode
+ ldr r1, =0x000B0041
+ str r1, [r0]
+
+ ldr r6, =0x00F7E6D0 @ Init spiclk loop
+ mov r8, #0x0 @ Init delay record
+
+spi_cbr_next_clkrate:
+ mov r6, r6, lsr #0x4
+ cmp r6, #0x0
+ beq spi_cbr_end
+
+ mov r7, #0x0 @ Init delay loop
+ mov r8, r8, lsl #4
+
+spi_cbr_next_delay_s:
+ mov r2, #0x8
+ init_spi_checksum
+spi_checksum_wait_1:
+ ldr r1, [r0]
+ tst r1, r2
+ beq spi_checksum_wait_1
+ ldr r0, =0x1e620090
+ ldr r2, [r0] @ read checksum
+ ldr r0, =0x1e620080
+ mov r1, #0x0
+ str r1, [r0]
+ cmp r2, r5
+ bne spi_cbr_next_delay_e
+
+ mov r2, #0x0
+ init_spi_checksum
+spi_checksum_wait_2:
+ ldr r1, [r0]
+ tst r1, r2
+ beq spi_checksum_wait_2
+ ldr r0, =0x1e620090
+ ldr r2, [r0] @ read checksum
+ ldr r0, =0x1e620080
+ mov r1, #0x0
+ str r1, [r0]
+ cmp r2, r5
+ bne spi_cbr_next_delay_e
+
+ orr r8, r8, r7 @ record passed delay
+ b spi_cbr_next_clkrate
+
+spi_cbr_next_delay_e:
+ add r7, r7, #0x1
+ cmp r7, #0x6
+ blt spi_cbr_next_delay_s
+ b spi_cbr_next_clkrate
+
+spi_cbr_end:
+ ldr r0, =0x1e620094
+ str r8, [r0]
+ ldr r0, =0x1e620010
+ mov r1, #0x0
+ str r1, [r0]
+
+platform_exit4:
+
+ /* restore lr */
+ mov lr, r4
+
+ /* back to arch calling code */
+ mov pc, lr