[openfirmware] [commit] r2527 - cpu/arm/mmp2 dev/olpc/dcon
repository service
svn at openfirmware.info
Fri Sep 23 06:59:53 CEST 2011
Author: wmb
Date: Fri Sep 23 06:59:53 2011
New Revision: 2527
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2527
Log:
OLPC XO-1.75 - Stabilizing suspend/resume.
Modified:
cpu/arm/mmp2/dramrecal.fth
cpu/arm/mmp2/rtc.fth
dev/olpc/dcon/mmp2dcon.fth
Modified: cpu/arm/mmp2/dramrecal.fth
==============================================================================
--- cpu/arm/mmp2/dramrecal.fth Fri Sep 23 00:42:26 2011 (r2526)
+++ cpu/arm/mmp2/dramrecal.fth Fri Sep 23 06:59:53 2011 (r2527)
@@ -59,6 +59,10 @@
here ddr-recal - constant /ddr-recal
label ddr-self-refresh ( r0:memctrl-va -- )
+ dsb
+ mcr p15,0,r0,cr8,cr5,0 \ Invalidate TLB
+ mcr p15,0,r0,cr7,cr10,4 \ Write data synchronization barrier
+
mov r1, #0x1 \ Block all data requests
str r1, [r0, #0x7e0] \ SDRAM_CTRL14
@@ -73,14 +77,17 @@
\ str r1, [r0, #0x770] \ SDRAM_CTRL7_SDRAM_ODT_CTRL2
\ Store registers in SRAM so CForth can see them, for debugging
-\ set r2, #0xd102.0400
-\ stmia r2, {r0-r15}
+ set r2, #0xd102.0400
+ stmia r2, {r0-r15}
\ Linux sets the register to 0x860
ldr r1, [r0, #0x1e0] \ PHY_CTRL8
bic r1,r1,#0x07700000 \ PHY_ADCM_ZPDRV: 0 PHY_ADCM_ZNDRV: 0 (Disable drivers 6:0)
str r1, [r0, #0x1e0] \ PHY_CTRL8
+\ mov r1, #0x00070000 \ PHY_SYNC_EN
+\ str r1, [r0, #0x110] \ MMAP_CS1
+
dsb \ Data Synchronization Barrier
wfi \ Wait for interrupt
@@ -295,13 +302,305 @@
\ WAKEUP6: SDH1_CD, SDH3_CD, MSP_INS
\ WAKEUP7: PMIC INT
5 value sleep-depth
-: setup-wakeup-sources ( -- mask )
- h# 0002.0094 h# 4c mpmu! \ RTC_ALARM, WAKEUP7, WAKEUP4, WAKEUP2
-\ h# 0002.0094 h# 104c mpmu! \ RTC_ALARM, WAKEUP7, WAKEUP4, WAKEUP2 ???
+: setup-wakeup-sources ( -- mask )
+\ h# 0002.0094 h# 4c mpmu! \ RTC_ALARM, WAKEUP7, WAKEUP4, WAKEUP2
+\ h# 0002.0094 h# 104c mpmu! \ RTC_ALARM, WAKEUP7, WAKEUP4, WAKEUP2
h# ff08.7fff ( mask ) \ Enable all wakeup ports
;
: block-irqs ( -- ) 1 h# 110 +icu io! ;
+\ XXX we might need to set GPIOs 71 and 160 (ps2 clocks), and perhaps the dat lines too,
+\ for non-sleep-mode control - or maybe for sleep mode control as inputs.
+\ We also may need to enable falling edge detects.
+: disable-int40 ( -- ) d# 40 disable-interrupt ;
+
+: gpio-wakeup? ( gpio# -- flag )
+ h# 019800 over 5 rshift la+ l@ ( gpio# mask )
+ swap h# 1f and ( mask bit# )
+ 1 swap lshift and 0<> ( flag )
+;
+
+: icu@ ( offset -- value ) h# 28.2000 + io@ ;
+: .masked ( irq# -- )
+ dup /l* h# 10c + icu@ ( irq# masked )
+ 1 and if ( irq# )
+ ." IRQ" .d ." is masked off" cr
+ else ( irq# )
+ drop ( )
+ then ( )
+;
+: .selected ( irq# -- )
+ dup /l* h# 100 + icu@ ( irq# n )
+ dup h# 40 and if ( irq# n )
+ ." IRQ" swap .d ( n )
+ ." selected INT" h# 3f and .d cr ( )
+ else ( irq# n )
+ 2drop ( )
+ then ( )
+;
+: (.pending) ( d -- )
+ ." pending INTs: " ( d )
+ d# 64 0 do ( d )
+ over 1 and if i .d then ( d )
+ d2/ ( d' )
+ loop ( d )
+ 2drop ( )
+;
+: .pending ( irq# -- )
+ dup 2* /l* h# 130 + dup icu@ swap la1+ icu@ ( irq# d )
+ 2dup d0= if ( irq# d )
+ 3drop ( )
+ else ( irq# d )
+ ." IRQ " rot .d (.pending) cr ( )
+ then ( )
+;
+
+: bit? ( n bit# -- n flag ) 1 swap lshift over and 0<> ;
+: .ifbit ( n bit# msg$ -- n )
+ 2>r bit? if ( n r: msg$ )
+ 2r> type space ( n )
+ else ( n r: msg$ )
+ 2r> 2drop ( n )
+ then ( n )
+;
+: .enabled-ints ( -- )
+ d# 64 0 do ( )
+ i /l* icu@ dup h# 70 and if ( n )
+ ." INT" i .d ." -> IRQ" ( n )
+ 4 " 0" .ifbit ( n )
+ 5 " 1" .ifbit ( n )
+ 6 " 2" .ifbit ( n )
+ ." Pri " h# f and .d cr ( )
+ else ( n )
+ drop ( )
+ then ( )
+ loop ( )
+;
+: .int4 ( -- )
+ ." INT4 - mask " h# 168 icu@ .x
+ ." status " h# 150 icu@ dup .x
+ 0 " USB " .ifbit
+ 1 " PMIC" .ifbit
+ drop cr
+;
+: .int5 ( -- )
+ ." INT5 - mask " h# 16c icu@ .x
+ ." status " h# 154 icu@ dup .x
+ 0 " RTC " .ifbit
+ 1 " RTC_Alarm" .ifbit
+ drop cr
+;
+: .int9 ( -- )
+ ." INT9 - mask " h# 17c icu@ .x
+ ." status " h# 180 icu@ dup .x
+ 0 " Keypad " .ifbit
+ 1 " Rotary " .ifbit
+ 2 " Trackball" .ifbit
+ drop cr
+;
+: .int17 ( -- )
+ ." INT17 - mask " h# 170 icu@ .x
+ ." status " h# 158 icu@ dup .x ( n )
+ 7 2 do ( n )
+ dup 1 and if ( n )
+ ." TWSI" i .d ( n )
+ then ( n )
+ u2/ ( n' )
+ loop ( n )
+ drop cr ( )
+;
+: .int35 ( -- )
+ ." INT5 - mask " h# 174 icu@ .x
+ ." status " h# 15c icu@ dup .x
+ d# 0 " PJ_PerfMon" .ifbit
+ d# 1 " L2_PA_ECC" .ifbit
+ d# 2 " L2_ECC" .ifbit
+ d# 3 " L2_UECC" .ifbit
+ d# 4 " DDR" .ifbit
+ d# 5 " Fabric0" .ifbit
+ d# 6 " Fabric1" .ifbit
+ d# 7 " Fabric2" .ifbit
+ d# 9 " Thermal" .ifbit
+ d# 10 " MainPMU" .ifbit
+ d# 11 " WDT2" .ifbit
+ d# 12 " CoreSight" .ifbit
+ d# 13 " PJ_Commtx" .ifbit
+ d# 14 " PJ_Commrx" .ifbit
+ drop
+ cr
+;
+: .int51 ( -- )
+ ." INT51 - mask " h# 178 icu@ .x
+ ." status " h# 160 icu@ dup .x
+ 0 " HSI_CAWAKE1 " .ifbit
+ 1 " MIPI_HSI1" .ifbit
+ drop cr
+;
+: .int55 ( -- )
+ ." INT55 - mask " h# 184 icu@ .x
+ ." status " h# 188 icu@ dup .x
+ 0 " HSI_CAWAKE0 " .ifbit
+ 1 " MIPI_HSI0" .ifbit
+ drop cr
+;
+
+: .fiq ( -- )
+ h# 304 icu@ if ." FIQ is masked off" cr then
+ h# 300 icu@ dup h# 40 and if ." FIQ selected INT" h# 3f and .d cr else drop then
+ h# 310 icu@ h# 314 icu@ 2dup d0= if ( d )
+ 2drop ( )
+ else ( d )
+ ." FIQ " (.pending) cr ( )
+ then ( )
+;
+
+: .icu ( -- )
+ .enabled-ints
+ 3 0 do i .masked i .selected i .pending loop
+ \ XXX should handle DMA interrupts too
+ .fiq
+ .int4 .int5 .int9 .int17 .int35 .int51 .int55
+;
+string-array wakeup-bit-names
+ ," WU0 "
+ ," WU1 "
+ ," WU2 "
+ ," WU3 "
+ ," WU4 "
+ ," WU5 "
+ ," WU6 "
+ ," WU7 "
+ ," TIMER_1_1 "
+ ," TIMER_1_2 "
+ ," TIMER_1_3 "
+ ," MSP_INS "
+ ," AUDIO "
+ ," WDT1 "
+ ," TIMER_2_1 "
+ ," TIMER_2_2 "
+ ," TIMER_2_3 "
+ ," RTC_ALARM "
+ ," WDT2 "
+ ," ROTARY "
+ ," TRACKBALL "
+ ," KEYPRESS "
+ ," SDH3_CARD "
+ ," SDH1_CARD "
+ ," FULL_IDLE "
+ ," ASYNC_INT "
+ ," SSP1_SRDY "
+ ," CAWAKE "
+ ," resv28 "
+ ," SSP3_SRDY "
+ ," ALL_WU "
+ ," resv31 "
+end-string-array
+
+string-array wakeup-mask-names
+ ," WU0 "
+ ," WU1 "
+ ," WU2 "
+ ," WU3 "
+ ," WU4 "
+ ," WU5 "
+ ," WU6 "
+ ," WU7 "
+ ," TIMER_1_1 "
+ ," TIMER_1_2 "
+ ," TIMER_1_3 "
+ ," "
+ ," "
+ ," "
+ ," TIMER_2_1 "
+ ," TIMER_2_2 "
+ ," TIMER_2_3 "
+ ," RTC_ALARM "
+ ," WDT2 "
+ ," ROTARY "
+ ," TRACKBALL "
+ ," KEYPRESS "
+ ," SDH3_CARD "
+ ," SDH1_CARD "
+ ," FULL_IDLE "
+ ," ASYNC_INT "
+ ," WDT1 "
+ ," SSP3_SRDY "
+ ," SSP1_SRDY "
+ ," CAWAKE "
+ ," MSP_INS "
+ ," resv31 "
+end-string-array
+
+: .active-wakeups ( -- )
+ ." Wakeups: "
+ h# 1048 mpmu@ ( n )
+ d# 31 0 do ( n )
+ dup 1 and if i wakeup-bit-names count type then ( n )
+ u2/ ( n' )
+ loop ( n )
+ drop cr ( )
+;
+: .wakeup-mask ( -- )
+ ." Enabled wakeups: "
+ h# 4c mpmu@ h# 104c or ( n )
+ d# 31 0 do ( n )
+ dup 1 and if i wakeup-mask-names count type then ( n )
+ u2/ ( n' )
+ loop ( n )
+ drop cr ( )
+;
+: .edges ( -- )
+ ." Wakeup edges: " ( )
+ d# 6 0 do ( )
+ h# 19800 i la+ io@ ( n )
+ d# 32 0 do ( n )
+ dup 1 and if ( n )
+ j d# 32 * i + .d ( n )
+ then ( n )
+ u2/ ( n' )
+ loop ( n )
+ drop ( )
+ loop ( )
+ cr ( )
+;
+: .edge-enables ( -- )
+ ." Enabled edges: "
+ d# 160 0 do
+ i af@ dup h# 70 and h# 40 <> if ( n )
+ dup h# 10 and if ." R" then ( n )
+ dup h# 20 and if ." F" then ( n )
+ dup h# 40 and if ." C" then ( n )
+ i .d ( n )
+ then ( n )
+ drop ( )
+ loop
+;
+: .wakeup ( -- ) .active-wakeups .wakeup-mask .edges .edge-enables ;
+
+: .irqstat ( -- ) h# 148 h# 130 do i icu@ . 4 +loop ;
+\ !!! The problem right now is that I have woken from keyboard, but the interrupt is still asserted
+\ So perhaps the interrupt handler didn't fire
+: rotate-wakeup? ( -- flag ) d# 15 gpio-wakeup? ;
+: kbd-wakeup? ( -- flag ) d# 71 gpio-wakeup? ;
+: tpd-wakeup? ( -- flag ) d# 160 gpio-wakeup? ;
+\ We need to do this in the SP interrupt handler
+: clear-wakeup ( gpio# -- )
+ dup af@ ( gpio# value )
+ 2dup h# 40 or swap af! ( gpio# value )
+ swap af!
+;
+\ How to wakeup from SP:
+: setup-key-wakeup ( -- )
+ d# 24 d# 16 do h# b1 i af! loop \ Wake SP on game keys
+ h# b0 d# 15 af! \ Wake SP on rotate key
+ h# 220 d# 71 af! \ Wake SP on KBD CLK falling edge
+ h# 221 d# 160 af! \ Wake SP on TPD CLK falling edge
+ h# 4c mpmu@ h# 20.0000 or h# 4c mpmu! \ Keypress wakes SP
+ ['] disable-int40 d# 40 interrupt-handler!
+ d# 40 enable-interrupt \ SP to PJ4 communications interrupt
+ h# 2900cc io@ 1 invert and h# 2900cc io! \ Unmask the communications interrupt
+;
+
0 value save-apcr
0 value save-idlecfg
@@ -404,6 +703,8 @@
" dcon-suspend" $call-screen
then
" suspend" $call-screen
+ " set-ack" $call-ec
+
\ 0 h# 54 pmua! \ Kill the SDIO 0 clocks - insignificant savings
\ 0 h# 58 pmua! \ Kill the SDIO 1 clocks - insignificant savings
sleep-mask 2 and 0= if keyboard-power-off then \ Should save about 17 mW
@@ -412,6 +713,7 @@
: screen-on ( -- )
sleep-mask 4 and 0= if wlan-power-on then
sleep-mask 2 and 0= if keyboard-power-on then
+ " clr-ack" $call-ec
" resume" $call-screen
sleep-mask 1 and if \ DCON power up
dcon-unfreeze
Modified: cpu/arm/mmp2/rtc.fth
==============================================================================
--- cpu/arm/mmp2/rtc.fth Fri Sep 23 00:42:26 2011 (r2526)
+++ cpu/arm/mmp2/rtc.fth Fri Sep 23 06:59:53 2011 (r2527)
@@ -15,10 +15,13 @@
;
: soc-rtc@ ( offset -- value ) h# 01.0000 + io@ ;
: soc-rtc! ( value offset -- value ) h# 01.0000 + io! ;
+: cancel-alarm ( -- )
+ 0 8 soc-rtc!
+ int5-mask@ 1 or int5-mask! \ Mask alarm
+;
: take-alarm ( -- )
." Alarm fired" cr
- 0 8 soc-rtc!
- int5-mask@ 1 or int5-mask! \ Mask alarm
+ cancel-alarm
;
: alarm-in-3 ( -- )
enable-rtc \ Turn on clocks
@@ -30,3 +33,79 @@
['] take-alarm 5 interrupt-handler!
5 enable-interrupt
;
+: alarm-in-1 ( -- )
+ enable-rtc \ Turn on clocks
+
+ int5-mask@ 1 invert and int5-mask! \ Unmask alarm
+ enable-rtc-wakeup
+ 0 soc-rtc@ d# 1 + 4 soc-rtc! \ Set alarm for 3 seconds from now
+ 7 8 soc-rtc! \ Ack old interrupts and enable new ones
+ ['] cancel-alarm 5 interrupt-handler!
+ 5 enable-interrupt
+;
+: wake1 ( -- )
+ enable-rtc \ Turn on clocks
+
+ int5-mask@ 1 invert and int5-mask! \ Unmask alarm
+ enable-rtc-wakeup
+ 0 soc-rtc@ d# 1 + 4 soc-rtc! \ Set alarm for 3 seconds from now
+ 7 8 soc-rtc! \ Ack old interrupts and enable new ones
+ ['] cancel-alarm 5 interrupt-handler!
+ 5 enable-interrupt
+;
+: alarm1 ( -- )
+ enable-rtc \ Turn on clocks
+
+ int5-mask@ 1 invert and int5-mask! \ Unmask alarm
+ enable-rtc-wakeup
+ 0 soc-rtc@ d# 1 + 4 soc-rtc! \ Set alarm for 3 seconds from now
+ 7 8 soc-rtc! \ Ack old interrupts and enable new ones
+ ['] take-alarm 5 interrupt-handler!
+ 5 enable-interrupt
+;
+: test1
+ 0
+ begin
+ alarm1
+ str
+ (cr dup . 1+
+ d# 500 ms
+ key? until
+;
+: test2
+ 0
+ begin
+ wake1
+ str
+ (cr dup . 1+
+ d# 500 ms
+ key? until
+;
+: test3
+ 0
+ begin
+ wake1
+ str
+ cr dup . 1+
+ d# 500 ms
+ key? until
+;
+: test4
+ begin
+ 0 d# 13 at-xy
+ 5 0 do
+ wake1 str
+ cr i .
+ d# 500 ms
+ key? if unloop exit then
+ loop
+ again
+;
+
+\ test3
+\ wake1 str cr
+
+\ patch noop cr take-alarm test1
+\ patch (cr cr take-alarm test1
+
+\ : cx cr d# 400 ms ; patch cx cr take-alarm test1
Modified: dev/olpc/dcon/mmp2dcon.fth
==============================================================================
--- dev/olpc/dcon/mmp2dcon.fth Fri Sep 23 00:42:26 2011 (r2526)
+++ dev/olpc/dcon/mmp2dcon.fth Fri Sep 23 06:59:53 2011 (r2527)
@@ -176,8 +176,8 @@
h# dc02 =
;
-: dcon-setup ( -- )
- 0 dcon@ drop 0 dcon@ drop
+: dcon-setup ( -- error? )
+ dcon2? 0= if ." Can't init DCON" true exit then
[ifdef] notdef
d# 1200 2 dcon! \ HResolution
@@ -196,9 +196,10 @@
h# 0101 h# 42 dcon!
h# 12 mode!
+ false
;
: dcon-enable ( -- )
- dcon-setup
+ dcon-setup if exit then
true set-color
h# f bright!
;
@@ -234,8 +235,12 @@
dcon-power-off
;
: dcon-resume ( -- )
- dcon-power-on d# 50 ms
- dcon-setup
+ ['] dcon-power-on catch if
+ ." dcon-power-on failed" cr
+ exit
+ then
+ d# 80 ms
+ dcon-setup if exit then
saved-dcon-mode mode!
saved-brightness bright!
;
More information about the openfirmware
mailing list