📄 pmgr1110.s
字号:
ldr r0, [r1, #MDREFR_OFFSET]
ldr r7, =0xffff000f ; clear DRI field in MDREFR
and r0, r0, r7 ; clear DRI to stop CBR
orr r8, r0, #0x80000000 ; set SLFRSH bit
ldr r7, =0x7fefffff ; clear SLFRSH and E1PIN bits in MDREFR
and r11, r0, r7 ; clear SLFRSH and E1PIN bits
ldr r9, [r1, #MDCNFG_OFFSET]
and r9, r9, r3 ; clear DE bits
ldr r2, =PMC_BASE_VIRTUAL
mov r3, #PMCR_SLEEP ; Force sleep entry
;------------------------------------------------------------------------
; At this point the registers contain the following:
; r0 - MDREFR image to stop CBR
; r1 - Memory controller base
; r2 - Power controller base address
; r3 - PMCR final value
; r4 - MSC0 disable image
; r5 - MSC1 disable image
; r6 - MSC2 disable image
; r7 - Open
; r8 - MDREFR image to force self refresh
; r9 - MDCNFG final image to disable SDRAM
; r10 - Open
; r11 - Final MDREFR image
; r12 - r14 Open
IF :DEF: TEST_PRESTOP_CBR
;------------------------------------------------------------------------
; We need to stop CBR in advance and wait for the last possibly pending
; CBR. We can't really avoid the delay since the request may already be
; pending when we get here. We can not risk hitting the CBR in the final
; shutdown.
IF :DEF: TEST_TRACE_GPIO
ldr r12, =GPIO_BASE_VIRTUAL
mov r13, #TEST_GPIO_BIT
str r13, [r12, #GPSR_OFFSET] ; Set to mark start
ENDIF ; TEST_TRACE_GPIO
str r0, [r1, #MDREFR_OFFSET] ; Stop CBR
mov r12, #1056 ; Delay 16us (max refresh time)
88 subs r12,r12,#1
bne %B88
IF :DEF: TEST_TRACE_GPIO
ldr r12, =GPIO_BASE_VIRTUAL
mov r13, #TEST_GPIO_BIT
str r13, [r12, #GPCR_OFFSET] ; Set to mark end
ENDIF ; TEST_TRACE_GPIO
ENDIF ; TEST_PRESTOP_CBR
IF :DEF: TEST_DMA_SYNC
;------------------------------------------------------------------------
; The basic idea here is to sync with the still running DMA. We wait for
; the DMA burst and then run the final shutdown. Since we know the DMA
; at the LCD controller is off we time out to avoid the end of frame
; gap. This leaves the fastest possible path thru the DMA minefield.
; The timeout needs to be longer than the end of line delay.
bl LoadFinalShutdown ; Preload final IC blocks
; Set the GPIO pin to indicate we are here.
IF :DEF: TEST_TRACE_GPIO
ldr r12, =GPIO_BASE_VIRTUAL
mov r13, #TEST_GPIO_BIT
str r13, [r12, #GPSR_OFFSET] ; Set to mark start
ENDIF ; TEST_TRACE_GPIO
ldr r12, =LCD_BASE_VIRTUAL
ldr r13, [r12,#DCAR1_OFFSET] ; Read DCAR1 and wait for change
mov r7, #120 ; 10 us (tuned for loop below)
89 ldr r14, [r12,#DCAR1_OFFSET]
subs r7, r7, #1
beq %F899 ; Timeout
cmp r13, r14
beq %B89
899
mov r7, #15
;------------------------------------------------------------------------
; From this point on we are running in the inter-DMA gap. PLEASE BE BRIEF ...
; IF :DEF: TEST_TRACE_GPIO
; If is suspected that this GPIO write actually synchronizes with
; the DMA when it arbs for the system bus. Removing it causes
; serious failures.
ldr r12, =GPIO_BASE_VIRTUAL
mov r13, #TEST_GPIO_BIT
str r13, [r12, #GPCR_OFFSET] ; Set to mark end.
; ENDIF ; TEST_TRACE_GPIO
b FinalShutdown ; And now for the final act ...
ENDIF ; TEST_DMA_SYNC
bl LoadFinalShutdown
b FinalShutdown
;------------------------------------------------------------------------
; This is the final step in the shutdown. This code needes to be
; executed from the I-cache. It will disable all memory references, force
; self-refresh and enter sleep mode.
; The following technique will load the two blocks in the I-cache
; by folling the initial jump path. The code then continues on the
; second thread thru the blocks executing instructions just loaded
; in the cache. - Evans
ALIGN 32
;------------------------------------------------------------------------
; Block 0 load entry
LoadFinalShutdown
b %F60 ; Link to next in preload chain
;------------------------------------------------------------------------
; Block 0 exectution entry
FinalShutdown
str r4, [r1, #MSC0_OFFSET] ; Stop burst flash cycle
str r5, [r1, #MSC1_OFFSET]
str r6, [r1, #MSC2_OFFSET]
str r0, [r1, #MDREFR_OFFSET] ; Stop CBR
nop
str r8, [r1, #MDREFR_OFFSET] ; Start Self-refresh
b %F61
ALIGN 32
;------------------------------------------------------------------------
; Block 1 load entry
60 mov pc,lr ; End of preload chain, return to caller
;------------------------------------------------------------------------
; Block 1 exectution entry
61 str r9, [r1, #MDCNFG_OFFSET]
;mov r7, #15 ; Delay to give controller time
62 ;subs r7,r7,#1
;bne %B62
str r11, [r1, #MDREFR_OFFSET] ; Stop Self-refresh
str r3, [r2, #PMCR_OFFSET] ; Enter sleep - done
;------------------------------------------------------------------------
; We are now down (and should never get here ...)
80
b %B80 ; don't let it fall through
;------------------------------------------------------------------------
; We return here from RESET after doing the wakeup processing. We are
; in virtual mode. This is the address saved in the SLEEPDATA area.
Awake_address
ldr r3, =SLEEPDATA_BASE_VIRTUAL ; Sleep mode information data structure
ldr r0, =GPIO_BASE_VIRTUAL
add r2, r3, #SleepState_GAFR
ldr r1, [r2], #4
str r1, [r0, #GAFR_OFFSET]
ldr r1, [r2], #4
str r1, [r0, #GFER_OFFSET]
ldr r1, [r2], #4
str r1, [r0, #GRER_OFFSET]
ldr r0, =OSC_BASE_VIRTUAL
add r2, r3, #SleepState_OSMR0
ldr r1, [r2], #4
str r1, [r0], #4 ; OSMR0
ldr r1, [r2], #4
str r1, [r0], #4 ; OSMR1
ldr r1, [r2], #4
str r1, [r0], #4 ; OSMR2
ldr r1, [r2], #4
str r1, [r0], #4 ; OSMR3
ldr r1, [r2], #4
str r1, [r0], #4 ; OSCR
ldr r1, [r2], #4
str r1, [r0], #4 ; OSSR
ldr r1, [r2], #4
str r1, [r0], #4 ; OWER
ldr r1, [r2], #4
str r1, [r0], #4 ; OIER
ldr r0, =RTC_BASE_VIRTUAL
add r2, r3, #SleepState_RTTR
ldr r1, [r2], #4
str r1, [r0, #RTTR_OFFSET]
;ldr r1, [r2]
;str r1, [r0, #RTSR_OFFSET]
ldr r0, =PPAR_VIRTUAL
mov r1, #0x40000 ; SPR sets UART 4 to default to MCP operation
str r1, [r0]
; SA1110 Dev Board UART1 does not use alternate functions
; set up the SDLC controller and clear sticky bits
ldr r0,=SDSR1_VIRTUAL
mov r1, #0x10
str r1, [r0]
ldr r0,=SDSR0_VIRTUAL
mov r1, #0x6
str r1, [r0]
ldr r0,=SDCR0_VIRTUAL
mov r1, #0x1 ; Sus allows normal serial operation
str r1, [r0]
IF DEBUG_UART = "3"
ldr r0, =UART3_BASE_VIRTUAL
ELSE
ldr r0, =UART1_BASE_VIRTUAL
ENDIF
ldr r1, =0x8
str r1, [r0, #UTCR0_OFFSET]
ldr r1, =0x0
str r1, [r0, #UTCR1_OFFSET]
ldr r1, =0x5 ; 0x17: 9600, 0x0b: 19200, 0x05: 38400 baud
str r1, [r0, #UTCR2_OFFSET]
;mov r1, #0x1C
;str r1, [r0, #UTSR0_OFFSET] ; clear sticky bits See SA-1110 UG pg 11-140
ldr r1, =0x3 ; TX/RX enable, no interrupts
str r1, [r0, #UTCR3_OFFSET]
IF EBOOT = "0"
ldr r0,=DRIVER_GLOBALS_BCRSHADOW_VIRTUAL ; restore SA1110DB Board configuration register
ldr r1,=BCR_SETUPVAL1 ; no daughter card, force RS232 tranceiver, red LED off, grn on
str r1, [r0]
ldr r0,=SA1110DB_BCR_U_VIRTUAL
str r1, [r0]
ENDIF
IF _SA1111 = "1"
IF EBOOT = "0"
;*********** the following are specific to the SA-11x1
ldr r0,=SA1110DB_BCR_U_VIRTUAL
ldr r1,=BCR_SETUPVAL2 ; red LED on, grn off we've got a SA-1111 DC
str r1,[r0] ; SA-1110 bd RS232 tranceiver it will fight with the SA-1111BD's
ENDIF
ldr r0,=SKCR_VIRTUAL ; perform a read to the SKCR to wake up the SA-1111
ldr r1, [r0]
ldr r0,=SKCR_VIRTUAL ; Turn on the PLL, enable Ready and enable nOE assertion from DC
ldr r1,=SKCR_INIT ; defined in SA11X1.inc
str r1,[r0]
mov r0,#0x80000
80 subs r0,r0,#1 ; wait for PLL to settle
bne %b80
ldr r0,=SKCR_VIRTUAL ; turn on the RCLOCK
ldr r1,=SKCR_RCLK ; defined in SA11X1.inc
str r1,[r0]
ldr r0,=SKINTENABL0_VIRTUAL
mov r1, #0 ; Disable interrupts on DC
str r1, [r0]
ldr r0,=SKINTENABL1_VIRTUAL
mov r1, #0 ; Disable interrupts on DC
;ldr r1, =BIT11
str r1, [r0]
ldr r0,=SKINTSTCLR0_VIRTUAL
ldr r1,=0xFFFFFFFF ; Clear SA-1101 system interrupt sources reg 0
str r1, [r0]
ldr r0,=SKINTSTCLR1_VIRTUAL
ldr r1,=0xFFFFFFFF ; Clear SA-1101 system interrupt sources reg 1
str r1, [r0]
;********** end of SA-1101 specific code
ENDIF
ldr r0, =IC_BASE_VIRTUAL
mov r1, #0
str r1, [r0, #ICCR_OFFSET] ; All interrupts bring the SA-1110 out of idle
str r1, [r0, #ICLR_OFFSET]
add r2, r3, #SleepState_FIQ_SPSR
mov r1, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; Enter FIQ mode, no interrupts
msr cpsr, r1
ldr r0, [r2], #4
msr spsr, r0
ldr r8, [r2], #4
ldr r9, [r2], #4
ldr r10, [r2], #4
ldr r11, [r2], #4
ldr r12, [r2], #4
ldr sp, [r2], #4
ldr lr, [r2], #4
mov r1, #Mode_ABT:OR:I_Bit:OR:F_Bit ; Enter ABT mode, no interrupts
msr cpsr, r1
ldr r0, [r2], #4
msr spsr, r0
ldr sp, [r2], #4
ldr lr, [r2], #4
mov r1, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; Enter IRQ mode, no interrupts
msr cpsr, r1
ldr r0, [r2], #4
msr spsr, r0
ldr sp, [r2], #4
ldr lr, [r2], #4
mov r1, #Mode_UND:OR:I_Bit:OR:F_Bit ; Enter UND mode, no interrupts
msr cpsr, r1
ldr r0, [r2], #4
msr spsr, r0
ldr sp, [r2], #4
ldr lr, [r2], #4
mov r1, #Mode_SYS:OR:I_Bit:OR:F_Bit ; Enter SYS mode, no interrupts
msr cpsr, r1
ldr sp, [r2], #4
ldr lr, [r2]
mov r1, #Mode_SVC:OR:I_Bit:OR:F_Bit ; Enter SVC mode, no interrupts
msr cpsr, r1
ldr r0, [r3, #SleepState_SVC_SPSR]
msr spsr, r0
ldr sp, [r3, #SleepState_SVC_SP]
ldr r0, =IC_BASE_VIRTUAL ; Restore SA-1110 Interrupt Mask
ldr r1, [r3, #SleepState_ICMR]
str r1, [r0, #ICMR_OFFSET]
mov r1, #1
str r1, [r0, #ICCR_OFFSET] ; only unmasked interrupts can bring the SA-1110 out of idle
ldr r0, =GPIO_BASE_VIRTUAL
ldr r1, =0xFFFFFFFF ; Clear SA-1110 system interrupt sources
str r1, [r0, #GEDR_OFFSET]
ldr lr, [sp], #4
ldmia sp!, {r4-r12}
mov pc, lr ; and now back to our sponsors
AREA | .Idlearea |, CODE READONLY, ALIGN=5
;
; OEMIdle - system idle
;
; This routine is called by the kernel when there are no threads ready to
; run. The CPU should be put into a reduced power mode and halted.
; It is important to be able to resume execution quickly upon receiving
; an interrupt.
;
; NOTE: Exceptions are blocked when this routine is called and must not
; be reenabled unless the functions is going to return immediately.
;
; Entry Interrupts disabled
; Exit none
; Uses r0-r1
;LEAF_ENTRY OEMIdle
; LEAF_ENTRY CPUEnterIdle
;
; ldr r1, =0xA8000000 ; just an arbitrary uncachable location
; mcr p15, 0, r0, c15, c2, 2 ; disable clock switching
; ldr r0, [r1]
; mcr p15, 0, r0, c15, c8, 2 ; go idle
; nop
; nop
; mcr p15, 0, r0, c15, c1, 2 ; (re)enable clock switching
;
; mov pc, lr ; return
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -