[openfirmware] [commit] r3270 - in cpu/arm: mmp2 mmp3 olpc
repository service
svn at openfirmware.info
Sun Sep 2 01:57:24 CEST 2012
Author: wmb
Date: Sun Sep 2 01:57:24 2012
New Revision: 3270
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/3270
Log:
OLPC ARM - Implemented suspend/resume for XO-4, in the process refactoring the XO-1.75 suspend/resume code so much of it could be shared.
Added:
cpu/arm/mmp2/showirqs.fth
cpu/arm/mmp2/wakeups.fth
cpu/arm/mmp3/dramrecal.fth
cpu/arm/olpc/suspend.fth
Modified:
cpu/arm/mmp2/dramrecal.fth
cpu/arm/mmp2/socregs.fth
cpu/arm/olpc/build-fw.fth
Modified: cpu/arm/mmp2/dramrecal.fth
==============================================================================
--- cpu/arm/mmp2/dramrecal.fth Sun Sep 2 01:42:57 2012 (r3269)
+++ cpu/arm/mmp2/dramrecal.fth Sun Sep 2 01:57:24 2012 (r3270)
@@ -1,5 +1,5 @@
\ See license at end of file
-purpose: Recalibrate DDR3 DRAM
+purpose: Recalibrate DDR3 DRAM (SoC-specific low-level power management factors)
\ DDR3 DRAM requires periodic recalibration to cope with parameter drift from
\ temperature variation. The recalibration below affects both the DLL and
@@ -189,14 +189,7 @@
end-code
here ddr-self-refresh - constant /ddr-self-refresh
-memctrl-pa constant memctrl-va
-
: ddr-code-to-sram ( -- )
- memctrl-pa h# c02 or memctrl-va map-section \ Map the memory controller
-
-\ sram is already mapped by initmmu.fth
-\ sram-pa h# c0e or sram-va map-section \ Make the code cacheable
-
ddr-recal 'ddr-recal /ddr-recal move
'ddr-recal /ddr-recal sync-cache
@@ -227,124 +220,6 @@
mov pc,r1
c;
-: apbc-clr-rst ( offset -- ) 4 swap +apbc io-clr ;
-: apbc-set-rst ( offset -- ) 4 swap +apbc io-set ;
-
-: disable-apbc-clks ( -- )
- \ 3 h# 38 +apbc io-clr \ GPIO
- 3 h# 74 +apbc io-clr \ MPMU
- 3 h# 78 +apbc io-clr \ IPC
- 3 h# 90 +apbc io-clr \ THSENS1
-
- \ h# 38 apbc-set-rst
- \ h# 74 apbc-set-rst \ MPMU - resetting this kills TIMER2, used by the SP PS/2
- h# 78 apbc-set-rst \ IPC
- h# 90 apbc-set-rst \ THSENS1
-;
-: enable-apbc-clks ( -- )
- \ 3 h# 38 +apbc io-set \ GPIO
- 3 h# 74 +apbc io-set \ MPMU
- 3 h# 78 +apbc io-set \ IPC
- 3 h# 90 +apbc io-set \ THSENS1
-
- \ h# 38 apbc-clr-rst
- h# 74 apbc-clr-rst \ MPMU
- h# 78 apbc-clr-rst \ IPC
- h# 90 apbc-clr-rst \ THSENS1
-;
-: disable-scu-clks ( -- )
- 0 h# 64 +scu io! \ SCU_AXIFAB_CKGT_CTRL0 - Close AXI fabric clock gate
- 0 h# 68 +scu io! \ SCU_AXIFAB_CKGT_CTRL1
- h# f0 h# 1c +scu io-set \ SCU_MCB_CONF
-;
-: enable-scu-clks ( -- )
- h# 3003003 h# 64 +scu io! \ SCU_AXIFAB_CKGT_CTRL0 - Open AXI fabric clock gate
- h# 0303030 h# 68 +scu io! \ SCU_AXIFAB_CKGT_CTRL1
- h# f0 h# 1c +scu io-clr \ SCU_MCB_CONF
-;
-: disable-apmu-clks ( -- )
- h# 1b h# 54 +pmua io-clr \ PMUA_SDH0_CLK_RES_CTRL
- h# 1b h# 58 +pmua io-clr \ PMUA_SDH1_CLK_RES_CTRL
- h# 1b h# e8 +pmua io-clr \ PMUA_SDH2_CLK_RES_CTRL
- h# 1b h# d4 +pmua io-clr \ PMUA_SMC_CLK_RES_CTRL
- h# 3f h# 60 +pmua io-clr \ PMUA_NF_CLK_RES_CTRL
- h# 3f h# d8 +pmua io-clr \ PMUA_MSPRO_CLK_RES_CTRL - XO does not use MSPRO
- h# 12 h# 10c +pmua io-clr \ PMUA_AUDIO_CLK_RES_CTRL
- h# 1fffd h# dc +pmua io-clr \ PMUA_GLB_CLK_RES_CTRL
-\ 0 h# 68 pmua! \ PMUA_WTM_CLK_RES_CTRL
- h# 9 h# 5c +pmua io-clr \ PMUA_USB_CLK_RES_CTRL
-;
-: enable-apmu-clks ( -- )
- h# 1b h# 54 +pmua io-set \ PMUA_SDH0_CLK_RES_CTRL
- h# 1b h# 58 +pmua io-set \ PMUA_SDH1_CLK_RES_CTRL
- h# 1b h# e8 +pmua io-set \ PMUA_SDH2_CLK_RES_CTRL
- h# 1b h# d4 +pmua io-set \ PMUA_SMC_CLK_RES_CTRL \ ??? what is this and why is it on?
- h# 3f h# 60 +pmua io-set \ PMUA_NF_CLK_RES_CTRL \ Should this be on?
-\ h# 3f h# d8 +pmua io-set \ PMUA_MSPRO_CLK_RES_CTRL
- h# 12 h# 10c +pmua io-set \ PMUA_AUDIO_CLK_RES_CTRL
- h# 1fffd h# dc +pmua io-set \ PMUA_GLB_CLK_RES_CTRL
-\ h# 1b h# 68 pmua! \ PMUA_WTM_CLK_RES_CTRL
- h# 9 h# 5c +pmua io-set \ PMUA_USB_CLK_RES_CTRL
-;
-: pll2? ( -- flag ) h# 34 mpmu@ h# 100 and 0<> ;
-: disable-mpmu-clks ( -- )
- pll2? if h# e010 else h# a010 then ( cgr-value )
- dup h# 1024 mpmu! \ MPMU_CGR_PJ
- h# 0024 mpmu! \ MPMU_CGR_SP
-
-\ h# 2000.0000 h# 414 +mpmu io-clr \ MPMU_PLL2_CTRL1
- h# 8000.0000 h# 0040 +mpmu io-clr \ MPMU_ISCCR1
- h# 8000.0000 h# 0044 +mpmu io-clr \ MPMU_ISCCR2
-;
-: enable-mpmu-clks ( -- )
- h# dffe.fffe h# 1024 mpmu! \ MPMU_ACGR
-\ h# 2000.0000 h# 0414 +mpmu io-set \ MPMU_PLL2_CTRL1
- h# 8000.0000 h# 0040 +mpmu io-set \ MPMU_ISCCR1
- h# 8000.0000 h# 0044 +mpmu io-set \ MPMU_ISCCR2
-;
-: disable-twsi-clks ( -- )
- \ set RST in APBC_TWSIx_CLK_RST registers
-
-[ifdef] notdef
- \ just disable TWSI1 clk rather than reset it since it's needed to access PMIC onkey
- \ when system is waken up from low power mode */
- 0 4 +apbc io! \ Disable TWSI1 clock
-[else]
- h# 04 apbc-set-rst \ TWSI1
-[then]
- h# 08 apbc-set-rst \ TWSI2
- h# 0c apbc-set-rst \ TWSI3
- h# 10 apbc-set-rst \ TWSI4
- h# 7c apbc-set-rst \ TWSI5
- h# 80 apbc-set-rst \ TWSI6
-;
-: enable-twsi-clks ( -- )
-[ifdef] notdef
- 3 4 +apbc io! \ Enable TWSI1 clock
-[else]
- h# 04 apbc-clr-rst \ TWSI1
-[then]
- h# 08 apbc-clr-rst \ TWSI2
- h# 0c apbc-clr-rst \ TWSI3
- h# 10 apbc-clr-rst \ TWSI4
- h# 7c apbc-clr-rst \ TWSI5
- h# 80 apbc-clr-rst \ TWSI6
-;
-: disable-clks ( -- )
- disable-twsi-clks
- disable-apbc-clks
- disable-scu-clks
- disable-apmu-clks
- disable-mpmu-clks
-;
-: enable-clks ( -- )
- enable-mpmu-clks
- enable-apmu-clks
- enable-scu-clks
- enable-apbc-clks
- enable-twsi-clks
-;
-
\ Wakeup ports - from datasheet page 718
\ WAKEUP0: CAWAKE (MIPI-HSI wakeup)
\ WAKEUP1: Audio Island
@@ -362,301 +237,6 @@
;
: 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
- 1 h# 29.00cc io-set \ Unmask the inter-processor communications 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 )
-;
-
-: .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 ( -- )
- ." INT35 - 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# 15 do h# b0 i af! loop \ Wake SoC on game keys
-[ifdef] soc-kbd-clk-gpio#
- h# 220 soc-kbd-clk-gpio# af! \ Wake SoC on KBD CLK falling edge
- h# 221 soc-tpd-clk-gpio# af! \ Wake SoC on TPD CLK falling edge
-[then]
- h# 4 h# 4c +mpmu io-set \ Pin edge (GPIO per datasheet) wakes SoC
- ['] disable-int40 d# 40 interrupt-handler!
- d# 40 enable-interrupt \ SP to PJ4 communications interrupt
- 1 h# 29.00cc io-clr \ Unmask the inter-processor communications interrupt
-;
-
: breadcrumb ( n -- ) h# d000.0110 l! ;
0 value save-apcr
@@ -749,137 +329,31 @@
h# 1000 mpmu! ( ) \ Set APCR register
\ end mmp2_pm_enter_lowpower_mode(state)
-;
-
-[ifdef] soc-en-kbd-pwr-gpio#
-: keyboard-power-on ( -- ) soc-en-kbd-pwr-gpio# gpio-clr ;
-: keyboard-power-off ( -- ) soc-en-kbd-pwr-gpio# gpio-set ;
-[else]
-: keyboard-power-on ( -- ) ;
-: keyboard-power-off ( -- ) ;
-[then]
-: wlan-power-on ( -- ) en-wlan-pwr-gpio# gpio-set ;
-: wlan-power-off ( -- ) en-wlan-pwr-gpio# gpio-clr h# 040 en-wlan-pwr-gpio# af! h# 040 wlan-pd-gpio# af! h# 040 wlan-reset-gpio# af! ;
-: wlan-stay-on ( -- ) h# 140 en-wlan-pwr-gpio# af! h# 140 wlan-pd-gpio# af! h# 140 wlan-reset-gpio# af! ;
-
-0 value sleep-mask
-: screen-sleep
- sleep-mask 1 and if \ DCON power down
- dcon-freeze
- else
- " dcon-suspend" $call-dcon
- then
- " sleep" $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
- sleep-mask 4 and if
- wlan-stay-on
- else
- " /wlan" " sleep" execute-device-method drop
- wlan-power-off
- then \ saves 100 mW
-;
-: screen-wake ( -- )
- sleep-mask 4 and 0= if
- wlan-power-on
- " /wlan" " wake" execute-device-method drop
- then
- sleep-mask 2 and 0= if keyboard-power-on then
- " clr-ack" $call-ec
- " wake" $call-screen
- sleep-mask 1 and if \ DCON power up
- dcon-unfreeze
- else
- " dcon-resume" $call-dcon
- then
-;
-
-: stdin-idle-on ['] safe-idle to stdin-idle d# 15 enable-interrupt ;
-: stdin-idle-off ['] noop to stdin-idle ( install-uart-io ) d# 15 disable-interrupt ;
+ h# 000c.0000 h# 8c +pmua io-set \ Power down CoreSight SRAM
-: timers-sleep ( -- )
- 0 h# 14048 io! \ Disable interrupts from the tick timer
- 7 h# 1407c io! \ Clear any pending interrupts
- h# f disable-interrupt \ Block timer interrupt
-;
-: timers-wake ( -- )
- 1 h# 14048 io! \ Enable interrupts from the tick timer
- 7 h# 1407c io! \ Clear any pending interrupts
- h# f enable-interrupt \ Unblock timer interrupt
- reschedule-tick
+ block-irqs
;
: power-islands-off ( -- )
+ \ TODO - need to power down sram/l2$
+ \ mmp2_cpu_disable_l2(0);
+ \ outer_cache.flush_range(0, -1ul);
+
+[ifdef] use-gpio
+ 3 gpio-dir-out
+[then]
0 h# 10c pmua! \ Turn off audio power island
;
: power-islands-on ( -- )
h# 712 h# 10c pmua! \ Turn on audio power island
;
-
-: str ( -- )
-[ifdef] use-gpio
- 3 gpio-dir-out
-[then]
-
- disable-interrupts
- suspend-usb
- timers-sleep
-
- screen-sleep
- stdin-idle-off
- 5 h# 38 mpmu! \ Use 32 kHz clock instead of VCXO for slow clock
-
-\ OLPC: Unmask main PMU interrupt - don't know if this is necessary
-\ h# 400 h# 174 +icu io-clr
-\ d# 35 enable-interrupt
-
-\ The PMIC_INT line is unconnected on XO-1.75. Normally it would come from the EC,
-\ presumably for the purpose of waking on a keystroke.
-\ 4 enable-interrupt \ Route PMIC interrupt to PJ4 IRQ
-\ 2 h# 168 +icu io-clr \ Enable PMIC interrupt
-
- setup-sleep-state
-
- h# 000c.0000 h# 8c +pmua io-set \ Power down CoreSight SRAM
-
- \ TODO - need to power down sram/l2$
- \ mmp2_cpu_disable_l2(0);
- \ outer_cache.flush_range(0, -1ul);
-
- power-islands-off
-
- disable-clks
-
- \ begin mmp2_cpu_do_idle()
- block-irqs ( ) \ Block IRQs - will be cleared by PMU
-[ifdef] use-hw-s3
+: do-wfi ( -- )
+ [ifdef] use-hw-s3
wfi
[else]
do-self-refresh
[then]
-
- restore-run-state
- \ end mmp2_cpu_do_idle()
-
- enable-clks
-
- power-islands-on
-
- \ mmp2_cpu_enable_l2(0);
-
- \ idle_cfg &= (~PMUA_MOH_SRAM_PWRDWN);
- stdin-idle-on
-
- screen-wake
- timers-wake
- resume-usb
- enable-interrupts
- init-thermal-sensor
;
-: strp ( -- ) ec-rst-pwr str ec-max-pwr .d ." mW " soc .% space ;
\ LICENSE_BEGIN
\ Copyright (c) 2011 FirmWorks
Added: cpu/arm/mmp2/showirqs.fth
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ cpu/arm/mmp2/showirqs.fth Sun Sep 2 01:57:24 2012 (r3270)
@@ -0,0 +1,169 @@
+\ See license at end of file
+purpose: Display the state of the MMP2 ICU interrupt controller
+
+: .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 ( -- )
+ ." INT35 - 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
+;
+
+: .irqstat ( -- ) h# 148 h# 130 do i icu@ . 4 +loop ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2012 FirmWorks
+\
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
Modified: cpu/arm/mmp2/socregs.fth
==============================================================================
--- cpu/arm/mmp2/socregs.fth Sun Sep 2 01:42:57 2012 (r3269)
+++ cpu/arm/mmp2/socregs.fth Sun Sep 2 01:57:24 2012 (r3270)
@@ -22,6 +22,9 @@
: mpmu@ ( offset -- l ) +mpmu io@ ;
: mpmu! ( l offset -- ) +mpmu io! ;
+: mpmu-set ( bits reg# -- ) +mpmu io-set ;
+: mpmu-clr ( bits reg# -- ) +mpmu io-clr ;
+
: pmua@ ( offset -- l ) +pmua io@ ;
: pmua! ( l offset -- ) +pmua io! ;
Added: cpu/arm/mmp2/wakeups.fth
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ cpu/arm/mmp2/wakeups.fth Sun Sep 2 01:57:24 2012 (r3270)
@@ -0,0 +1,182 @@
+\ See license at end of file
+purpose: Setup keyboard wakeups and display the state of the wakeup machinery
+
+\ 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
+ 1 h# 29.00cc io-set \ Unmask the inter-processor communications interrupt
+;
+
+\ How to wakeup from SP:
+: setup-key-wakeup ( -- )
+ d# 24 d# 15 do h# b0 i af! loop \ Wake SoC on game keys
+[ifdef] soc-kbd-clk-gpio#
+ h# 220 soc-kbd-clk-gpio# af! \ Wake SoC on KBD CLK falling edge
+ h# 221 soc-tpd-clk-gpio# af! \ Wake SoC on TPD CLK falling edge
+[then]
+ h# 4 h# 4c +mpmu io-set \ Pin edge (GPIO per datasheet) wakes SoC
+ ['] disable-int40 d# 40 interrupt-handler!
+ d# 40 enable-interrupt \ SP to PJ4 communications interrupt
+ 1 h# 29.00cc io-clr \ Unmask the inter-processor communications interrupt
+;
+
+\ 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!
+;
+
+: 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 )
+;
+
+\ !!! 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? ;
+
+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 ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2012 FirmWorks
+\
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
Added: cpu/arm/mmp3/dramrecal.fth
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ cpu/arm/mmp3/dramrecal.fth Sun Sep 2 01:57:24 2012 (r3270)
@@ -0,0 +1,323 @@
+\ See license at end of file
+purpose: SoC-specific low-level power management factors
+
+\ First some tools for managing the DRAM reconfiguration table
+
+0 value table#
+0 value entry#
+0 value mc-cs-map
+
+0 value mc#
+: set-mc ( mc# -- ) to mc# ;
+: +mc ( offset -- adr ) h# d000.0000 + mc# if h# 1.0000 + then ;
+: mc@ ( offset -- value ) +mc l@ ;
+: mc! ( value offset -- ) +mc l! ;
+
+: +pause ( reg# -- reg#' ) h# 1.0000 or ;
+: +last ( reg# -- reg#' ) h# 2.0000 or ;
+
+: +mct ( value register#+flags -- )
+ entry# d# 32 = abort" DRAM init table overflow"
+ swap h# 1c8 mc! ( data1-value )
+ h# 1cc mc! ( )
+ table# 5 lshift
+ entry# or
+ h# 8000.0000 or ( ctrl-value )
+ h# 1c0 mc! ( )
+ entry# 1+ to entry#
+;
+: mc-table( ( mc# table# -- )
+ to table# set-mc 0 to entry#
+
+ 0
+ h# 10 mc@ 1 and if h# 1000.0000 or then
+ h# 14 mc@ 1 and if h# 2000.0000 or then
+ to mc-cs-map
+;
+: )mc-table ( -- )
+ table# 5 lshift
+ mc# if 3 lshift h# 700 else h# e0 then ( field mask )
+ invert h# 11c pmua@ and or h# 11c pmua!
+;
+
+: +phy-dll ( -- )
+ 4 0 do i h# 300 +mct h# 1080 h# 304 +mct loop
+;
+: +read-leveling ( -- )
+ 4 0 do h# 100 i + h# 380 +mct h# 200 h# 390 +mct loop
+;
+: +reset-dll ( -- )
+ h# 2000.0000 h# 24c +mct \ DLL reset
+ h# 0003.0001 h# 160 +mct \ SDRAM INIT
+ h# 4000.0000 h# 24c +mct \ DLL update via pulse mode
+;
+: +update-mode ( -- )
+ mc-cs-map h# 100 or h# 160 +mct
+ mc-cs-map h# 400 or h# 160 +mct
+;
+: +reset-sdram-dll ( -- ) h# 50 mc@ h# 40 or h# 50 +mct ;
+: +zq-cal ( -- ) mc-cs-map h# 1000 or h# 160 +mct ;
+: +halt-pause ( -- ) 2 h# 68 +pause +mct ;
+
+: +halt ( -- ) 2 h# 68 +mct ; \ SDRAM_CTRL14 - Halt scheduler
+: +restart ( -- ) 0 h# 68 +last +mct ; \ SDRAM_CTRL14 - Resume scheduler
+
+: +cmd0 ( lowbits -- ) mc-cs-map or h# 160 +mct ;
+
+: make-ddr3-recal-table ( mc# -- )
+ 0 mc-table(
+ +halt
+ h# 2000.0000 h# 24c +mct \ PHY_CTRL14 - PHY DLL reset
+ h# 4000.0000 h# 24c +mct \ PHY_CTRL14 - PHY DLL update
+ h# 8000.0000 h# 24c +pause +mct \ PHY_CTRL14 - Sync 2x clock
+ h# 50 mc@ h# 40 or
+ h# 50 +mct \ SDRAM_CTRL1 - set DLL_RESET bit
+ h# 0000.0100 +cmd0 \ USER_COMMAND0 - Send LMR0 DLL
+ h# 0000.0400 +cmd0 \ USER_COMMAND0 - Send LMR2 DLL
+ h# 0000.1000 +cmd0 \ USER_COMMAND0 - ZQ Calibration
+ +restart
+ )mc-table
+;
+: mc2-enabled? ( -- flag ) h# 6c pmua@ 2 and 0<> ;
+: make-ddr3-recal-tables ( -- )
+ 0 make-ddr3-recal-table
+ mc2-enabled? if
+ 1 make-ddr3-recal-table
+ else
+ 2 h# 190 pmua-set \ PMUA_DEBUG2 - don't wait for ack from MC2
+ then
+;
+
+0 value old-ccic
+0 value old-gc
+0 value old-vmeta
+0 value old-aclk
+0 value old-adsa
+0 value old-aisl
+: power-islands-off ( -- )
+ h# 50 pmua@ to old-ccic 0 h# 50 pmua! \ Camera
+ h# cc pmua@ to old-gc 0 h# cc pmua! \ Graphics
+ h# a4 pmua@ to old-vmeta 0 h# a4 pmua! \ Vmeta
+ h# 10c pmua@ to old-aclk 0 h# 10c pmua! \ Audio clock
+ h# 164 pmua@ to old-adsa 0 h# 164 pmua! \ Audio DSA
+ h# 1e4 pmua@ to old-aisl 0 h# 1e4 pmua! \ Audio Island
+ h# fc0 h# 240 pmua-set \ Retain audio SRAM state (0 to power them off)
+;
+: power-islands-on ( -- )
+ old-aisl h# 1e4 pmua!
+ old-adsa h# 164 pmua!
+ old-aclk h# 10c pmua!
+ old-vmeta h# a4 pmua!
+ old-gc h# cc pmua!
+ old-ccic h# 50 pmua!
+;
+
+: +ciu ( adr -- adr' ) h# 282c00 + ;
+: ciu! ( l adr -- ) +ciu io! ;
+: ciu@ ( adr -- l ) +ciu io@ ;
+
+: sp-c1-on ( -- )
+ h# 1000.0000 0 mpmu-set \ Allow SP clock shutdown in IDLE (can't DMA to TCM)
+;
+
+: idle-cfg@ ( -- n ) h# 18 pmua@ ; \ Core-dependent
+: idle-cfg! ( -- n ) h# 18 pmua! ; \ Core-dependent
+: idle-cfg-clr ( mask -- ) h# 18 pmua-clr ;
+: idle-cfg-set ( mask -- ) h# 18 pmua-set ;
+
+: cc4-set ( mask -- ) h# 248 pmua-set ;
+: cc4-clr ( mask -- ) h# 248 pmua-clr ;
+
+0 [if]
+: pj-c1 ( -- )
+ h# 62 idle-cfg-clr \ light sleep after WFI
+ wfi
+;
+: pj-c1-extclk
+ h# 62 idle-cfg-clr \ light sleep after WFI
+ h# 02 idle-cfg-set \ Allow core clock shutdown (won't respond to snoops)
+ h# 01 cc4-set \ Mask off GIC interrupts
+ wfi
+;
+: pj-c2
+ ( clean&invalidate-l1 ) \ Must do this if coherency is enabled
+ h# 8000.0062 idle-cfg-clr \ light sleep after WFI
+
+ \ To set the 40 bit, you must first clean&invalidate the l1 cache
+ h# 22 idle-cfg-set \ Allow core clock shutdown and core powerdown
+
+ \ Also set the 8000 bit to keep L2 cache powered on
+ h# 01 cc4-set \ Mask off GIC interrupts
+ wfi
+;
+[then]
+
+create wakeup-masks \ Bits in MPMU+0 and MPMU+1000, indexed by wakeup port number
+ h# 0080.0000 , h# 0040.0000 , h# 0020.0000 , h# 0010.0000 ,
+ h# 0004.0000 , h# 0002.0000 , h# 0001.0000 , h# 0000.8000 ,
+
+: port>bit ( port# -- ) wakeup-masks swap na+ @ ;
+
+: pcr! ( value -- ) dup h# 00 mpmu! h# 1000 mpmu! ;
+: pcr-set ( mask -- ) dup h# 00 mpmu-set h# 1000 mpmu-set ;
+: pcr-clr ( mask -- ) dup h# 00 mpmu-clr h# 1000 mpmu-clr ;
+: wucrm-set ( mask -- ) dup h# 4c mpmu-set h# 104c mpmu-set ;
+
+\ We enable the wakeup port in both the SP and PJ registers, thus avoiding
+\ any ambiguity about whether the bits are ORed or ANDed
+: wakeup-port-on ( port# -- )
+ dup port>bit pcr-clr
+ 1 swap lshift wucrm-set
+;
+: deep-sleep-on ( -- )
+ \ Start with all wakeup ports masked off, enable specific ones later
+ h# beffe000 pcr! \ AXISD, SPLEN, SPSD, DDRCORSD, APBSD, RSVD, VCXOSD, MSASLPEN, UDR_POWER_OFF_EN \ Step 11
+;
+
+\ D2_L2_PWD 462
+\ C2_L1_L2_PWD 820004e2 \ 80 might be L2 power down bit
+\ C2_L1_PWD 82000462 \ Power off SRAM by setting 40 bit
+\ C2_L1R_L2_PWD 820004a2 \ Retain SRAM by not setting 40 bit
+: set-idle ( mask -- )
+ h# e2 and ( mask' ) \ Mask with 62 for other cores
+ idle-cfg@ h# 0def.fc1d and ( mask kept )
+ or idle-cfg! ( )
+;
+: rtc-wakeup-on ( -- )
+ h# 2.0000 wucrm-set
+ 4 wakeup-port-on
+;
+code outer-flush-all ( -- )
+c;
+code flush-cache-all
+ mcr p15, 0, r0, cr8, cr5, 0 \ instruction tlb
+ mcr p15, 0, r0, cr8, cr6, 0 \ data tlb
+ mcr p15, 0, r0, cr8, cr7, 0 \ unified tlb
+
+ mcr p15, 0, r0, cr7, cr5, 0 \ invalid I cache
+ mcr p15, 0, r0, cr7, cr5, 6 \ invalid branch predictor array
+ mcr p15, 0, r0, cr7, cr5, 4 \ instruction barrier
+ mcr p15, 0, r0, cr7, cr14, 0 \ flush entire d cache
+ mcr p15, 0, r0, cr7, cr5, 4 \ flush prefetch buffer
+ isb
+ dsb
+c;
+code fw-off
+ mrc p15, 0, r0, cr1, cr0, 1
+ bic r0,r0,1
+ mcr p15, 0, r0, cr1, cr0, 1
+ isb
+ dsb
+c;
+code fw-on
+ mrc p15, 0, r0, cr1, cr0, 1
+ orr r0,r0,1
+ mcr p15, 0, r0, cr1, cr0, 1
+ isb
+ dsb
+c;
+code mp-off
+ mrc p15, 0, r0, cr1, cr0, 1
+ bic r0,r0,#0x40
+ mcr p15, 0, r0, cr1, cr0, 1
+ isb
+ dsb
+c;
+code mp-on
+ mrc p15, 0, r0, cr1, cr0, 1
+ orr r0,r0,#0x40
+ mcr p15, 0, r0, cr1, cr0, 1
+ isb
+ dsb
+c;
+: wakeup-irqs-on ( -- )
+\ 2f is high priority (f), directed to PJ (20)
+\ h# 2f h# 82010 io! \ IRQ 4 - PMIC
+ h# 2f h# 82014 io! \ IRQ 5 - RTC
+\ h# 2f h# 820c4 io! \ IRQ 49 - GPIO
+;
+: wakeup-irqs-off ( -- )
+\ h# 0 h# 82010 io! \ IRQ 4 - PMIC
+ h# 0 h# 82014 io! \ IRQ 5 - RTC
+\ h# 0 h# 820c4 io! \ IRQ 49 - GPIO
+;
+: global-irqs-off ( -- )
+ \ disable global irq of ICU for MP1, MP2, MM
+ 1 h# 82110 io! \ ICU_GBL_IRQ1_MSK
+ 1 h# 82114 io! \ ICU_GBL_IRQ2_MSK
+ 1 h# 8410c io! \ ICU_GBL_IRQ3_MSK
+ 1 h# 84110 io! \ ICU_GBL_IRQ4_MSK
+ 1 h# 84114 io! \ ICU_GBL_IRQ5_MSK
+ 1 h# 84190 io! \ ICU_GBL_IRQ6_MSK
+;
+
+0 value apcr
+: setup-sleep-state ( -- )
+ sp-c1-on
+
+ make-ddr3-recal-tables
+
+ h# 1000 mpmu@ to apcr
+
+ deep-sleep-on
+ rtc-wakeup-on
+
+ h# 462 set-idle \ D2_L2_PWD
+
+ \ Workaround - shut down AT clock
+ h# 8000.0000 idle-cfg-clr
+
+ \ I don't think we need this because L2 is off
+ \ h# 8000 cc4-set \ workaround: keep SL2 power on
+
+ wakeup-irqs-on
+
+ flush-cache-all
+ \ outer-flush-all
+
+ \ fw-off
+ \ mp-off
+;
+: restore-run-state ( -- )
+ wakeup-irqs-off
+
+ \ fw-on
+ \ mp-on
+
+ \ I don't think we need this because L2 is off
+ \ h# 8000 cc4-clr \ workaround: keep SL2 power on
+
+ global-irqs-off
+
+ apcr h# 1000 mpmu!
+
+ h# 8000.0000 idle-cfg-set \ Workaround: restore AT clock
+
+ 0 set-idle \ C1_INCG
+;
+
+alias do-wfi wfi
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2012 FirmWorks
+\
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
Modified: cpu/arm/olpc/build-fw.fth
==============================================================================
--- cpu/arm/olpc/build-fw.fth Sun Sep 2 01:42:57 2012 (r3269)
+++ cpu/arm/olpc/build-fw.fth Sun Sep 2 01:57:24 2012 (r3270)
@@ -562,7 +562,16 @@
fload ${BP}/cpu/x86/pc/olpc/strokes.fth
fload ${BP}/cpu/x86/pc/olpc/plot.fth
+fload ${BP}/cpu/arm/mmp2/showirqs.fth
+fload ${BP}/cpu/arm/mmp2/wakeups.fth
+
+[ifdef] mmp3
+fload ${BP}/cpu/arm/mmp3/dramtable.fth
+[then]
+[ifdef] mmp2
fload ${BP}/cpu/arm/mmp2/dramrecal.fth
+[then]
+fload ${BP}/cpu/arm/olpc/suspend.fth
code halt ( -- ) wfi c;
Added: cpu/arm/olpc/suspend.fth
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ cpu/arm/olpc/suspend.fth Sun Sep 2 01:57:24 2012 (r3270)
@@ -0,0 +1,218 @@
+purpose: Common uspend/resume code for OLPC XO ARM plaforms
+
+: apbc-clr-rst ( offset -- ) 4 swap +apbc io-clr ;
+: apbc-set-rst ( offset -- ) 4 swap +apbc io-set ;
+
+: disable-apbc-clks ( -- )
+ \ 3 h# 38 +apbc io-clr \ GPIO
+ 3 h# 74 +apbc io-clr \ MPMU
+ 3 h# 78 +apbc io-clr \ IPC
+ 3 h# 90 +apbc io-clr \ THSENS1
+
+ \ h# 38 apbc-set-rst
+ \ h# 74 apbc-set-rst \ MPMU - resetting this kills TIMER2, used by the SP PS/2
+ h# 78 apbc-set-rst \ IPC
+ h# 90 apbc-set-rst \ THSENS1
+;
+: enable-apbc-clks ( -- )
+ \ 3 h# 38 +apbc io-set \ GPIO
+ 3 h# 74 +apbc io-set \ MPMU
+ 3 h# 78 +apbc io-set \ IPC
+ 3 h# 90 +apbc io-set \ THSENS1
+
+ \ h# 38 apbc-clr-rst
+ h# 74 apbc-clr-rst \ MPMU
+ h# 78 apbc-clr-rst \ IPC
+ h# 90 apbc-clr-rst \ THSENS1
+;
+: disable-scu-clks ( -- )
+ 0 h# 64 +scu io! \ SCU_AXIFAB_CKGT_CTRL0 - Close AXI fabric clock gate
+ 0 h# 68 +scu io! \ SCU_AXIFAB_CKGT_CTRL1
+ h# f0 h# 1c +scu io-set \ SCU_MCB_CONF
+;
+: enable-scu-clks ( -- )
+ h# 3003003 h# 64 +scu io! \ SCU_AXIFAB_CKGT_CTRL0 - Open AXI fabric clock gate
+ h# 0303030 h# 68 +scu io! \ SCU_AXIFAB_CKGT_CTRL1
+ h# f0 h# 1c +scu io-clr \ SCU_MCB_CONF
+;
+: disable-apmu-clks ( -- )
+ h# 1b h# 54 +pmua io-clr \ PMUA_SDH0_CLK_RES_CTRL
+ h# 1b h# 58 +pmua io-clr \ PMUA_SDH1_CLK_RES_CTRL
+ h# 1b h# e8 +pmua io-clr \ PMUA_SDH2_CLK_RES_CTRL
+ h# 1b h# d4 +pmua io-clr \ PMUA_SMC_CLK_RES_CTRL
+ h# 3f h# 60 +pmua io-clr \ PMUA_NF_CLK_RES_CTRL
+ h# 3f h# d8 +pmua io-clr \ PMUA_MSPRO_CLK_RES_CTRL - XO does not use MSPRO
+ h# 12 h# 10c +pmua io-clr \ PMUA_AUDIO_CLK_RES_CTRL
+ h# 1fffd h# dc +pmua io-clr \ PMUA_GLB_CLK_RES_CTRL
+\ 0 h# 68 pmua! \ PMUA_WTM_CLK_RES_CTRL
+ h# 9 h# 5c +pmua io-clr \ PMUA_USB_CLK_RES_CTRL
+;
+: enable-apmu-clks ( -- )
+ h# 1b h# 54 +pmua io-set \ PMUA_SDH0_CLK_RES_CTRL
+ h# 1b h# 58 +pmua io-set \ PMUA_SDH1_CLK_RES_CTRL
+ h# 1b h# e8 +pmua io-set \ PMUA_SDH2_CLK_RES_CTRL
+ h# 1b h# d4 +pmua io-set \ PMUA_SMC_CLK_RES_CTRL \ ??? what is this and why is it on?
+ h# 3f h# 60 +pmua io-set \ PMUA_NF_CLK_RES_CTRL \ Should this be on?
+\ h# 3f h# d8 +pmua io-set \ PMUA_MSPRO_CLK_RES_CTRL
+ h# 12 h# 10c +pmua io-set \ PMUA_AUDIO_CLK_RES_CTRL
+ h# 1fffd h# dc +pmua io-set \ PMUA_GLB_CLK_RES_CTRL
+\ h# 1b h# 68 pmua! \ PMUA_WTM_CLK_RES_CTRL
+ h# 9 h# 5c +pmua io-set \ PMUA_USB_CLK_RES_CTRL
+;
+: pll2? ( -- flag ) h# 34 mpmu@ h# 100 and 0<> ;
+: disable-mpmu-clks ( -- )
+ pll2? if h# e010 else h# a010 then ( cgr-value )
+ dup h# 1024 mpmu! \ MPMU_CGR_PJ
+ h# 0024 mpmu! \ MPMU_CGR_SP
+
+\ h# 2000.0000 h# 414 +mpmu io-clr \ MPMU_PLL2_CTRL1
+ h# 8000.0000 h# 0040 +mpmu io-clr \ MPMU_ISCCR1
+ h# 8000.0000 h# 0044 +mpmu io-clr \ MPMU_ISCCR2
+;
+: enable-mpmu-clks ( -- )
+ h# dffe.fffe h# 1024 mpmu! \ MPMU_ACGR
+\ h# 2000.0000 h# 0414 +mpmu io-set \ MPMU_PLL2_CTRL1
+ h# 8000.0000 h# 0040 +mpmu io-set \ MPMU_ISCCR1
+ h# 8000.0000 h# 0044 +mpmu io-set \ MPMU_ISCCR2
+;
+: disable-twsi-clks ( -- )
+ \ set RST in APBC_TWSIx_CLK_RST registers
+
+[ifdef] notdef
+ \ just disable TWSI1 clk rather than reset it since it's needed to access PMIC onkey
+ \ when system is waken up from low power mode */
+ 0 4 +apbc io! \ Disable TWSI1 clock
+[else]
+ h# 04 apbc-set-rst \ TWSI1
+[then]
+ h# 08 apbc-set-rst \ TWSI2
+ h# 0c apbc-set-rst \ TWSI3
+ h# 10 apbc-set-rst \ TWSI4
+ h# 7c apbc-set-rst \ TWSI5
+ h# 80 apbc-set-rst \ TWSI6
+;
+: enable-twsi-clks ( -- )
+[ifdef] notdef
+ 3 4 +apbc io! \ Enable TWSI1 clock
+[else]
+ h# 04 apbc-clr-rst \ TWSI1
+[then]
+ h# 08 apbc-clr-rst \ TWSI2
+ h# 0c apbc-clr-rst \ TWSI3
+ h# 10 apbc-clr-rst \ TWSI4
+ h# 7c apbc-clr-rst \ TWSI5
+ h# 80 apbc-clr-rst \ TWSI6
+;
+: disable-clks ( -- )
+ disable-twsi-clks
+ disable-apbc-clks
+ disable-scu-clks
+ disable-apmu-clks
+ disable-mpmu-clks
+;
+: enable-clks ( -- )
+ enable-mpmu-clks
+ enable-apmu-clks
+ enable-scu-clks
+ enable-apbc-clks
+ enable-twsi-clks
+;
+
+[ifdef] soc-en-kbd-pwr-gpio#
+: keyboard-power-on ( -- ) soc-en-kbd-pwr-gpio# gpio-clr ;
+: keyboard-power-off ( -- ) soc-en-kbd-pwr-gpio# gpio-set ;
+[else]
+: keyboard-power-on ( -- ) ;
+: keyboard-power-off ( -- ) ;
+[then]
+: wlan-power-on ( -- ) en-wlan-pwr-gpio# gpio-set ;
+: wlan-power-off ( -- ) en-wlan-pwr-gpio# gpio-clr h# 040 en-wlan-pwr-gpio# af! h# 040 wlan-pd-gpio# af! h# 040 wlan-reset-gpio# af! ;
+: wlan-stay-on ( -- ) h# 140 en-wlan-pwr-gpio# af! h# 140 wlan-pd-gpio# af! h# 140 wlan-reset-gpio# af! ;
+
+0 value sleep-mask
+: screen-sleep
+ sleep-mask 1 and if \ DCON power down
+ dcon-freeze
+ else
+ " dcon-suspend" $call-dcon
+ then
+ " sleep" $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
+ sleep-mask 4 and if
+ wlan-stay-on
+ else
+ " /wlan" " sleep" execute-device-method drop
+ wlan-power-off
+ then \ saves 100 mW
+;
+: screen-wake ( -- )
+ sleep-mask 4 and 0= if
+ wlan-power-on
+ " /wlan" " wake" execute-device-method drop
+ then
+ sleep-mask 2 and 0= if keyboard-power-on then
+ " clr-ack" $call-ec
+ " wake" $call-screen
+ sleep-mask 1 and if \ DCON power up
+ dcon-unfreeze
+ else
+ " dcon-resume" $call-dcon
+ then
+;
+
+: stdin-idle-on ['] safe-idle to stdin-idle d# 15 enable-interrupt ;
+: stdin-idle-off ['] noop to stdin-idle ( install-uart-io ) d# 15 disable-interrupt ;
+
+: timers-sleep ( -- )
+ 0 h# 14048 io! \ Disable interrupts from the tick timer
+ 7 h# 1407c io! \ Clear any pending interrupts
+ h# f disable-interrupt \ Block timer interrupt
+;
+: timers-wake ( -- )
+ 1 h# 14048 io! \ Enable interrupts from the tick timer
+ 7 h# 1407c io! \ Clear any pending interrupts
+ h# f enable-interrupt \ Unblock timer interrupt
+ reschedule-tick
+;
+
+: platform-off ( -- )
+ disable-interrupts
+ suspend-usb
+ timers-sleep
+
+ screen-sleep
+ stdin-idle-off
+
+ disable-clks
+ power-islands-off
+;
+
+: platform-on ( -- )
+ power-islands-on
+
+ enable-clks
+
+ stdin-idle-on
+
+ screen-wake
+ timers-wake
+ resume-usb
+ enable-interrupts
+ init-thermal-sensor
+;
+
+: str ( -- )
+ platform-off
+
+ setup-sleep-state
+ do-wfi
+ restore-run-state
+
+ platform-on
+;
+
+: strp ( -- ) ec-rst-pwr str ec-max-pwr .d ." mW " soc .% space ;
More information about the openfirmware
mailing list