Author: wmb Date: Wed Aug 29 02:48:20 2012 New Revision: 3236 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/3236
Log: OLPC ARM - implemented a generic mechanism for enabling and disabling device clocks based on the "clocks" property. Important new words are "my-clock-on" and "my-clock-off", which can be called from a device instance in a node that has a "clocks" property.
Modified: cpu/arm/mmp2/apbc.fth cpu/arm/mmp2/pmua.fth
Modified: cpu/arm/mmp2/apbc.fth ============================================================================== --- cpu/arm/mmp2/apbc.fth Wed Aug 29 02:12:35 2012 (r3235) +++ cpu/arm/mmp2/apbc.fth Wed Aug 29 02:48:20 2012 (r3236) @@ -89,4 +89,11 @@ h# 94 +int h# 7 +int h# 3 +int d# 26,000,000 +int \ 35 CORESIGHT " clock-enable-registers" property
+: on/off ( on? clock# -- ) + get-reg&masks if drop exit then ( on? set-mask clr-mask reg ) + >r r@ apbc@ and ( on? set-mask regval r: reg ) + rot if or else nip then ( regval' r: reg ) + r> apbc! +; + end-package
Modified: cpu/arm/mmp2/pmua.fth ============================================================================== --- cpu/arm/mmp2/pmua.fth Wed Aug 29 02:12:35 2012 (r3235) +++ cpu/arm/mmp2/pmua.fth Wed Aug 29 02:48:20 2012 (r3236) @@ -2,6 +2,31 @@ : clocks 2 ; previous definitions
+\ Given a clock index, retrieve the register offset and set/clear masks +\ from the clock-enable-registers property in the device node from which +\ this is called. The format and usage of clock-enable-registers is +\ specific to PXA/MMP SoCs, but might be useful for any hardware whose +\ clock enabling can be expressed by clearing some register bits and +\ setting others. + +: get-reg&masks ( clock# -- set-mask ~clr-mask reg false | true ) + " clock-enable-registers" get-property if ( clock# ) + drop true exit ( true -- ) + then ( clock# propval$ ) + + \ Offset into clock-enable-registers array + rot h# 10 * ( propval$ offset ) + 2dup <= if ( propval$ offset ) + 3drop true exit ( true -- ) + then ( propval-adr$ offset ) + /string ( propval-adr$' ) + + decode-int >r ( propval-adr$' r: reg ) + decode-int invert >r ( propval-adr$' r: reg ~clr-mask ) + get-encoded-int r> r> ( set-mask ~clr-mask reg ) + false ( set-mask ~clr-mask reg false ) +; + 0 0 " " " /" begin-package " pmua" name " mrvl,pxa-apmu" +compatible @@ -96,4 +121,132 @@ [then] " clock-enable-registers" property
+[ifdef] notdef + " clock-enable-registers" get-property if ( on? clock# ) + 2drop exit ( -- ) + then ( on? clock# propval$ ) + + \ Offset into clock-enable-registers array + rot h# 10 * ( on? propval$ offset ) + 2dup <= if ( on? propval$ offset ) + 4drop exit ( -- ) + then ( on? propval-adr$ offset ) + /string ( on? propval-adr$' ) + + \ Get register offset + decode-int >r ( on? propval-adr$' r: reg-offset ) + + \ Apply the clear mask to the register value + decode-int invert ( on? propval-adr$' clr-mask r: reg-offset ) + r@ pmua@ and ( on? propval-adr$' regval r: reg-offset ) + -rot ( on? regval propval-adr$ r: reg-offset ) + + \ Apply the set mask if the clock is being turned on + 3 roll if ( regval propval-adr$ r: reg-offset ) + get-encoded-int or ( regval' r: reg-offset ) + else ( regval propval-adr$ r: reg-offset ) + 2drop ( regval r: reg-offset ) + then ( regval r: reg-offset ) + + \ Write back the modified register value + r> pmua! ( ) +[then] + +: generic-on/off ( on? clock# -- ) + get-reg&masks if drop exit then ( on? set-mask clr-mask reg ) + >r r@ pmua@ and ( on? set-mask regval r: reg ) + rot if or else nip then ( regval' r: reg ) + r> pmua! +; + +[ifdef] mmp3 +: ccic-isp-island-off ( -- ) + h# 600 h# 1fc pmua! \ Isolation enabled + \ Fiddle with ISP_CLK_RES_CTRL here to turn off ISP engine + h# 000 h# 1fc pmua! \ Power off +; + +: ccic-isp-island-on ( -- ) + \ set ISP regs to the default value + 0 h# 50 pmua! + 0 h# 1fc pmua! + + \ Turn on the CCIC/ISP power switch + h# 200 h# 1fc pmua! \ Partially powered + d# 10 ms + h# 600 h# 1fc pmua! \ Fully powered + d# 10 ms + h# 700 h# 1fc pmua! \ Isolation disabled + +[ifdef] notdef + \ Empirically, the memory redundancy and SRAMs are unnecessary + \ for camera-only (no ISP) operation. + + \ Start memory redundacy repair + 4 h# 224 pmua-set \ PMUA_ISP_CLK_RES_CTRL + begin d# 10 ms h# 224 pmua@ 4 and 0= until + + \ Enable dummy clocks to the SRAMS + h# 10 h# 1e0 pmua-set \ PMUA_ISLD_CI_PDWN_CTRL + d# 200 ms + h# 10 h# 1e0 pmua-clr +[then] + + \ Enable ISP clocks here if you want to use the ISP + \ 8 h# 224 pmua-set \ Enable AXI clock in PMUA_ISP_CLK_RES_CTRL + \ h# f00 h# 200 h# 224 pmua-fld \ Clock divider + \ h# c0 h# 40 h# 224 pmua-fld \ CLock source + \ h# 10 h# 224 pmua-set + + \ enable CCIC clocks + h# 8238 h# 50 pmua-set + + \ Deassert ISP clocks here if you want to use the ISP + \ XXX should these be pmua-clr ? + \ 1 h# 224 pmua-set \ AXI reset + \ 2 h# 224 pmua-set \ ISP SW reset + \ h# 10000 h# 50 pmua-set \ CCIC1 AXI Arbiter reset + + \ De-assert CCIC Resets + h# 10107 h# 50 pmua-set \ XXX change to 107 +; +[then] + +: ccic-on/off ( on? -- ) + if + [ifdef] mmp3 ccic-isp-island-on [then] + + \ Enable clocks + h# 3f h# 28 pmua! \ Clock gating - AHB, Internal PIXCLK, AXI clock always on + h# 0003.805b h# 50 pmua! \ PMUA clock config for CCIC - /1, PLL1/16, AXI arb, AXI, perip on + else + h# 3f h# 50 pmua-clr + [ifdef] mmp3 ccic-isp-island-off [then] + then +; + +: on/off ( on? clock# -- ) + \ Special-case devices that need more elaborate on/off procedures + dup 2 = if \ CCIC ( on? clock# ) + drop ccic-on/off exit ( -- ) + then ( on? clock# ) + + generic-on/off +; + end-package + +\ This is a general-purpose mechanism for enabling/disabling a clock +\ that is described by a "clocks" property in the device node. The +\ property value is a phandle and an index, as used in Linux. + +: my-clock-on/off ( on? -- ) + " clocks" get-my-property abort" No clocks property" ( on? propval$ ) + decode-int >r ( on? propval$ r: phandle ) + get-encoded-int ( on? clock# r: phandle ) + r> push-package ( on? clock# ) + " on/off" package-execute ( ) + pop-package ( ) +; +: my-clock-off ( -- ) false my-clock-on/off ; +: my-clock-on ( -- ) true my-clock-on/off ;
openfirmware@openfirmware.info