Author: wmb Date: Fri Aug 31 00:57:10 2012 New Revision: 3255 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/3255
Log: OLPC ARM - Created a proper device-tree factoring of the OFW TWSI driver with the goal of replacing the present global version. The new version has methods in /i2c@N nodes, delegating the work to code in /packages/twsi . The global version is still present and is still used for RTC and touchscreen. The codec and accelerometer drivers have been converted over to use the new code. This resolves OLPC Trac #12072 (there was a simpler way to fix 12072, by renaming one of the accelerometer nodes, but this refactoring needed to be done eventually.)
Added: cpu/arm/mmp2/twsi-node.fth cpu/arm/mmp2/twsi-package.fth Modified: cpu/arm/olpc/accelerometer.fth cpu/arm/olpc/prefw.fth cpu/arm/olpc/rtc.fth cpu/arm/olpc/sound.fth cpu/arm/olpc/twsi-i2c.fth
Added: cpu/arm/mmp2/twsi-node.fth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/arm/mmp2/twsi-node.fth Fri Aug 31 00:57:10 2012 (r3255) @@ -0,0 +1,92 @@ +\ See license at end of file +purpose: Create a device node for a TWSI device based on stack arguments + +\ Put the following on the stack prior to floading this file: +\ ( phys-addr clk irq mux? fast? linux-unit# ) +\ E.g: h# d4011000 1 7 false true 2 + +root-device +new-device + +" linux,unit#" integer-property ( baseadr clock# irq# muxed-irq? fast? ) +" i2c" name ( baseadr clock# irq# muxed-irq? fast? ) +" mrvl,mmp-twsi" +compatible ( baseadr clock# irq# muxed-irq? fast? ) +[if] 0 0 " mrvl,i2c-fast-mode" property [then] ( baseadr clock# irq# muxed-irq? ) +[if] + " /interrupt-controller/interrupt-controller@158" encode-phandle " interrupt-parent" property +[then] ( baseadr clock# irq# ) +" interrupts" integer-property ( baseadr clock# ) + +" /apbc" encode-phandle rot encode-int encode+ " clocks" property +h# 1000 reg ( ) + +1 " #address-cells" integer-property +1 " #size-cells" integer-property + +: decode-unit ( adr len -- n ) parse-int ; +: encode-unit ( n -- adr len ) push-hex (u.) pop-base ; + +0 instance value twsi +0 instance value my-va + +: $call-twsi ( ? -- ? ) twsi $call-method ; + +: open ( -- okay? ) + my-clock-on + + " " " twsi" $open-package to twsi + twsi 0= if false exit then + + my-unit h# 40 " map-in" $call-parent to my-va + + true +; +: close ( -- ) + my-va h# 40 " map-out" $call-parent + + twsi close-package + my-clock-off +; + +1 " #address-cells" integer-property +1 " #size-cells" integer-property + +: set-address ( target -- ) my-va " set-address" $call-twsi ; + +: bytes-out-in ( out ... #outs #ins -- in ... ) " bytes-out-in" $call-twsi ; + +: get ( #bytes -- bytes ... ) 0 swap bytes-out-in ; + +: byte@ ( -- ) " byte@" $call-twsi ; +: byte! ( -- ) " byte!" $call-twsi ; +: bytes-out ( byte .. #bytes -- ) " bytes-out" $call-twsi ; + +\ Useful range is 25K .. 400K - 100K and 400K are typical +: set-bus-speed ( hz -- ) " set-bus-speed" $call-twsi ; + +finish-device +device-end + +\ 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/mmp2/twsi-package.fth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/arm/mmp2/twsi-package.fth Fri Aug 31 00:57:10 2012 (r3255) @@ -0,0 +1,189 @@ +purpose: Support package driver for Two Wire Serial Interface on Marvell Armada 610 + +support-package: twsi + +0 instance value twsi-chip +0 instance value slave-address + +: dbr@ ( -- n ) twsi-chip h# 08 + rl@ ; +: cr@ ( -- n ) twsi-chip h# 10 + rl@ ; +: sr@ ( -- n ) twsi-chip h# 18 + rl@ ; +: sar@ ( -- n ) twsi-chip h# 20 + rl@ ; +: lcr@ ( -- n ) twsi-chip h# 28 + rl@ ; +: wcr@ ( -- n ) twsi-chip h# 30 + rl@ ; +: dbr! ( n -- ) twsi-chip h# 08 + rl! ; +: cr! ( n -- ) twsi-chip h# 10 + rl! ; +: sr! ( n -- ) twsi-chip h# 18 + rl! ; +: sar! ( n -- ) twsi-chip h# 20 + rl! ; +: lcr! ( n -- ) twsi-chip h# 28 + rl! ; +: wcr! ( -- n ) twsi-chip h# 30 + rl! ; + +\ Bit defines + +h# 4000 constant bbu_ICR_UR \ Unit Reset bit +h# 0040 constant bbu_ICR_IUE \ ICR TWSI Unit enable bit +h# 0020 constant bbu_ICR_SCLE \ ICR TWSI SCL Enable bit +h# 0010 constant bbu_ICR_MA \ ICR Master Abort bit +h# 0008 constant bbu_ICR_TB \ ICR Transfer Byte bit +h# 0004 constant bbu_ICR_ACKNAK \ ICR ACK bit +h# 0002 constant bbu_ICR_STOP \ ICR STOP bit +h# 0001 constant bbu_ICR_START \ ICR START bit +h# 0040 constant bbu_ISR_ITE \ ISR Transmit empty bit +h# 0400 constant bbu_ISR_BED \ Bus Error Detect bit + +h# 1000 constant BBU_TWSI_TimeOut \ TWSI bus timeout loop counter value + +d# 26 constant ftwsi-mhz \ +d# 1400 constant tlow-nsec \ The I2C spec calls for Tlow >= 1300 ns +ftwsi-mhz tlow-nsec d# 1000 */ constant tlow-ticks + +bbu_ICR_IUE bbu_ICR_SCLE or value cr-set \ bits to maintain as set +: twsi-on ( -- ) + cr-set bbu_ICR_UR or cr! \ Reset the unit + cr-set cr! \ Release the reset + 0 sar! \ Set host slave address + 0 cr! \ Disable interrupts + \ The COUNT field of TWSI_WCR establishes a minimum value for the SCL low time. + \ The minimum Tlow is the clock period * (12 + 2*COUNT) + wcr@ h# 1f invert and tlow-ticks d# 12 - 2/ or wcr! \ Setup and hold times +; + +: twsi-run ( extra-flags -- ) + cr-set or bbu_ICR_TB or cr! ( ) + + h# 1000 0 do + cr@ bbu_ICR_TB and 0= if unloop exit then + loop + true abort" TWSI timeout" +; +: twsi-putbyte ( byte extra-flags -- ) + swap dbr! ( extra-flags ) + twsi-run +; +: twsi-getbyte ( extra-flags -- byte ) + twsi-run ( ) + dbr@ ( byte ) + sr@ sr! ( byte ) +; + +: twsi-start ( slave-address -- ) + bbu_ICR_START twsi-putbyte ( ) + sr@ bbu_ISR_BED and if ( ) + bbu_ISR_BED sr! ( ) + cr-set bbu_ICR_MA or cr! ( ) + true abort" TWSI bus error" + then ( ) +; + +external + +: write-bytes ( adr len -- ) + dup 0= if 2drop exit then ( adr len ) + slave-address twsi-start ( adr len ) + + 1- 0 ?do dup c@ 0 twsi-putbyte 1+ loop ( adr' ) + c@ bbu_ICR_STOP twsi-putbyte ( ) +; + +: read-bytes ( adr len -- ) + dup 0= if 2drop exit then ( adr len ) + slave-address 1 or twsi-start ( adr len ) + + 1- 0 ?do 0 twsi-getbyte over c! 1+ loop ( adr' ) + bbu_ICR_STOP bbu_ICR_ACKNAK or twsi-getbyte swap c! ( ) +; + +: set-address ( slave chip -- ) \ Channel numbers range from 1 to 6 + to twsi-chip + 2* to slave-address + twsi-on +; + +: bytes-out-in ( register-address .. #reg-bytes #data-bytes -- data-byte ... ) + >r ( reg-adr .. #regs r: #data-bytes ) + ?dup if ( reg-adr .. #regs slave-address r: #data-bytes ) + slave-address ( reg-adr .. #regs slave-address r: #data-bytes ) + twsi-start ( reg-adr .. #regs r: #data-bytes ) + + \ Send register addresses + 0 ?do 0 twsi-putbyte loop ( r: #data-bytes ) + + \ If no result data requested, quit now + r@ 0= if ( r: #data-bytes ) + r> drop ( ) + cr-set bbu_ICR_STOP or cr! ( ) + exit + then ( r: #data-bytes ) + then ( r: #data-bytes ) + + r> ?dup if ( #data-bytes ) + \ Send the read address with a (or another) start bit + slave-address 1 or bbu_ICR_START twsi-putbyte ( #data-bytes ) + sr@ sr! \ clear ITE and IRF status bits ( #data-bytes ) + \ Bug on line 367 of bbu_TWSI.s - writes SR without first reading it + + 1- 0 ?do 0 twsi-getbyte loop ( bytes ) + + \ Set the stop bit on the final byte + bbu_ICR_STOP bbu_ICR_ACKNAK or twsi-getbyte ( bytes ) + then +; + +: bytes-out ( byte .. #bytes -- ) + slave-address twsi-start ( byte .. #bytes ) + + 1- 0 ?do 0 twsi-putbyte loop ( byte ) + bbu_ICR_STOP twsi-putbyte ( ) +; + +: byte@ ( reg -- byte ) 1 1 bytes-out-in ; +: byte! ( byte reg -- ) 2 bytes-out ; + +: set-bus-standard cr-set h# 18000 invert and to cr-set ; +: set-bus-fast cr-set h# 18000 invert and h# 8000 or to cr-set ; + +: set-bus-speed ( hz -- ) \ Useful range is 25K .. 400K - 100K and 400K are typical + ftwsi-mhz d# 1,000,000 2 pick */ ( hz ticks ) + swap d# 100,000 <= if ( ticks ) + \ In slow mode, Thi = Tclk * (8+slv), Tlow = Tclk * (1+slv) + 9 - 2/ 1+ ( slv ) + lcr@ h# 1ff invert and or lcr! ( ) + set-bus-standard ( ) + else ( ticks ) + \ (The information below is poorly documented and was determined empirically) + \ In fast mode, Thi = Tclk * (10+flv), Tlo = Tclk * max(1+flv, tlow_ticks)) + dup d# 11 - 2/ 1+ tlow-ticks max ( ticks ticks-low ) + - d# 10 - ( flv ) + 9 lshift lcr@ h# 3.fe00 invert and or lcr! ( ) + set-bus-fast ( ) + then ( ) +; + +: open ( -- okay? ) true ; +: close ( -- ) ; + +end-support-package + +\ 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/accelerometer.fth ============================================================================== --- cpu/arm/olpc/accelerometer.fth Fri Aug 31 00:10:06 2012 (r3254) +++ cpu/arm/olpc/accelerometer.fth Fri Aug 31 00:57:10 2012 (r3255) @@ -1,15 +1,16 @@ -hex -0 0 " " " /twsi" begin-package +dev /i2c@d4034000 \ TWSI6 +new-device + " accelerometer" name +" lis3lv02d" +compatible
\ reg is set dynamically by probing to find which chip is present -\ my-address my-space encode-phys " reg" property
\ This is for the stand-alone accelerometers LIS3DHTR and LIS33DETR
\ We could call this just once in open if we had a TWSI parent node -: acc-reg@ ( reg# -- b ) 1 1 " smbus-out-in" $call-parent ; -: acc-reg! ( b reg# -- ) 2 0 " smbus-out-in" $call-parent ; +: acc-reg@ ( reg# -- b ) " byte@" $call-parent ; +: acc-reg! ( b reg# -- ) " byte!" $call-parent ; : ctl1! ( b -- ) h# 20 acc-reg! ; : ctl4! ( b -- ) h# 23 acc-reg! ; : accelerometer-on ( -- ) h# 47 ctl1! ; @@ -17,7 +18,7 @@ : wext ( b -- n ) dup h# 8000 and if h# ffff0000 or then ; : acceleration@ ( -- x y z ) begin h# 27 acc-reg@ h# 08 and until \ wait for data available - h# 0a8 1 6 " smbus-out-in" $call-parent ( xl xh yl yh zl zh ) + h# 0a8 1 6 " bytes-out-in" $call-parent ( xl xh yl yh zl zh ) bwjoin wext 5 >>a ( xl xh yl yh z ) >r ( xl xh yl yh r: z ) bwjoin wext 5 >>a ( xl xh y r: z ) @@ -142,7 +143,7 @@ ;
: probe ( -- ) - h# 3a 6 " set-address" $call-parent + h# 1d " set-address" $call-parent d# 25,000 " set-bus-speed" $call-parent \ XO-1.75 B1 lacks pullups SCL SDA ['] accelerometer-on catch if \ The attempt to talk at the old address failed, so we assume the new chip @@ -150,7 +151,7 @@ d# 400,000 to bus-speed d# 50 to min-x d# 50 to min-y d# 50 to min-z d# 150 to max-x d# 150 to max-y d# 450 to max-z - h# 19 6 encode-phys " reg" property + h# 19 1 reg ['] lis3dhtr-selftest to lis-selftest else accelerometer-off @@ -159,12 +160,13 @@ d# 25,000 to bus-speed d# 20 to min-x d# 20 to min-y d# 20 to min-z d# 400 to max-x d# 400 to max-y d# 400 to max-z - h# 1d 6 encode-phys " reg" property + h# 1d 1 reg ['] lis33de-selftest to lis-selftest then ;
-end-package +finish-device +device-end
stand-init: Accelerometer " /accelerometer" " probe" execute-device-method drop
Modified: cpu/arm/olpc/prefw.fth ============================================================================== --- cpu/arm/olpc/prefw.fth Fri Aug 31 00:10:06 2012 (r3254) +++ cpu/arm/olpc/prefw.fth Fri Aug 31 00:57:10 2012 (r3255) @@ -232,6 +232,8 @@ fload ${BP}/cpu/arm/mmp2/twsi.fth fload ${BP}/cpu/arm/mmp2/mfpr.fth
+fload ${BP}/cpu/arm/mmp2/twsi-package.fth + \ Uninstall the diag menu from the general user interface vector \ so exiting from emacs doesn't invoke the diag menu. ' quit to user-interface
Modified: cpu/arm/olpc/rtc.fth ============================================================================== --- cpu/arm/olpc/rtc.fth Fri Aug 31 00:10:06 2012 (r3254) +++ cpu/arm/olpc/rtc.fth Fri Aug 31 00:57:10 2012 (r3255) @@ -1,9 +1,10 @@ purpose: Driver for external IDT1388 RTC chip on XO-1.75
-0 0 " 68" " /i2c@d4031000" begin-package \ TWSI2 +dev /i2c@d4031000 \ TWSI2 +new-device " rtc" name " idt,idt1338-rtc" +compatible - my-address my-space 1 reg + h# 68 1 reg
[ifdef] cl2-a1 : set-address ( -- ) @@ -91,4 +92,5 @@ close ;
-end-package +finish-device +device-end
Modified: cpu/arm/olpc/sound.fth ============================================================================== --- cpu/arm/olpc/sound.fth Fri Aug 31 00:10:06 2012 (r3254) +++ cpu/arm/olpc/sound.fth Fri Aug 31 00:57:10 2012 (r3255) @@ -1,10 +1,16 @@ -0 0 " 1a" " /i2c@d4011000" begin-package \ TWSI1 +dev /i2c@d4011000 +new-device " audio-codec" name " realtek,alc5631" +compatible " realtek,rt5631" +compatible - my-address my-space 1 reg + h# 1a 1 reg " rt5631-hifi" " dai-name" string-property \ snd_soc_dai_link.codec_dai_name -end-package + : open ( -- true ) my-unit " set-address" $call-parent true ; + : close ( -- ) ; + : codec@ ( reg# -- w ) 1 2 " bytes-out-in" $call-parent swap bwjoin ; + : codec! ( w reg# -- ) >r wbsplit r> 3 " bytes-out" $call-parent ; +finish-device +device-end
: +audio ( offset -- address ) [ifdef] mmp3 h# c0ffd000 [else] h# d42a0000 [then] + @@ -288,17 +294,15 @@ my-in-desc 3 la+ l@ to my-in-desc ;
-[ifdef] cl2-a1 -: choose-smbus ( -- ) h# 18 1 set-twsi-target ; -[else] -: choose-smbus ( -- ) h# 1a 1 set-twsi-target ; -[then] - \ Reset is unconnected on current boards \ : audio-reset ( -- ) audio-reset-gpio# gpio-clr ; \ : audio-unreset ( -- ) audio-reset-gpio# gpio-set ; -: codec@ ( reg# -- w ) choose-smbus 1 2 twsi-get swap bwjoin ; -: codec! ( w reg# -- ) choose-smbus >r wbsplit r> 3 twsi-out ; +0 value codec-ih +: $call-codec ( ? -- ? ) codec-ih $call-method ; + +: codec@ ( reg# -- w ) " codec@" $call-codec ; +: codec! ( w reg# -- ) " codec!" $call-codec ; + : codec-i@ ( index# -- w ) h# 6a codec! h# 6c codec@ ; : codec-i! ( w index# -- ) h# 6a codec! h# 6c codec! ;
@@ -635,12 +639,15 @@ sspa-base h# 100 " map-out" $call-parent 0 to adma-base 0 to sspa-base ; + 0 value open-count : open ( -- flag ) open-count 0= if my-unit h# 400 - h# 100 " map-in" $call-parent to adma-base my-unit h# 100 " map-in" $call-parent to sspa-base audio-clock-on if (close) false exit then + " /audio-codec" open-dev to codec-ih + codec-ih 0= if (close) false exit then init-codec then open-count 1+ to open-count @@ -649,6 +656,7 @@ : close ( -- ) open-count 1 = if uninstall-playback-alarm codec-off + codec-ih close-dev (close) then open-count 1- 0 max to open-count
Modified: cpu/arm/olpc/twsi-i2c.fth ============================================================================== --- cpu/arm/olpc/twsi-i2c.fth Fri Aug 31 00:10:06 2012 (r3254) +++ cpu/arm/olpc/twsi-i2c.fth Fri Aug 31 00:57:10 2012 (r3255) @@ -1,27 +1,6 @@ purpose: Device tree nodes for board-specific I2C buses implemented by TWSI hardware
-: make-twsi-node ( baseadr clock# irq# muxed-irq? fast? unit# -- ) - root-device - new-device - " linux,unit#" integer-property - " i2c" name - " mrvl,mmp-twsi" +compatible ( baseadr clock# irq# muxed-irq? fast? ) - if 0 0 " mrvl,i2c-fast-mode" property then ( baseadr clock# irq# muxed-irq? ) - if - " /interrupt-controller/interrupt-controller@158" encode-phandle " interrupt-parent" property - then ( baseadr clock# irq# ) - " interrupts" integer-property ( baseadr clock# ) - " /apbc" encode-phandle rot encode-int encode+ " clocks" property - - h# 1000 reg ( ) - 1 " #address-cells" integer-property - 1 " #size-cells" integer-property - " : open true ; : close ;" evaluate - " : encode-unit ( phys.. -- str ) push-hex (u.) pop-base ;" evaluate - " : decode-unit ( str -- phys.. ) push-hex $number if 0 then pop-base ;" evaluate - finish-device - device-end -; +: make-twsi-node " ${BP}/cpu/arm/mmp2/twsi-methods.fth" included ;
\ baseadr clk irq mux? fast? unit# h# d4011000 1 7 false true 2 make-twsi-node \ TWSI1 @@ -31,7 +10,6 @@ \ h# d4038000 d# 30 3 true true N make-twsi-node \ TWSI5 h# d4034000 d# 31 4 true true 4 make-twsi-node \ TWSI6
- [ifdef] soon-olpc-cl2 \ this breaks cl4-a1 boards, which ofw calls cl2. 0 0 " 30" " /i2c@d4033000" begin-package \ TWSI4 " touchscreen" name @@ -49,9 +27,3 @@ touch-int-gpio# 1 " dr-gpios" gpio-property end-package [then] - -0 0 " 19" " /i2c@d4034000" begin-package \ TWSI6 - " accelerometer" name - " lis3lv02d" +compatible - my-address my-space 1 reg -end-package