📄 xlli_lowlev_init.s
字号:
; Note: Synchronous Flash is handled in a separate xlli Function
;
;
; ***** STEP 3 *****
;
; Clear the free run clock bits to enable the use of SDCLK for memory timing
;
bic r2, r2, #(xlli_MDREFR_K2FREE :OR: xlli_MDREFR_K1FREE :OR: xlli_MDREFR_K0FREE)
;
; set K1RUN if bank 0 installed
;
orr r2, r2, #xlli_MDREFR_K1RUN ; Enable SDCLK[1]
bic r2, r2, #xlli_MDREFR_K2DB2 ; Clear K2DB2
str r2, [r4, #xlli_MDREFR_offset] ; write updated MDREFR
ldr r2, [r4, #xlli_MDREFR_offset] ; read back
bic r2, r2, #xlli_MDREFR_SLFRSH ; Disable self refresh
str r2, [r4, #xlli_MDREFR_offset] ; write updated MDREFR
ldr r2, [r4, #xlli_MDREFR_offset] ; read back
orr r2, r2, #xlli_MDREFR_E1PIN ; Assert E1PIN to enable SDCKE[1]
str r2, [r4, #xlli_MDREFR_offset] ; write updated MDREFR (finished with value in r2)
ldr r2, [r4, #xlli_MDREFR_offset] ; read back
nop ; Do not remove!
nop ; Do not remove!
;
; ***** STEP 4 *****
;
; Appropriately configure, but don't enable, each SDRAM partition pair
;
ldr r1, =xlli_MDCNFG_value ; Fetch platform value for MDCNFG
bic r1, r1, #(xlli_MDCNFG_DE0 :OR: xlli_MDCNFG_DE1) ; Disable all
bic r1, r1, #(xlli_MDCNFG_DE2 :OR: xlli_MDCNFG_DE3) ; SDRAM banks
;
; Check for conditional def for 32 vs 16 bit bus width
;
IF :DEF: xlli_SDRAM_WIDTH_16_BIT ; Set bus width to 16 bits?
orr r1, r1, #xlli_MDCNFG_DWID0 ; Set banks 0/1 for 16 bit width
ELSE
bic r1, r1, #xlli_MDCNFG_DWID0 ; Set banks 0/1 for 32 bit width
ENDIF
str r1, [r4, #xlli_MDCNFG_offset] ; Write w/o enabling SDRAM banks
;
; ***** STEP 5 ***** (Delay at least 200 uS)
;
ldr r2, =xlli_OSTREGS_PHYSICAL_BASE ; Load OS timer base address
ldr r3, [r2, #xlli_OSCR0_offset] ; Fetch starting value of OSCR0
add r3, r3, #0x300 ; Really 0x2E1 is about 200usec, so 0x300 should be plenty
;hzh, masked for emulation
xlli_5 ldr r1, [r2, #xlli_OSCR0_offset] ; Fetch current OSCR0 value
cmp r1, r3 ; Is the timer past the time out value?
bmi xlli_5 ; No - Loop until it is
;
; ***** STEP 6 ***** (Make sure DCACHE is disabled)
;
mrc p15, 0, r2, c1, c0, 0 ; load r2 contents of register 1 in CP 15
bic r2, r2, #xlli_CONTROL_DCACHE ; Disable D-Cache
mcr p15, 0, r2, c1, c0, 0 ; Write back to CP15
;
; ***** STEP 7 *****
;
; Access memory *not yet enabled* for CBR refresh cycles (8)
; - CBR is generated for all banks
;
ldr r1, =xlli_SDRAM_PHYSICAL_BASE
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1] ; Fix for erratum #116. Makes up for ineffective 1st mem access.
; This is being left in for PXA27x for the moment
;
; ***** STEP 8 *****
;
; Re-enable D-cache if desired (we don't)
;
; ***** STEP 9 *****
;
; Re-enable SDRAM partitions
;
ldr r2, [r4, #xlli_MDCNFG_offset] ; Fetch the current MDCNFG value
orr r2, r2, #xlli_MDCNFG_DE0 ; Enable SDRAM bank 0
str r2, [r4, #xlli_MDCNFG_offset] ; Write back MDCNFG, enabling the SDRAM bank(s)
;
; ***** STEP 10 *****
;
; Write the MDMRS register to trigger an MRS command to all enabled banks of SDRAM.
;
;
ldr r1, =xlli_MDMRS_value ; Fetch platform MDMRS value
str r1, [r4, #xlli_MDMRS_offset] ; Write the MDMRS value back
;
; ***** STEP 11 *****
;
; In systems with SDRAM or Synchronous Flash, optionally enable auto-power-down by setting MDREFR:APD
;
ldr r3, [r4, #xlli_MDREFR_offset] ; Get MDREFR value
orr r3, r3, #xlli_MDREFR_APD ; enable auto power down
str r3, [r4, #xlli_MDREFR_offset] ; Write value back
mov pc, lr ; return to calling routine
ENDFUNC
LTORG
;********************************************************************************************
;
; ***********************************************
; ********** **********
; ********** RESTART MEMORY CONTROLLER **********
; ********** **********
; ***********************************************
;
; This command restarts the memory controller and should be called after a frequency change sequence
; or when memory controller settings have been changed (such as xlli_mem_Tmax and xlli_memTopt).
;
xlli_mem_restart FUNCTION
ldr r4, =xlli_MEMORY_CONFIG_BASE ; Get memory controller base address
ldr r2, [r4, #xlli_MDREFR_offset] ; Get MDREFR value
bic r3, r2, #xlli_MDREFR_E0PIN ; Clear E0PIN to disable SDCKE[0]
bic r3, r3, #xlli_MDREFR_E1PIN ; Clear E1PIN to disable SDCKE[1]
b xlli_5A
;
; The next line should start on a cache line boundary so we don't accidently hang the system
;
ALIGN 32
xlli_5A str r3, [r4, #xlli_MDREFR_offset] ; Write value back with E0PIN and E1PIN cleared
str r2, [r4, #xlli_MDREFR_offset] ; Write value back with E0PIN and E1PIN set
;
; Disable all SDRAM banks
;
ldr r1, [r4, #xlli_MDCNFG_offset] ; Fetch platform value for MDCNFG
bic r1, r1, #(xlli_MDCNFG_DE0 :OR: xlli_MDCNFG_DE1) ; Disable all
bic r1, r1, #(xlli_MDCNFG_DE2 :OR: xlli_MDCNFG_DE3) ; SDRAM banks
str r1, [r4, #xlli_MDCNFG_offset] ; Write w/o enabling SDRAM banks
;
; Access memory *not yet enabled* for CBR refresh cycles (8)
; - CBR is generated for all banks
;
ldr r1, =xlli_SDRAM_PHYSICAL_BASE
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1]
str r1, [r1] ; Fix for erratum #116. Makes up for ineffective 1st mem access.
; This is being left in for PXA27x for the moment
;
; Re-enable SDRAM partition(s)
;
ldr r2, [r4, #xlli_MDCNFG_offset] ; Fetch the current MDCNFG value
orr r2, r2, #xlli_MDCNFG_DE0 ; Enable SDRAM bank 0
str r2, [r4, #xlli_MDCNFG_offset] ; Write back MDCNFG, enabling the SDRAM bank(s)
;
; Write the MDMRS register to trigger an MRS command to all enabled banks of SDRAM.
;
;
ldr r1, [r4, #xlli_MDMRS_offset] ; Fetch platform MDMRS value
str r1, [r4, #xlli_MDMRS_offset] ; Write the MDMRS value back
;
ldr r3, [r4, #xlli_MDREFR_offset] ; Get MDREFR value
str r3, [r4, #xlli_MDREFR_offset] ; Write value back
mov pc, lr ; return to calling routine
ENDFUNC
;********************************************************************************************
;
; ********************************************************
; ********** **********
; ********** MAXIMIZE MEMORY CONTROLLER VALUES **********
; ********** **********
; ********************************************************
;
; NOTE: This function maximizes the timing values in the memory controller so the frequency change
; sequence can be done safely without the risk of a system hang. Once the frequency change
; sequence is complete, xlli__mem_Topt may be called to set the optimal timing values.
;
; This function does not need to be called if the new MemClk frequency is going to be higher
; than the present MemClk frequency. However, the overhead of this function is minimal so
; it is suggested this function be called before any change frequency sequence.
;
; r1, r2, and r3 are used and not preserved.
;
xlli_mem_Tmax FUNCTION
ldr r1, =xlli_MEMORY_CONFIG_BASE ; Get memory controller base address
ldr r3, =0x7FF07FF0 ; Maximize bits for RDF, RDN and RRR
;
ldr r2, [r1, #xlli_MSC0_offset] ; Get MSC0 value
orr r2, r2, r3 ; Set all the RDF, RDN and RRR bits
str r2, [r1, #xlli_MSC0_offset] ; Set the new MSC0 value
ldr r2, [r1, #xlli_MSC0_offset] ; Read MSC0 value back to lock the values
;
ldr r2, [r1, #xlli_MSC1_offset] ; Get MSC1 value
orr r2, r2, r3 ; Set all the RDF, RDN and RRR bits
str r2, [r1, #xlli_MSC1_offset] ; Set the new MSC1 value
ldr r2, [r1, #xlli_MSC1_offset] ; Read MSC1 value back to lock the values
;
ldr r2, [r1, #xlli_MSC2_offset] ; Get MSC2 value
orr r2, r2, r3 ; Set all the RDF, RDN and RRR bits
str r2, [r1, #xlli_MSC2_offset] ; Set the new MSC2 value
ldr r2, [r1, #xlli_MSC2_offset] ; Read MSC2 value back to lock the values
;
ldr r3, =0x03000300 ; Set up mask bits for DTC0 and DTC2
ldr r2, [r1, #xlli_MDCNFG_offset] ; Get present MDCNFG value
orr r2, r2, r3 ; Clear the DTC0 and DTC2 bits
str r2, [r1, #xlli_MDCNFG_offset] ; Write back the MDCNFG value
;
ldr r3, =0xFFF ; Set up mask bits for DRI value
ldr r2, [r1, #xlli_MDREFR_offset] ; Get present MDREFR value
bic r2, r2, r3 ; Clear all the DRI bits
orr r2, r2, #0x13 ; Set to lowest safe value
str r2, [r1, #xlli_MDREFR_offset] ; Write back the MDREFR value
mov pc, lr ; return to calling routine
ENDFUNC
;********************************************************************************************
;
; ***********************************************************
; ********** **********
; ********** SET OPTIMAL MEMORY CONTROLLER VALUES **********
; ********** **********
; ***********************************************************
;
; NOTE: This function sets the TIMING values in the memory controller to the optimum values based on
; the frequency of the MemClk. This function should be called AFTER the frequency change
; sequence is complete to get optimal performance out of the memory system.
;
; If changing the core frequency to a value that increases the MemClk speed, it is strongly
; suggested that xlli_MSCx_max be called before the frequency change sequence. Once the
; frequency chage sequence is complete, this routine may be called to reset the optimal
; values for the memory system and the memory controller restarted.
;
; r1 through r8 are used and not preserved.
;
xlli_mem_Topt FUNCTION
ldr r1, =xlli_CLKREGS_PHYSICAL_BASE ; Get base address of clock registers
ldr r2, [r1, #xlli_CCSR_offset] ; Get current clock status
and r2, r2, #0x1F ; r2 now contains the CCSR L value
ldr r3, [r1, #xlli_CCCR_offset] ; Get the current CCCR for the "A" bit
and r3, r3, #xlli_CCCR_A_Bit_Mask
mov r3, r3, LSR #0x19 ; Move down to bit position 0 to make comparison easy (LSL by 25)
;
; Check for the "B" bit from CCCR (CP14,R6)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -