[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