[openfirmware] [commit] r3337 - in dev: . mmc/sdhci mmc/sdhci/mv8686
repository service
svn at openfirmware.info
Thu Sep 27 03:14:28 CEST 2012
Author: wmb
Date: Thu Sep 27 03:14:27 2012
New Revision: 3337
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/3337
Log:
OLPC WLAN driver - Support both 8686 and 8787 WLAN modules from the same driver.
Modified:
dev/libertas.fth
dev/mmc/sdhci/mv8686/fw8686.fth
dev/mmc/sdhci/mv8686/mv8686.fth
dev/mmc/sdhci/mv8686/sdio.fth
dev/mmc/sdhci/sdhci.fth
dev/mmc/sdhci/slot.fth
Modified: dev/libertas.fth
==============================================================================
--- dev/libertas.fth Thu Sep 27 03:12:32 2012 (r3336)
+++ dev/libertas.fth Thu Sep 27 03:14:27 2012 (r3337)
@@ -51,6 +51,7 @@
ds-not-ready value driver-state
+: driver-is-not-ready ( -- ) ds-not-ready to driver-state ;
: set-driver-state ( bit-mask -- ) driver-state or to driver-state ;
: reset-driver-state ( bit-mask -- ) invert driver-state and to driver-state ;
@@ -155,7 +156,7 @@
2 field >fw-seq
2 field >fw-result
dup constant /fw-cmd
-dup 4 - constant /fw-cmd-hdr \ Command header len (less /fw-transport)
+dup /fw-transport - constant /fw-cmd-hdr \ Command header len (less /fw-transport)
0 field >fw-data \ Command payload starts here
drop
@@ -207,6 +208,22 @@
0 field >tx-pkt
constant /tx-hdr
+struct
+ /fw-transport +
+ 1 field >tx14-bsstype
+ 1 field >tx14-bss#
+ 2 field >tx14-len
+ 2 field >tx14-offset
+ 2 field >tx14-type
+ 4 field >tx14-ctrl
+ 1 field >tx14-priority
+ 1 field >tx14-pwr
+ 1 field >tx14-delay \ in 2ms
+ 1+
+ 0 field >tx14-pkt
+constant /tx14-hdr
+
+
0 constant tx-ctrl \ Tx rates, etc
: set-tx-ctrl ( n -- ) to tx-ctrl ;
@@ -216,32 +233,47 @@
: mesh-on? ( -- flag ) tx-ctrl TX_WDS and 0<> ;
-: (wrap-msg-thin) ( adr len dst-mac-adr -- adr' len' )
- outbuf /tx-hdr erase ( adr len dst-mac-adr )
- outbuf >tx-mac /mac-adr move ( adr len )
+: wrap-802.11 ( adr len -- adr' len' )
+ outbuf /tx-hdr erase ( adr len )
+ over 4 + outbuf >tx-mac /mac-adr move ( adr len )
dup outbuf >tx-len le-w! ( adr len )
tuck outbuf >tx-pkt-no-mesh swap move ( len )
- /tx-hdr-no-mesh 4 - outbuf >tx-offset le-l! ( len ) \ Offset from >tx-ctrl field
+ /tx-hdr-no-mesh /fw-transport - outbuf >tx-offset le-l! ( len ) \ Offset from >tx-stat field
tx-ctrl outbuf >tx-ctrl le-l! ( len )
outbuf swap /tx-hdr-no-mesh + ( adr' len' )
;
-: (wrap-msg) ( adr len dst-mac-adr -- adr' len' )
- outbuf /tx-hdr erase ( adr len dst-mac-adr )
- outbuf >tx-mac /mac-adr move ( adr len )
+
+: wrap-v9 ( adr len -- adr' len' )
+ outbuf /tx-hdr erase ( adr len )
+ over outbuf >tx-mac /mac-adr move ( adr len )
dup outbuf >tx-len le-w! ( adr len )
tuck outbuf >tx-pkt swap move ( len )
- /tx-hdr 4 - outbuf >tx-offset le-l! ( len ) \ Offset from >tx-ctrl field
+ /tx-hdr /fw-transport - outbuf >tx-offset le-l! ( len ) \ Offset from >tx-stat field
tx-ctrl outbuf >tx-ctrl le-l! ( len )
mesh-on? if 1 outbuf >tx-mesh-ttl c! then ( len )
outbuf swap /tx-hdr + ( adr' len' )
;
-: wrap-802.11 ( adr len -- adr' len' ) over 4 + (wrap-msg-thin) ;
-: wrap-msg ( adr len -- adr' len' ) over (wrap-msg) ;
+
+: wrap-v14 ( adr len -- adr' len' )
+ \ Erasing sets the following fields to 0:
+ \ >tx14-bsstype (0=STA), >tx14-bss# (BSS#=0), >tx14-type (0=802.3)
+ \ >tx14-pri (PRI=0), >tx14-flags, >tx14-delay
+ outbuf /tx14-hdr erase ( adr len )
+
+ dup outbuf >tx14-len le-w! ( adr len )
+ tuck outbuf >tx14-pkt swap move ( len )
+
+ /tx14-hdr /fw-transport - outbuf >tx14-offset le-w! ( len ) \ Offset from >tx14-bsstype field
+ tx-ctrl outbuf >tx14-ctrl le-l! ( len )
+
+ outbuf swap /tx14-hdr + ( adr' len' )
+;
+instance defer wrap-ethernet
\ =========================================================================
\ Receive Packet Descriptor
@@ -275,6 +307,24 @@
d# 22 + \ Size of an Ethernet header with SNAP
constant /rx-min
+struct
+ /fw-transport +
+ 1 field >rx14-bsstype
+ 1 field >rx14-bss#
+ 2 field >rx14-len
+ 2 field >rx14-offset
+ 2 field >rx14-type \ 2:ethernet 3:802.3 w/ LLC+SNAP 5:802.11 e6:AMSDU e7:BAR ef:debug
+ 2 field >rx14-seq
+ 1 field >rx14-pri
+ 1 field >rx14-rate
+ 1 field >rx14-snr
+ 1 field >rx14-nf
+ 1 field >rx14-ht
+ 1 +
+\ d# 14 + \ Size of an Ethernet header
+\ d# 22 + \ Size of an Ethernet header with SNAP
+constant /rx14-min
+
\ >rx-stat constants
1 constant rx-stat-ok
2 constant rx-stat-multicast
@@ -297,11 +347,16 @@
drop
;
-: unwrap-pkt ( adr len -- data-adr data-len )
- /rx-min < if drop 0 0 then \ Invalid packet: too small
+: unwrap-v9 ( adr len -- data-adr data-len false | true )
+ over .rx-desc ( adr len )
+ over >rx-stat le-w@ rx-stat-ok <> if ( adr len )
+ 2drop true exit ( -- true )
+ then ( adr len )
+
+ /rx-min < if drop true exit then ( adr ) \ Invalid packet: too small
\ Go to the payload, skipping the descriptor header
- dup dup >rx-offset le-l@ + la1+ ( adr data-adr )
+ dup dup >rx-offset le-l@ + /fw-transport + ( adr data-adr )
swap >rx-len le-w@ ( data-adr data-len )
\ Remove snap header by moving the MAC addresses up
@@ -310,15 +365,39 @@
over dup 8 + d# 12 move ( data-adr data-len )
8 /string ( adr' len' )
then
+ false
+;
+: unwrap-v14 ( adr len -- data-adr data-len )
+ /rx14-min < if drop true exit then ( adr ) \ Invalid packet: too small
+
+ \ Go to the payload, skipping the descriptor header
+ >r ( r: adr )
+ r@ r@ >rx14-offset le-w@ + /fw-transport + ( data-adr r: adr )
+ r@ >rx14-len le-w@ ( data-adr data-len r: adr )
+
+ r> >rx14-type c@ case ( data-adr data-len )
+ 2 of endof \ Ethernet ( data-adr data-len )
+ 3 of \ 802.3 with LLC + SNAP ( data-adr data-len )
+ \ Remove snap header by moving the MAC addresses up
+ \ That's faster than moving the contents down
+ over d# 14 + snap-header comp 0= if ( data-adr data-len )
+ over dup 8 + d# 12 move ( data-adr data-len )
+ 8 /string ( adr' len' )
+ then
+ endof
+ ( default ) ( adr len type )
+ ." libertas.fth: Frame type not supported" cr
+ 3drop true exit
+ endcase
+ false
;
+instance defer unwrap-ethernet
: process-data ( adr len -- )
2dup vdump ( adr len )
- over .rx-desc ( adr len )
-
- over >rx-stat le-w@ rx-stat-ok <> if 2drop exit then
- unwrap-pkt to /data to data ( )
+ unwrap-ethernet if exit then ( adr' len' )
+ to /data to data ( )
true to got-data? \ do-process-eapol may unset this
@@ -407,6 +486,8 @@
0076 of ." CMD_802_11_RATE_ADAPT_RATESET" endof
007f of ." CMD_TX_RATE_QUERY" endof
00a5 of ." CMD_SET_BOOT2_VER" endof \ Thin firmware only
+ 00a9 of ." CMD_FUNC_INIT" endof \ Multifunction versions
+ 00aa of ." CMD_FUNC_SHUTDOWN" endof
00b0 of ." CMD_802_11_BEACON_CTRL" endof \ Thin firmware only
00cb of ." CMD_802_11_BEACON_SET" endof \ Thin firmware only
00cc of ." CMD_802_11_SET_MODE" endof \ Thin firmware only
@@ -483,12 +564,15 @@
h# 0e of " Unicast MIC error" .event process-pmic-failure endof
h# 0e of " WM awake" .event endof \ n
h# 11 of " HWAC - adhoc BCN lost" .event endof
+ h# 17 of endof \ Suppress: " WMM status change" .event endof \ XXX supposed to issue CMD_WMM_GET_STATUS
h# 19 of " RSSI low" .event endof
h# 1a of " SNR low" .event endof
h# 1b of " Max fail" .event endof
h# 1c of " RSSI high" .event endof
h# 1d of " SNR high" .event endof
h# 23 of endof \ Suppress this; the user doesn't need to see it
+ h# 2b of endof \ Suppress this; the user doesn't need to see it
+\ h# 2b of " Port release" .event endof
\ h# 23 of ." Mesh auto-started" endof
h# 30 of endof \ Handle this silently
\ h# 30 of " Firmware ready" .event endof
@@ -515,7 +599,7 @@
: check-for-rx ( -- )
got-packet? if ( error | buf len 0 )
- 0= if process-rx then ( )
+ 0= if 2dup vdump process-rx then ( )
recycle-packet ( )
then ( )
;
@@ -603,13 +687,13 @@
: reset-wlan ( -- )
" wlan-reset" evaluate
- ds-not-ready to driver-state
+ driver-is-not-ready
reset-host-bus
;
: sleep ( -- ) reset-wlan ;
: wake ( -- ) ;
-: marvel-get-hw-spec ( -- true | adr false )
+: get-hw-spec ( -- true | adr false )
d# 38 h# 03 ( CMD_GET_HW_SPEC ) prepare-cmd
outbuf-out ?dup if true exit then
resp-wait-tiny to resp-wait
@@ -618,13 +702,37 @@
respbuf >fw-data false
;
-\ The purpose of this is to work around a problem that I don't fully understand.
-\ For some reason, when you reopen the device without re-downloading the
-\ firmware, the first command silently fails - you don't get a response.
-\ This is a "throwaway" command to handle that case without a long timeout
-\ or a warning message.
+: set-fw-params ( -- )
+ get-hw-spec 0= if ( adr )
+
+ \ The 4-byte FWReleaseNumber field starts at offset d# 18.
+ \ Firmware version 2.3.4.p1 is represented in that field
+ \ as 04 03 02 01, i.e. the first three bytes are little-endian,
+ \ and the final byte is the "p-number". The "MSB" at offset
+ \ d# 20 reflects the major version number, corresponding to
+ \ the "v-number" of the firmware interface document.
+
+ d# 20 + c@ d# 14 >= if
+ ['] wrap-v14 to wrap-ethernet
+ ['] unwrap-v14 to unwrap-ethernet
+ else
+ ['] wrap-v9 to wrap-ethernet
+ ['] unwrap-v9 to unwrap-ethernet
+ then
+ then
+;
+
+\ This is necessary for multifunction devices like 8688 and 8787 that have
+\ extra functions like BlueTooth in addition to WiFi
+: init-function ( -- )
+ 0 h# a9 ( CMD_FUNC_INIT ) prepare-cmd
+ outbuf-wait if exit then
+;
-: nonce-cmd ( -- ) marvel-get-hw-spec 0= if drop then ;
+: shutdown-function ( -- )
+ 0 h# aa ( CMD_FUNC_SHUTDOWN ) prepare-cmd
+ outbuf-wait if exit then
+;
\ =========================================================================
\ MAC address
@@ -870,6 +978,14 @@
: mac-off ( -- )
0 to mac-ctrl set-mac-control 3 to mac-ctrl
;
+
+: reconfig-tx-buffer ( bufsize -- ) \ mwifiex
+ 3 h# d9 ( RECONFIGURE_TX_BUFF ) prepare-cmd
+ ACTION_SET +xw
+ ( bufsize ) +xw
+ outbuf-wait drop
+;
+
headers
\ =========================================================================
@@ -1661,7 +1777,7 @@
\ This is a heavy-handed way to force the device back into baseline state
\ The recipe above is nicer.
-\ ds-not-ready to driver-state \ Forces firmware reload on next open
+\ driver-is-not-ready \ Forces firmware reload on next open
\ reset-host-bus \ Primes module to accept new firmware
\ false to ap-mode?
;
@@ -1711,8 +1827,8 @@
;
: .hw-spec ( -- )
- marvel-get-hw-spec if
- ." marvel-get-hw-spec command failed" cr
+ get-hw-spec if
+ ." get-hw-spec command failed" cr
else
." HW interface version: " dup le-w@ u. cr
." HW version: " dup 2 + le-w@ u. cr
@@ -1901,6 +2017,7 @@
then
ds-ready to driver-state
then
+ multifunction? if init-function then
?make-mac-address-property
;
@@ -1932,11 +2049,12 @@
" " set-ssid \ Instance buffers aren't necessarily initially 0
opencount @ 0= if
init-buf
+ driver-is-not-ready
/inbuf /outbuf setup-bus-io if free-buf false exit then
?load-fw if release-bus-resources free-buf false exit then
+ set-fw-params
my-args " supplicant" $open-package to supplicant-ih
supplicant-ih 0= if release-bus-resources free-buf false exit then
- nonce-cmd
force-open? if
ds-disconnected reset-driver-state
else
@@ -1965,7 +2083,9 @@
stop-nic
mac-off
supplicant-ih ?dup if close-package 0 to supplicant-ih then
+ multifunction? if shutdown-function then
release-bus-resources
+ driver-is-not-ready
then
;
@@ -1973,7 +2093,7 @@
\ Used by the /supplicant support package to perform key handshaking.
: write-force ( adr len -- actual )
tuck ( actual adr len )
- wrap-msg ( actual adr' len' )
+ wrap-ethernet ( actual adr' len' )
data-out ( actual )
;
Modified: dev/mmc/sdhci/mv8686/fw8686.fth
==============================================================================
--- dev/mmc/sdhci/mv8686/fw8686.fth Thu Sep 27 03:12:32 2012 (r3336)
+++ dev/mmc/sdhci/mv8686/fw8686.fth Thu Sep 27 03:14:27 2012 (r3337)
@@ -1,4 +1,4 @@
-purpose: Marvel 8686 firmware loader
+purpose: Marvel SDIO WLAN module firmware loader
\ See license at end of file
@@ -21,10 +21,7 @@
0 value fw-tx-len
0 value dn-retry
-: fw-dn-blksz ( -- blksz )
- h# 10 1 sdio-reg@
- h# 11 1 sdio-reg@ bwjoin
-;
+: fw-dn-blksz ( -- blksz ) host-f1-rd-base-0-reg 1 sdio-reg-w@ ;
: wait-for-fw-dn-blksz ( -- blksz )
\ Wait for the first non-zero value
d# 5000 0 do fw-dn-blksz dup ?leave drop loop
@@ -33,7 +30,7 @@
: fw-download-ok? ( -- flag )
false d# 100 0 do
- sdio-scratch@ FIRMWARE_READY = if drop true leave then
+ sdio-fw-status@ FIRMWARE_READY = if drop true leave then
d# 10 ms
loop
;
@@ -46,7 +43,7 @@
fw-len dn-idx - fw-tx-len min ( len )
fw-adr dn-idx + outbuf 2 pick move ( len )
outbuf over sdio-fw! <> if
- 4 3 1 sdio-reg! \ FN1 CFG = write iomem fail
+ 4 config-reg 1 sdio-reg! \ FN1 CFG = write iomem fail
then
sdio-poll-dl-ready 0= if ." Download fw died" cr true exit then
fw-dn-blksz ?dup 0= if false exit then
@@ -65,7 +62,7 @@
: fw-image-ok? ( adr len -- flag ) 2drop true ;
: download-fw ( adr len -- error? )
- 2dup fw-image-ok? 0= if ." Bad WLAN firmware image" cr true exit then
+ 2dup fw-image-ok? 0= if ." Bad WLAN firmware image" cr true exit then ( adr len )
wait-for-fw-dn-blksz
?dup 0= if ." Failed to get firmware download block size" cr 2drop true exit then
@@ -75,7 +72,10 @@
fw-download-ok? 0= if true exit then
- 3 4 1 sdio-reg! \ Enable host interrupt mask
+ 3 host-int-mask-reg 1 sdio-reg! \ Enable upload (1) and download (2)
+ mv8787? if
+ 2 config-reg 1 sdio-reg! \ Host power up
+ then
false
;
@@ -97,26 +97,30 @@
;
: download-helper ( adr len -- error? )
- sdio-scratch@ FIRMWARE_READY = if " Firmware downloaded" vtype 2drop true exit then
+ sdio-fw-status@ FIRMWARE_READY = if " Firmware downloaded" vtype 2drop true exit then
2dup fw-image-ok? 0= if ." Bad WLAN helper image" cr true exit then
(download-helper)
;
-: load-8686-fw ( -- error? )
- wlan-helper find-fw dup if ( adr len )
- download-helper if true exit then
- else ( adr len )
- 2drop ( )
- then ( )
+: load-sdio-fw ( -- error? )
+ helper? if
+ wlan-helper find-fw dup if ( adr len )
+ 2dup download-helper ( adr len error? )
+ -rot free-mem ( error? )
+ if true exit then ( )
+ else ( adr len )
+ 2drop ( )
+ then ( )
+ then
wlan-fw find-fw dup if ( adr len )
- download-fw ( error? )
+ 2dup download-fw ( adr len error? )
+ -rot free-mem ( error? )
else ( adr len )
- 2drop false ( error? )
+ 2drop true ( error? )
then ( error? )
;
-' load-8686-fw to load-all-fw
-
+' load-sdio-fw to load-all-fw
\ LICENSE_BEGIN
\ Copyright (c) 2007 FirmWorks
Modified: dev/mmc/sdhci/mv8686/mv8686.fth
==============================================================================
--- dev/mmc/sdhci/mv8686/mv8686.fth Thu Sep 27 03:12:32 2012 (r3336)
+++ dev/mmc/sdhci/mv8686/mv8686.fth Thu Sep 27 03:14:27 2012 (r3337)
@@ -4,12 +4,6 @@
headers
hex
-" mv8686" encode-string " module-type" property
-
-\ This really depends on the firmware that we load, but we don't want
-\ to load the firmware in advance, so we hardcode this, assuming that
-\ the firmware we include with OFW has both thin and fullmac capability.
-0 0 encode-bytes " thin" property
0 0 encode-bytes " fullmac" property
\ =======================================================================
@@ -19,7 +13,7 @@
\ =======================================================================
: wlan-fw ( -- $ )
- " wlan-fw" " $getenv" evaluate if " rom:sd8686.bin" then
+ " wlan-fw" " $getenv" evaluate if default-fw$ then
;
: wlan-helper ( -- $ )
" wlan-helper" " $getenv" evaluate if " rom:helper_sd.bin" then
@@ -76,11 +70,8 @@
: release-bus-resources ( -- ) drain-queue detach-card ;
-0 value card-attached?
-
: ?attach-card ( -- ok? )
- card-attached? if true exit then
- attach-card dup to card-attached? ( ok? )
+ attach-card if set-version 0= else false then
;
: make-my-properties ( -- )
@@ -91,13 +82,13 @@
: setup-bus-io ( /inbuf /outbuf -- error? )
2drop
init-queue
- ?attach-card 0= if ." Fail to attach card" cr true exit then
+ ?attach-card 0= if ." Failed to attach card" cr true exit then
make-my-properties
init-device
false
;
-: reset-host-bus ( -- ) false to card-attached? ;
+: reset-host-bus ( -- ) ;
\ LICENSE_BEGIN
\ Copyright (c) 2009 FirmWorks
Modified: dev/mmc/sdhci/mv8686/sdio.fth
==============================================================================
--- dev/mmc/sdhci/mv8686/sdio.fth Thu Sep 27 03:12:32 2012 (r3336)
+++ dev/mmc/sdhci/mv8686/sdio.fth Thu Sep 27 03:14:27 2012 (r3337)
@@ -4,97 +4,252 @@
hex
headers
-0 value ioport
-d# 320 constant blksz \ Block size for data tx/rx
-d# 32 constant fw-blksz
+: sdio-reg@ ( reg# function# -- value ) " sdio-reg@" $call-parent ;
+: sdio-reg! ( value reg# function# -- ) " sdio-reg!" $call-parent ;
+: sdio-reg-w@ ( reg# function# -- w.value )
+ 2dup sdio-reg@ -rot ( low reg# function# )
+ swap 1+ swap sdio-reg@ ( low high )
+ bwjoin ( w.value )
+;
+: sdio-w@ ( reg# -- w.value ) 1 sdio-reg-w@ ;
+
+false instance value multifunction?
+false instance value helper?
+false instance value mv8787?
+instance defer rx-ready? ( -- len )
+instance defer get-ctrl-port ( -- port# )
+instance defer get-write-port ( -- port# )
-: roundup-blksz ( n -- n' ) blksz 1- + blksz / blksz * ;
+0 0 2value default-fw$
-: set-address ( rca slot -- ) " set-address" $call-parent ;
-: get-address ( -- rca ) " get-address" $call-parent ;
-: attach-card ( -- ok? ) " attach-sdio-card" $call-parent ;
-: detach-card ( -- ) " detach-sdio-card" $call-parent ;
+0 value ioport
+d# 256 constant blksz \ Block size for data tx/rx
+d# 256 constant fw-blksz
-\ The following are CMD52 (SDIO) variants
-\ Flags: 80:CRC_ERROR 40:ILLEGAL_COMMAND 30:IO_STATE (see spec)
-\ 08:ERROR 04:reserved 02:INVALID_FUNCTION# 01:OUT_OF_RANGE
-
-h# cf constant SDIO_FLAG_MASK
-
-: .io-state ( flags & 30 -- )
- case
- h# 00 of ." card disabled; " endof
- h# 10 of ." CMD state; " endof
- h# 20 of ." data transfer; " endof
- h# 30 of ." reserved; " endof
- endcase
-;
-: .sdio-flags ( flags -- )
- dup SDIO_FLAG_MASK and 0= if drop exit then
- ." IO_RW_DIRECT response = "
- dup h# 80 and if ." CRC error; " then
- dup h# 40 and if ." illegal command; " then
- dup h# 30 and .io-state
- dup h# 08 and if ." error; " then
- dup h# 02 and if ." invalid function; " then
- dup h# 01 and if ." argument out of range" then
- cr
+h# 0 constant config-reg
+h# 1 constant host-int-rsr-reg
+h# 2 constant host-int-mask-reg
+h# 3 constant host-intstatus-reg
+
+h# 4 constant rd-bitmap-reg
+h# 6 constant wr-bitmap-reg
+h# 8 constant rd-len-reg
+
+\ h# 20 constant host-f1-card-rdy-reg
+\ h# 28 constant host-int-status-reg
+h# 30 constant card-status-reg
+h# 34 constant interrupt-mask-reg
+\ h# 38 constant interrupt-status-reg
+\ h# 3c constant interrupt-rsr-reg
+h# 40 constant host-f1-rd-base-0-reg
+\ h# 41 constant host-f1-rd-base-1-reg
+h# 6c constant card-misc-cfg-reg
+h# 60 constant card-fw-status0-reg
+\ h# 61 constant card-fw-status1-reg
+\ h# 62 constant card-rx-len-reg
+\ h# 63 constant card-rx-unit-reg
+h# 78 constant ioport-reg
+
+: ?set-module-property ( adr len -- )
+ " module-type" get-my-property if ( adr len )
+ encode-string " module-type" property ( )
+ else ( adr len prop$ )
+ 2drop 2drop
+ then
;
-: sdio-reg@ ( reg# function# -- value )
- " io-b@" $call-parent .sdio-flags
+: sdio-fw-status@ ( -- n )
+ card-fw-status0-reg sdio-w@
;
-: sdio-reg! ( value reg# function# -- )
- " io-b!" $call-parent .sdio-flags
+: mv8686-rx-ready? ( -- len )
+ host-intstatus-reg 1 sdio-reg@
+ dup 0= if exit then
+ dup invert 3 and host-intstatus-reg 1 sdio-reg! \ Clear UP_LD bit
+ 1 and if
+ sdio-fw-status@
+ else
+ 0
+ then
;
-: sdio-reg!@ ( value reg# function# -- value' )
- " io-b!@" $call-parent .sdio-flags
+: use-mv8686 ( -- )
+ h# 3 to config-reg
+ h# 4 to host-int-mask-reg
+ h# 5 to host-intstatus-reg
+ h# 20 to card-status-reg
+ h# 10 to host-f1-rd-base-0-reg
+ h# 34 to card-fw-status0-reg
+ h# 00 to ioport-reg
+ d# 320 to blksz
+ d# 32 to fw-blksz
+ false to mv8787?
+ false to multifunction?
+ true to helper?
+ ['] mv8686-rx-ready? to rx-ready?
+ ['] 0 to get-ctrl-port
+ ['] 0 to get-write-port
+
+ " rom:sd8686.bin" to default-fw$
+ " mv8686" ?set-module-property
+
+ \ This really depends on the firmware that we load, but we don't want
+ \ to load the firmware in advance, so we hardcode this, assuming that
+ \ the firmware we include with OFW has both thin and fullmac capability.
+ " thin" get-my-property if
+ 0 0 encode-bytes " thin" property
+ else
+ 2drop
+ then
+;
+0 instance value rx-port#
+0 instance value wr-bitmap
+0 instance value rd-bitmap
+: update-bitmaps ( -- )
+ host-intstatus-reg 1 sdio-reg@
+ dup 2 and if wr-bitmap-reg sdio-w@ to wr-bitmap then
+ 1 and if rd-bitmap-reg sdio-w@ to rd-bitmap then
+;
+: mv8787-rx-ready? ( -- len )
+ rd-bitmap dup if ( bitmap )
+ d# 16 0 do ( bitmap )
+ dup 1 and if ( bitmap )
+ drop i leave ( port# )
+ then ( bitmap )
+ 2/ ( bitmap' )
+ loop ( port# )
+ 1 over lshift invert rd-bitmap and to rd-bitmap ( port# )
+ dup to rx-port# ( port# )
+ 2* rd-len-reg + sdio-w@ ( len )
+ else ( 0 )
+ update-bitmaps ( 0 )
+ then
;
-: sdio-scratch@ ( -- value )
- h# 34 1 sdio-reg@ ( lo )
- h# 35 1 sdio-reg@ ( lo hi )
- bwjoin ( value )
+: mv8787-get-ctrl-port ( -- n )
+ 0
+;
+: next-wr-port ( -- n )
+ wr-bitmap 2/ ( bits )
+ dup 0= if exit then ( bits )
+ d# 16 1 do ( bits )
+ dup 1 and if ( bits )
+ drop ( )
+ wr-bitmap 1 i lshift invert and to wr-bitmap
+ i leave ( n )
+ then ( bits )
+ 2/ ( bits' )
+ loop ( n )
+;
+
+: mv8787-get-write-port ( -- n )
+ begin next-wr-port ?dup 0= while ( )
+ update-bitmaps ( )
+ repeat ( n )
+;
+
+: use-mv8787 ( -- )
+ h# 0 to config-reg
+ h# 1 to host-int-rsr-reg
+ h# 2 to host-int-mask-reg
+ h# 3 to host-intstatus-reg
+\ h# 20 to host-f1-card-rdy-reg
+\ h# 28 to host-restart-reg
+ h# 30 to card-status-reg
+ h# 34 to interrupt-mask-reg
+\ h# 38 to interrupt-status-reg
+\ h# 3c to interrupt-rsr-reg
+ h# 40 to host-f1-rd-base-0-reg
+\ h# 41 to host-f1-rd-base-1-reg
+ h# 6c to card-misc-cfg-reg
+ h# 60 to card-fw-status0-reg
+\ h# 61 to card-fw-status1-reg
+\ h# 62 to card-rx-len-reg
+\ h# 63 to card-rx-unit-reg
+ h# 78 to ioport-reg
+ d# 256 to blksz
+ d# 256 to fw-blksz
+ true to mv8787?
+ ['] mv8787-rx-ready? to rx-ready?
+ ['] mv8787-get-ctrl-port to get-ctrl-port
+ ['] mv8787-get-write-port to get-write-port
+ " rom:mv8787.bin" to default-fw$
+ " mv8787" ?set-module-property
+ false to helper?
+ true to multifunction?
+;
+
+: set-version ( -- error? )
+ " sdio-card-id" $call-parent case
+ h# 02df9103 of use-mv8686 false endof
+ h# 02df9118 of use-mv8787 false endof
+ ( default )
+ ." Unsupported SDIO card ID " dup . cr
+ true swap
+ endcase
;
+: roundup-blksz ( n -- n' ) blksz 1- + blksz / blksz * ;
+
+: set-address ( rca slot -- ) " set-address" $call-parent ;
+: get-address ( -- rca ) " get-address" $call-parent ;
+: attach-card ( -- ok? ) " attach-sdio-card" $call-parent ;
+: detach-card ( -- ) " detach-sdio-card" $call-parent ;
+
: sdio-poll-dl-ready ( -- ready? )
false d# 100 0 do
- h# 20 1 sdio-reg@ \ card status register
+ card-status-reg 1 sdio-reg@
h# 9 tuck and = if drop true leave then
d# 100 usec
loop
dup 0= if ." sdio-poll-dl-ready failed" cr then
;
-: sdio-blocks@ ( adr len -- actual )
- >r >r
- ioport 1 true r> r> blksz true " r/w-ioblocks" $call-parent ( actual )
+: sdio-fw! ( adr len -- actual )
+ >r >r ioport 1 true r> r> fw-blksz false " r/w-ioblocks" $call-parent
;
-: sdio-blocks! ( adr len -- actual )
- >r >r ioport 1 true r> r> blksz false " r/w-ioblocks" $call-parent
-;
+: init-device ( -- )
+ ioport-reg 3 bounds do i 1 sdio-reg@ loop \ Read the IO port
+ 0 bljoin to ioport
-: packet-out ( adr len -- error? ) tuck sdio-blocks! <> ;
-: packet-out-async ( adr len -- ) sdio-blocks! drop ;
+ 7 0 sdio-reg@ h# 20 or 7 0 sdio-reg! \ Enable async interrupt mode
-: sdio-fw! ( adr len -- actual )
- >r >r ioport 1 true r> r> fw-blksz false " r/w-ioblocks" $call-parent
-;
+ 2 2 0 sdio-reg! \ Enable IO function 1 (2 = 1 << 1)
+ 3 4 0 sdio-reg! \ Enable interrupts (1) for function 1 (1 << 1)
-: rx-ready? ( -- len )
- 5 1 sdio-reg@ \ Read interrupt status reg
- dup 0= if exit then
- dup invert 3 and 5 1 sdio-reg! \ Clear UP_LD bit
- 1 and if
- sdio-scratch@ \ Read payload length
- else
- 0
+ mv8787? if
+ \ Set host interrupt reset to "read to clear"
+ host-int-rsr-reg 1 sdio-reg@ h# 3f or host-int-rsr-reg 1 sdio-reg!
+
+\ 3 host-int-mask-reg 1 sdio-reg! \ Enable upload (1) and download (2)
+
+ \ Set Dnld/upld to "auto reset"
+ card-misc-cfg-reg 1 sdio-reg@ h# 10 or card-misc-cfg-reg 1 sdio-reg!
then
;
+: sdio-blocks@ ( adr len -- actual )
+ >r >r
+ rx-port# ioport + 1 true r> r> blksz true " r/w-ioblocks" $call-parent ( actual )
+;
+
+\ : sdio-blocks! ( adr len -- actual )
+\ >r >r x-get-write-port ioport + 1 true r> r> blksz false " r/w-ioblocks" $call-parent
+\ ;
+
+\ 1 is the function number
+: (sdio-blocks!) ( adr len port# -- actual )
+ ioport + -rot ( port# adr len )
+ 1 true 2swap ( port# function# inc? adr len )
+ blksz false " r/w-ioblocks" $call-parent
+;
+
+\ 0 is the control port number
+: packet-out ( adr len -- error? ) tuck get-ctrl-port (sdio-blocks!) <> ;
+
+: packet-out-async ( adr len -- ) get-write-port (sdio-blocks!) drop ;
+
: read-poll ( -- )
begin rx-ready? ?dup while ( len )
new-buffer ( handle adr len )
@@ -103,15 +258,6 @@
repeat
;
-: init-device ( -- )
- 3 0 do i 1 sdio-reg@ loop \ Read the IO port
- 0 bljoin to ioport
-
- 7 0 sdio-reg@ h# 20 or 7 0 sdio-reg! \ Enable async interrupt mode
-
- 2 2 0 sdio-reg! \ Enable IO function
- 3 4 0 sdio-reg! \ Enable interrupts
-;
headers
Modified: dev/mmc/sdhci/sdhci.fth
==============================================================================
--- dev/mmc/sdhci/sdhci.fth Thu Sep 27 03:12:32 2012 (r3336)
+++ dev/mmc/sdhci/sdhci.fth Thu Sep 27 03:14:27 2012 (r3337)
@@ -930,9 +930,13 @@
false
;
+\ To dynamically probe, get the number of functions from bits 30..28 of OCR
+0 instance value sdio-ocr \ Contains info about voltages and functions
+
: set-sdio-voltage ( -- )
0 io-send-op-cond \ Cmd 5: get card voltage
- h# ff.ffff and io-send-op-cond drop \ Cmd 5: set card voltage
+ h# ff.ffff and io-send-op-cond \ Cmd 5: set card voltage
+ to sdio-ocr
;
external
@@ -1021,6 +1025,83 @@
\ unmap-regs
;
+: .io-state ( flags & 30 -- )
+ case
+ h# 00 of ." card disabled; " endof
+ h# 10 of ." CMD state; " endof
+ h# 20 of ." data transfer; " endof
+ h# 30 of ." reserved; " endof
+ endcase
+;
+\ The following are CMD52 (SDIO) variants
+\ Flags: 80:CRC_ERROR 40:ILLEGAL_COMMAND 30:IO_STATE (see spec)
+\ 08:ERROR 04:reserved 02:INVALID_FUNCTION# 01:OUT_OF_RANGE
+
+h# cf constant SDIO_FLAG_MASK
+
+: .sdio-flags ( flags -- )
+ dup SDIO_FLAG_MASK and 0= if drop exit then
+ ." IO_RW_DIRECT response = "
+ dup h# 80 and if ." CRC error; " then
+ dup h# 40 and if ." illegal command; " then
+ dup h# 30 and .io-state
+ dup h# 08 and if ." error; " then
+ dup h# 02 and if ." invalid function; " then
+ dup h# 01 and if ." argument out of range" then
+ cr
+;
+
+: sdio-reg@ ( reg# func# -- b ) io-b@ .sdio-flags ;
+: sdio-reg! ( b reg# func# -- ) io-b! .sdio-flags ;
+
+\ Can fetch a tuple list from this offset in function 0
+: sdio-cis-ptr ( function# -- reg# )
+ h# 100 * 9 + 3 bounds do i 0 sdio-reg@ loop 0 bljoin
+;
+
+: cis at + ( offset -- offset' byte ) dup 1+ swap 0 sdio-reg@ ;
+: skip-tuple ( offset -- offset' )
+ cis at + 0 ?do cis at + drop loop ( code offset' )
+;
+
+0 instance value sdio-card-id
+: parse-funcid ( offset -- offset' )
+ cis at + drop ( offset ) \ Skip length
+ cis at + >r cis at + >r cis at + >r cis at + >r ( offset r: ven.low,high prod.low,high )
+ r> r> swap bwjoin r> r> swap bwjoin ( offset product vendor )
+ wljoin to sdio-card-id ( vendor.product )
+;
+
+0 value sdio-card-blocksize
+0 value sdio-card-speed
+: parse-funce ( offset -- offset' )
+ cis at + drop ( offset' ) \ Skip length
+ cis at + 0= if ( offset' ) \ Function 0
+ cis at + >r cis at + r> swap bwjoin to sdio-card-blocksize ( offset' )
+ cis at + to sdio-card-speed
+ else ( offset ) \ Not function 0
+ 2- ( offset' ) \ Back up to length
+ skip-tuple ( offset' ) \ Skip it
+ then ( offset )
+;
+
+: parse-tuples ( function# -- )
+ sdio-cis-ptr begin ( offset )
+ cis at + ( offset' tuple-code )
+ dup h# ff <>
+ while ( offset tuple-code )
+ \ Another potentially interesting tuples si h# 15 from which
+ \ you can get strings naming the product.
+ case
+ h# 20 of parse-funcid endof
+ h# 22 of parse-funce endof
+ ( default: offset code )
+ swap skip-tuple swap
+ endcase
+ repeat ( offset tuple-code )
+ 2drop
+;
+
: attach-sdio-card ( -- okay? )
setup-host
power-up-sdio-card if ( retry? )
@@ -1045,8 +1126,11 @@
select-card \ Cmd 7 - Select
set-timeout
4-bit
- 22 7 0 io-b! \ Cmd 52 - Set 4-bit bus width and ECSI bit
- h# cf and 0=
+ d# 22 7 0 io-b! \ Cmd 52 - Set 4-bit bus width and ECSI bit
+ h# cf and 0= ( okay? )
+ dup if
+ 0 parse-tuples \ Get the card ID and other info
+ then
;
: detach-sdio-card ( -- )
@@ -1129,7 +1213,7 @@
2dup tuck 1- + swap / to io-#blocks ( reg# function# inc? addr len blksz r: in? )
4 pick write-blksz ( reg# function# inc? addr len r: in? )
iodma-setup ( reg# function# inc? r: in? )
- wait-write-done if -1 exit then
+ wait-write-done if r> 2drop 2drop -1 exit then
r> if ( reg# function# inc? )
io-read-blocks
else
Modified: dev/mmc/sdhci/slot.fth
==============================================================================
--- dev/mmc/sdhci/slot.fth Thu Sep 27 03:12:32 2012 (r3336)
+++ dev/mmc/sdhci/slot.fth Thu Sep 27 03:14:27 2012 (r3337)
@@ -2,8 +2,13 @@
0 " #address-cells" integer-property
0 " #size-cells" integer-property
-: open true ;
-: close ;
+: open
+ [ifdef] my-clock-on my-clock-on [then]
+ true
+;
+: close
+ [ifdef] my-clock-off my-clock-off [then]
+;
: r/w-blocks " r/w-blocks" $call-parent ;
: erase-blocks " erase-blocks" $call-parent ;
@@ -27,3 +32,7 @@
: io-b@ " io-b@" $call-parent ;
: io-b! " io-b!" $call-parent ;
: io-b!@ " io-b!@" $call-parent ;
+: sdio-reg@ " sdio-reg@" $call-parent ;
+: sdio-reg! " sdio-reg!" $call-parent ;
+: sdio-card-id " sdio-card-id" $call-parent ;
+: sdio-card-blocksize " sdio-card-blocksize" $call-parent ;
More information about the openfirmware
mailing list