Changeset 3337


Ignore:
Timestamp:
Sep 27, 2012, 3:14:27 AM (3 years ago)
Author:
wmb
Message:

OLPC WLAN driver - Support both 8686 and 8787 WLAN modules from the same driver.

Location:
dev
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • dev/libertas.fth

    r3189 r3337  
    5252ds-not-ready value driver-state
    5353
     54: driver-is-not-ready ( -- )   ds-not-ready to driver-state  ;
    5455: set-driver-state    ( bit-mask -- )  driver-state or to driver-state  ;
    5556: reset-driver-state  ( bit-mask -- )  invert driver-state and to driver-state  ;
     
    156157   2 field >fw-result
    157158dup constant /fw-cmd
    158 dup 4 - constant /fw-cmd-hdr    \ Command header len (less /fw-transport)
     159dup /fw-transport - constant /fw-cmd-hdr        \ Command header len (less /fw-transport)
    159160   0 field >fw-data             \ Command payload starts here
    160161drop
     
    208209constant /tx-hdr
    209210
     211struct
     212   /fw-transport +
     213   1 field >tx14-bsstype
     214   1 field >tx14-bss#
     215   2 field >tx14-len
     216   2 field >tx14-offset
     217   2 field >tx14-type
     218   4 field >tx14-ctrl
     219   1 field >tx14-priority
     220   1 field >tx14-pwr
     221   1 field >tx14-delay          \ in 2ms
     222   1+
     223   0 field >tx14-pkt
     224constant /tx14-hdr
     225
     226
    2102270 constant tx-ctrl              \ Tx rates, etc
    211228: set-tx-ctrl  ( n -- )  to tx-ctrl  ;
     
    217234: mesh-on?  ( -- flag )  tx-ctrl TX_WDS and 0<>  ;
    218235
    219 : (wrap-msg-thin)  ( adr len dst-mac-adr -- adr' len' )
    220    outbuf  /tx-hdr  erase                       ( adr len dst-mac-adr )
    221          outbuf >tx-mac  /mac-adr  move         ( adr len )
     236: wrap-802.11  ( adr len -- adr' len' )
     237   outbuf  /tx-hdr  erase                       ( adr len )
     238   over 4 +  outbuf >tx-mac  /mac-adr  move     ( adr len )
    222239   dup   outbuf >tx-len  le-w!                  ( adr len )
    223240   tuck  outbuf >tx-pkt-no-mesh  swap  move             ( len )
    224241
    225    /tx-hdr-no-mesh 4 -  outbuf >tx-offset le-l! ( len )  \ Offset from >tx-ctrl field
     242   /tx-hdr-no-mesh /fw-transport -  outbuf >tx-offset le-l!     ( len )  \ Offset from >tx-stat field
    226243   tx-ctrl        outbuf >tx-ctrl   le-l!       ( len )
    227244
    228245   outbuf  swap /tx-hdr-no-mesh +               ( adr' len' )
    229246;
    230 : (wrap-msg)  ( adr len dst-mac-adr -- adr' len' )
    231    outbuf  /tx-hdr  erase                       ( adr len dst-mac-adr )
    232          outbuf >tx-mac  /mac-adr  move         ( adr len )
     247
     248: wrap-v9  ( adr len -- adr' len' )
     249   outbuf  /tx-hdr  erase                       ( adr len )
     250   over  outbuf >tx-mac  /mac-adr  move         ( adr len )
    233251   dup   outbuf >tx-len  le-w!                  ( adr len )
    234252   tuck  outbuf >tx-pkt  swap  move             ( len )
    235253
    236    /tx-hdr 4 - outbuf >tx-offset le-l!  ( len )  \ Offset from >tx-ctrl field
     254   /tx-hdr /fw-transport - outbuf >tx-offset le-l!      ( len )  \ Offset from >tx-stat field
    237255   tx-ctrl        outbuf >tx-ctrl   le-l!       ( len )
    238256
     
    241259   outbuf  swap /tx-hdr +                       ( adr' len' )
    242260;
    243 : wrap-802.11  ( adr len -- adr' len' )  over 4 +  (wrap-msg-thin)  ;
    244 : wrap-msg  ( adr len -- adr' len' )  over (wrap-msg)  ;
     261
     262: wrap-v14  ( adr len -- adr' len' )
     263   \ Erasing sets the following fields to 0:
     264   \ >tx14-bsstype (0=STA), >tx14-bss# (BSS#=0), >tx14-type (0=802.3)
     265   \ >tx14-pri (PRI=0), >tx14-flags, >tx14-delay
     266   outbuf  /tx14-hdr  erase                     ( adr len )
     267
     268   dup   outbuf >tx14-len  le-w!                ( adr len )
     269   tuck  outbuf >tx14-pkt  swap  move           ( len )
     270
     271   /tx14-hdr /fw-transport - outbuf >tx14-offset le-w!  ( len )  \ Offset from >tx14-bsstype field
     272   tx-ctrl       outbuf >tx14-ctrl   le-l!      ( len )
     273
     274   outbuf  swap /tx14-hdr +                     ( adr' len' )
     275;
     276instance defer wrap-ethernet
    245277
    246278\ =========================================================================
     
    276308constant /rx-min
    277309
     310struct
     311   /fw-transport +
     312   1 field >rx14-bsstype
     313   1 field >rx14-bss#
     314   2 field >rx14-len
     315   2 field >rx14-offset
     316   2 field >rx14-type  \ 2:ethernet 3:802.3 w/ LLC+SNAP 5:802.11 e6:AMSDU e7:BAR ef:debug
     317   2 field >rx14-seq
     318   1 field >rx14-pri
     319   1 field >rx14-rate
     320   1 field >rx14-snr
     321   1 field >rx14-nf
     322   1 field >rx14-ht
     323   1 +
     324\ d# 14 +  \ Size of an Ethernet header
     325\ d# 22 +  \ Size of an Ethernet header with SNAP
     326constant /rx14-min
     327
    278328\ >rx-stat constants
    2793291 constant rx-stat-ok
     
    298348;
    299349
    300 : unwrap-pkt  ( adr len -- data-adr data-len )
    301    /rx-min <  if  drop 0 0  then        \ Invalid packet: too small
     350: unwrap-v9  ( adr len -- data-adr data-len false | true )
     351   over .rx-desc                                ( adr len )
     352   over >rx-stat le-w@ rx-stat-ok <>  if        ( adr len )
     353      2drop true exit                           ( -- true )
     354   then                                         ( adr len )
     355
     356   /rx-min <  if  drop  true exit  then         ( adr )  \ Invalid packet: too small
    302357
    303358   \ Go to the payload, skipping the descriptor header
    304    dup  dup >rx-offset le-l@ + la1+     ( adr data-adr )
     359   dup  dup >rx-offset le-l@ + /fw-transport +  ( adr data-adr )
    305360   swap >rx-len le-w@                   ( data-adr data-len )
    306361
     
    311366      8 /string                         ( adr' len' )
    312367   then
    313 ;
     368   false
     369;
     370: unwrap-v14  ( adr len -- data-adr data-len )
     371   /rx14-min <  if  drop true exit  then        ( adr ) \ Invalid packet: too small
     372
     373   \ Go to the payload, skipping the descriptor header
     374   >r                                                   ( r: adr )
     375   r@  r@ >rx14-offset le-w@ +  /fw-transport +         ( data-adr r: adr )
     376   r@ >rx14-len le-w@                                   ( data-adr data-len  r: adr )
     377
     378   r> >rx14-type c@  case                               ( data-adr data-len )
     379      2  of  endof   \ Ethernet                         ( data-adr data-len )
     380      3  of             \ 802.3 with LLC + SNAP         ( data-adr data-len )
     381   \ Remove snap header by moving the MAC addresses up
     382   \ That's faster than moving the contents down
     383         over d# 14 + snap-header comp 0=  if           ( data-adr data-len )
     384            over  dup 8 +  d# 12  move                  ( data-adr data-len )
     385            8 /string                                   ( adr' len' )
     386         then
     387      endof
     388      ( default )                                       ( adr len type )
     389         ." libertas.fth: Frame type not supported" cr
     390         3drop true exit
     391   endcase
     392   false
     393;
     394instance defer unwrap-ethernet
    314395
    315396: process-data  ( adr len -- )
    316397   2dup vdump                           ( adr len )
    317    over .rx-desc                        ( adr len )
    318 
    319    over >rx-stat le-w@ rx-stat-ok <>  if  2drop exit  then
    320 
    321    unwrap-pkt  to /data  to data        ( )
     398
     399   unwrap-ethernet  if  exit  then      ( adr' len' )
     400   to /data  to data                    ( )
    322401
    323402   true to got-data?    \ do-process-eapol may unset this
     
    408487      007f  of  ." CMD_TX_RATE_QUERY"                   endof
    409488      00a5  of  ." CMD_SET_BOOT2_VER"                   endof  \ Thin firmware only
     489      00a9  of  ." CMD_FUNC_INIT"                       endof  \ Multifunction versions
     490      00aa  of  ." CMD_FUNC_SHUTDOWN"                   endof
    410491      00b0  of  ." CMD_802_11_BEACON_CTRL"              endof  \ Thin firmware only
    411492      00cb  of  ." CMD_802_11_BEACON_SET"               endof  \ Thin firmware only
     
    484565      h# 0e  of  " WM awake" .event  endof \ n
    485566      h# 11  of  " HWAC - adhoc BCN lost" .event  endof
     567      h# 17  of  endof   \ Suppress:  " WMM status change" .event  endof  \ XXX supposed to issue CMD_WMM_GET_STATUS
    486568      h# 19  of  " RSSI low" .event  endof
    487569      h# 1a  of  " SNR low" .event  endof
     
    490572      h# 1d  of  " SNR high" .event  endof
    491573      h# 23  of  endof  \ Suppress this; the user doesn't need to see it
     574      h# 2b  of  endof  \ Suppress this; the user doesn't need to see it
     575\      h# 2b  of  " Port release" .event  endof
    492576      \ h# 23  of  ." Mesh auto-started"  endof
    493577      h# 30  of   endof  \ Handle this silently
     
    516600: check-for-rx  ( -- )
    517601   got-packet?  if              ( error | buf len 0 )
    518       0= if  process-rx  then   ( )
     602      0= if  2dup vdump process-rx       then   ( )
    519603      recycle-packet            ( )
    520604   then                         ( )
     
    604688: reset-wlan  ( -- )
    605689   " wlan-reset" evaluate
    606    ds-not-ready to driver-state
     690   driver-is-not-ready
    607691   reset-host-bus
    608692;
     
    610694: wake  ( -- )  ;
    611695
    612 : marvel-get-hw-spec  ( -- true | adr false )
     696: get-hw-spec  ( -- true | adr false )
    613697   d# 38 h# 03 ( CMD_GET_HW_SPEC ) prepare-cmd
    614698   outbuf-out  ?dup  if  true exit  then
     
    619703;
    620704
    621 \ The purpose of this is to work around a problem that I don't fully understand.
    622 \ For some reason, when you reopen the device without re-downloading the
    623 \ firmware, the first command silently fails - you don't get a response.
    624 \ This is a "throwaway" command to handle that case without a long timeout
    625 \ or a warning message.
    626 
    627 : nonce-cmd  ( -- )  marvel-get-hw-spec  0=  if  drop  then  ;
     705: set-fw-params  ( -- )
     706   get-hw-spec  0=  if   ( adr )
     707
     708      \ The 4-byte FWReleaseNumber field starts at offset d# 18.
     709      \ Firmware version 2.3.4.p1 is represented in that field
     710      \ as 04 03 02 01, i.e. the first three bytes are little-endian,
     711      \ and the final byte is the "p-number".  The "MSB" at offset
     712      \ d# 20 reflects the major version number, corresponding to
     713      \ the "v-number" of the firmware interface document.
     714
     715      d# 20 + c@  d# 14 >=  if
     716         ['] wrap-v14   to wrap-ethernet
     717         ['] unwrap-v14 to unwrap-ethernet
     718      else
     719         ['] wrap-v9   to wrap-ethernet
     720         ['] unwrap-v9 to unwrap-ethernet
     721      then
     722   then
     723;
     724
     725\ This is necessary for multifunction devices like 8688 and 8787 that have
     726\ extra functions like BlueTooth in addition to WiFi
     727: init-function  ( -- )
     728   0 h# a9 ( CMD_FUNC_INIT ) prepare-cmd
     729   outbuf-wait  if  exit  then
     730;
     731
     732: shutdown-function  ( -- )
     733   0 h# aa ( CMD_FUNC_SHUTDOWN ) prepare-cmd
     734   outbuf-wait  if  exit  then
     735;
    628736
    629737\ =========================================================================
     
    871979   0 to mac-ctrl  set-mac-control  3 to mac-ctrl
    872980;
     981
     982: reconfig-tx-buffer  ( bufsize -- )  \ mwifiex
     983   3  h# d9 ( RECONFIGURE_TX_BUFF )  prepare-cmd
     984   ACTION_SET +xw
     985   ( bufsize ) +xw
     986   outbuf-wait drop
     987;
     988
    873989headers
    874990
     
    16621778\ This is a heavy-handed way to force the device back into baseline state
    16631779\ The recipe above is nicer.
    1664 \   ds-not-ready  to driver-state  \ Forces firmware reload on next open
     1780\   driver-is-not-ready            \ Forces firmware reload on next open
    16651781\   reset-host-bus                 \ Primes module to accept new firmware
    16661782\   false to ap-mode?
     
    17121828
    17131829: .hw-spec  ( -- )
    1714    marvel-get-hw-spec  if
    1715       ." marvel-get-hw-spec command failed" cr
     1830   get-hw-spec  if
     1831      ." get-hw-spec command failed" cr
    17161832   else
    17171833      ." HW interface version: " dup le-w@ u. cr
     
    19022018      ds-ready to driver-state
    19032019   then
     2020   multifunction?  if  init-function  then
    19042021   ?make-mac-address-property
    19052022;
     
    19332050   opencount @ 0=  if
    19342051      init-buf
     2052      driver-is-not-ready
    19352053      /inbuf /outbuf setup-bus-io  if  free-buf false exit  then
    19362054      ?load-fw  if  release-bus-resources free-buf false exit  then
     2055      set-fw-params
    19372056      my-args " supplicant" $open-package to supplicant-ih
    19382057      supplicant-ih 0=  if  release-bus-resources free-buf false exit  then
    1939       nonce-cmd
    19402058      force-open?  if
    19412059         ds-disconnected reset-driver-state
     
    19662084      mac-off
    19672085      supplicant-ih ?dup  if  close-package 0 to supplicant-ih  then
     2086      multifunction?  if  shutdown-function  then
    19682087      release-bus-resources
     2088      driver-is-not-ready
    19692089   then
    19702090;
     
    19742094: write-force  ( adr len -- actual )
    19752095   tuck                                 ( actual adr len )
    1976    wrap-msg                             ( actual adr' len' )
     2096   wrap-ethernet                        ( actual adr' len' )
    19772097   data-out                             ( actual )
    19782098;
  • dev/mmc/sdhci/mv8686/fw8686.fth

    r1185 r3337  
    1 purpose: Marvel 8686 firmware loader
     1purpose: Marvel SDIO WLAN module firmware loader
    22\ See license at end of file
    33
     
    22220 value dn-retry
    2323
    24 : fw-dn-blksz  ( -- blksz )
    25    h# 10 1 sdio-reg@
    26    h# 11 1 sdio-reg@  bwjoin
    27 ;
     24: fw-dn-blksz  ( -- blksz )  host-f1-rd-base-0-reg 1 sdio-reg-w@  ;
    2825: wait-for-fw-dn-blksz  ( -- blksz )
    2926   \ Wait for the first non-zero value
     
    3431: fw-download-ok?  ( -- flag )
    3532   false d# 100 0  do
    36       sdio-scratch@  FIRMWARE_READY =  if  drop true leave  then
     33      sdio-fw-status@  FIRMWARE_READY =  if  drop true leave  then
    3734      d# 10 ms
    3835   loop
     
    4744      fw-adr dn-idx + outbuf 2 pick move        ( len )
    4845      outbuf over sdio-fw! <>  if
    49          4 3 1 sdio-reg!                        \ FN1 CFG = write iomem fail
     46         4 config-reg 1 sdio-reg!               \ FN1 CFG = write iomem fail
    5047      then
    5148      sdio-poll-dl-ready 0=  if  ." Download fw died" cr true exit  then
     
    6663
    6764: download-fw  ( adr len -- error? )
    68    2dup fw-image-ok? 0=  if  ." Bad WLAN firmware image" cr  true exit  then
     65   2dup fw-image-ok? 0=  if  ." Bad WLAN firmware image" cr  true exit  then  ( adr len )
    6966
    7067   wait-for-fw-dn-blksz
     
    7673   fw-download-ok? 0=  if  true exit  then
    7774
    78    3 4 1 sdio-reg!                 \ Enable host interrupt mask
     75   3 host-int-mask-reg 1 sdio-reg!      \ Enable upload (1) and download (2)
     76   mv8787?  if
     77      2 config-reg 1 sdio-reg!             \ Host power up
     78   then
    7979   false
    8080;
     
    9898
    9999: download-helper  ( adr len -- error? )
    100    sdio-scratch@ FIRMWARE_READY =  if  " Firmware downloaded" vtype 2drop true exit  then
     100   sdio-fw-status@ FIRMWARE_READY =  if  " Firmware downloaded" vtype 2drop true exit  then
    101101   2dup fw-image-ok? 0=  if  ." Bad WLAN helper image" cr true exit  then
    102102   (download-helper)
    103103;
    104104
    105 : load-8686-fw  ( -- error? )
    106    wlan-helper find-fw dup  if  ( adr len )
    107       download-helper  if  true exit  then
    108    else                         ( adr len )
    109       2drop                     ( )
    110    then                         ( )
     105: load-sdio-fw  ( -- error? )
     106   helper?  if
     107      wlan-helper find-fw dup  if  ( adr len )
     108         2dup download-helper      ( adr len error? )
     109         -rot free-mem             ( error? )
     110         if  true exit  then       ( )
     111      else                         ( adr len )
     112         2drop                     ( )
     113      then                         ( )
     114   then
    111115
    112116   wlan-fw find-fw dup  if  ( adr len )
    113      download-fw            ( error? )
     117      2dup download-fw      ( adr len error? )
     118      -rot free-mem         ( error? )
    114119   else                     ( adr len )
    115      2drop  false           ( error? )
     120      2drop  true           ( error? )
    116121   then                     ( error? )
    117122;
    118 ' load-8686-fw to load-all-fw
    119 
     123' load-sdio-fw to load-all-fw
    120124
    121125\ LICENSE_BEGIN
  • dev/mmc/sdhci/mv8686/mv8686.fth

    r1832 r3337  
    55hex
    66
    7 " mv8686" encode-string  " module-type" property
    8 
    9 \ This really depends on the firmware that we load, but we don't want
    10 \ to load the firmware in advance, so we hardcode this, assuming that
    11 \ the firmware we include with OFW has both thin and fullmac capability.
    12 0 0 encode-bytes  " thin" property
    1370 0 encode-bytes  " fullmac" property
    148
     
    2014
    2115: wlan-fw  ( -- $ )
    22    " wlan-fw" " $getenv" evaluate  if  " rom:sd8686.bin"  then 
     16   " wlan-fw" " $getenv" evaluate  if  default-fw$  then
    2317;
    2418: wlan-helper  ( -- $ )
     
    7771: release-bus-resources  ( -- )  drain-queue detach-card  ;
    7872
    79 0 value card-attached?
    80 
    8173: ?attach-card  ( -- ok? )
    82    card-attached?  if  true exit  then
    83    attach-card  dup to card-attached?   ( ok? )
     74   attach-card  if  set-version 0=  else  false  then
    8475;
    8576
     
    9283   2drop
    9384   init-queue
    94    ?attach-card 0=  if  ." Fail to attach card" cr true exit  then
     85   ?attach-card 0=  if  ." Failed to attach card" cr true exit  then
    9586   make-my-properties
    9687   init-device
     
    9889;
    9990
    100 : reset-host-bus  ( -- )  false to card-attached?  ;
     91: reset-host-bus  ( -- )  ;
    10192
    10293\ LICENSE_BEGIN
  • dev/mmc/sdhci/mv8686/sdio.fth

    r1179 r3337  
    55headers
    66
     7: sdio-reg@  ( reg# function# -- value )  " sdio-reg@" $call-parent  ;
     8: sdio-reg!  ( value reg# function# -- )  " sdio-reg!" $call-parent  ;
     9: sdio-reg-w@  ( reg# function# -- w.value )
     10   2dup sdio-reg@  -rot      ( low  reg# function# )
     11   swap 1+ swap  sdio-reg@   ( low high )
     12   bwjoin                    ( w.value )
     13;
     14: sdio-w@  ( reg# -- w.value )  1 sdio-reg-w@  ;
     15
     16false instance value multifunction?
     17false instance value helper?
     18false instance value mv8787?
     19instance defer rx-ready?  ( -- len )
     20instance defer get-ctrl-port  ( -- port# )
     21instance defer get-write-port  ( -- port# )
     22
     230 0 2value default-fw$
     24
    7250 value ioport
    8 d# 320 constant blksz                   \ Block size for data tx/rx
    9 d# 32 constant fw-blksz
     26d# 256 constant blksz                   \ Block size for data tx/rx
     27d# 256 constant fw-blksz
     28
     29h#  0 constant config-reg
     30h#  1 constant host-int-rsr-reg
     31h#  2 constant host-int-mask-reg
     32h#  3 constant host-intstatus-reg
     33
     34h#  4 constant rd-bitmap-reg
     35h#  6 constant wr-bitmap-reg
     36h#  8 constant rd-len-reg
     37
     38\ h# 20 constant host-f1-card-rdy-reg
     39\ h# 28 constant host-int-status-reg
     40h# 30 constant card-status-reg
     41h# 34 constant interrupt-mask-reg
     42\ h# 38 constant interrupt-status-reg
     43\ h# 3c constant interrupt-rsr-reg
     44h# 40 constant host-f1-rd-base-0-reg
     45\ h# 41 constant host-f1-rd-base-1-reg
     46h# 6c constant card-misc-cfg-reg
     47h# 60 constant card-fw-status0-reg
     48\ h# 61 constant card-fw-status1-reg
     49\ h# 62 constant card-rx-len-reg
     50\ h# 63 constant card-rx-unit-reg
     51h# 78 constant ioport-reg
     52
     53: ?set-module-property  ( adr len -- )
     54   " module-type" get-my-property  if  ( adr len )
     55      encode-string  " module-type" property  ( )
     56   else                ( adr len prop$ )
     57      2drop 2drop
     58   then
     59;
     60
     61: sdio-fw-status@  ( -- n )
     62   card-fw-status0-reg sdio-w@
     63;
     64
     65: mv8686-rx-ready?  ( -- len )
     66   host-intstatus-reg 1 sdio-reg@
     67   dup 0=  if  exit  then
     68   dup invert 3 and host-intstatus-reg 1 sdio-reg!  \ Clear UP_LD bit
     69   1 and  if
     70      sdio-fw-status@
     71   else
     72      0
     73   then
     74;
     75
     76: use-mv8686  ( -- )
     77    h#  3 to config-reg
     78    h#  4 to host-int-mask-reg
     79    h#  5 to host-intstatus-reg
     80    h# 20 to card-status-reg
     81    h# 10 to host-f1-rd-base-0-reg
     82    h# 34 to card-fw-status0-reg
     83    h# 00 to ioport-reg
     84    d# 320 to blksz
     85    d#  32 to fw-blksz
     86    false to mv8787?
     87    false to multifunction?
     88    true  to helper?
     89    ['] mv8686-rx-ready? to rx-ready?
     90    ['] 0 to get-ctrl-port
     91    ['] 0 to get-write-port
     92
     93    " rom:sd8686.bin" to default-fw$
     94    " mv8686" ?set-module-property
     95
     96    \ This really depends on the firmware that we load, but we don't want
     97    \ to load the firmware in advance, so we hardcode this, assuming that
     98    \ the firmware we include with OFW has both thin and fullmac capability.
     99    " thin" get-my-property  if
     100       0 0 encode-bytes  " thin" property
     101    else
     102       2drop
     103    then
     104;
     1050 instance value rx-port#
     1060 instance value wr-bitmap
     1070 instance value rd-bitmap
     108: update-bitmaps  ( -- )
     109   host-intstatus-reg 1 sdio-reg@
     110   dup 2 and  if  wr-bitmap-reg sdio-w@ to wr-bitmap  then
     111   1 and  if  rd-bitmap-reg sdio-w@ to rd-bitmap  then
     112;
     113: mv8787-rx-ready?  ( -- len )
     114   rd-bitmap  dup  if          ( bitmap )
     115      d# 16 0  do              ( bitmap )
     116         dup 1 and  if         ( bitmap )
     117            drop i  leave      ( port# )
     118         then                  ( bitmap )
     119         2/                    ( bitmap' )
     120      loop                     ( port# )
     121      1 over lshift invert  rd-bitmap and  to rd-bitmap  ( port# )
     122      dup  to rx-port#         ( port# )
     123      2* rd-len-reg + sdio-w@  ( len )
     124   else                        ( 0 )
     125      update-bitmaps           ( 0 )
     126   then
     127;
     128
     129: mv8787-get-ctrl-port  ( -- n )
     130   0
     131;
     132: next-wr-port  ( -- n )
     133   wr-bitmap  2/            ( bits )
     134   dup  0=  if  exit  then  ( bits )
     135   d# 16 1  do              ( bits )
     136      dup  1 and  if        ( bits )
     137         drop               ( )
     138         wr-bitmap  1 i lshift  invert and  to wr-bitmap
     139         i leave            ( n )
     140      then                  ( bits )
     141      2/                    ( bits' )
     142   loop                     ( n )
     143;
     144
     145: mv8787-get-write-port  ( -- n )
     146   begin  next-wr-port  ?dup 0=  while   ( )
     147      update-bitmaps                     ( ) 
     148   repeat                                ( n )
     149;
     150
     151: use-mv8787  ( -- )
     152    h#  0 to config-reg
     153    h#  1 to host-int-rsr-reg
     154    h#  2 to host-int-mask-reg
     155    h#  3 to host-intstatus-reg
     156\   h# 20 to host-f1-card-rdy-reg
     157\   h# 28 to host-restart-reg
     158    h# 30 to card-status-reg
     159    h# 34 to interrupt-mask-reg
     160\   h# 38 to interrupt-status-reg
     161\   h# 3c to interrupt-rsr-reg
     162    h# 40 to host-f1-rd-base-0-reg
     163\   h# 41 to host-f1-rd-base-1-reg
     164    h# 6c to card-misc-cfg-reg
     165    h# 60 to card-fw-status0-reg
     166\   h# 61 to card-fw-status1-reg
     167\   h# 62 to card-rx-len-reg
     168\   h# 63 to card-rx-unit-reg
     169    h# 78 to ioport-reg
     170    d# 256 to blksz
     171    d# 256 to fw-blksz
     172    true to mv8787?
     173    ['] mv8787-rx-ready? to rx-ready?
     174    ['] mv8787-get-ctrl-port  to get-ctrl-port
     175    ['] mv8787-get-write-port  to get-write-port
     176    " rom:mv8787.bin" to default-fw$
     177    " mv8787" ?set-module-property
     178    false to helper?
     179    true to multifunction?
     180;
     181
     182: set-version  ( -- error? )
     183   " sdio-card-id" $call-parent  case
     184      h# 02df9103  of  use-mv8686 false  endof
     185      h# 02df9118  of  use-mv8787 false  endof
     186      ( default )
     187      ." Unsupported SDIO card ID " dup . cr
     188      true  swap
     189   endcase
     190;
    10191
    11192: roundup-blksz  ( n -- n' )  blksz 1- + blksz / blksz *  ;
     
    16197: detach-card  ( -- )       " detach-sdio-card" $call-parent  ;
    17198
    18 \ The following are CMD52 (SDIO) variants
    19 \ Flags: 80:CRC_ERROR  40:ILLEGAL_COMMAND  30:IO_STATE (see spec)
    20 \        08:ERROR  04:reserved  02:INVALID_FUNCTION#  01:OUT_OF_RANGE
    21 
    22 h# cf constant SDIO_FLAG_MASK
    23 
    24 : .io-state  ( flags & 30 -- )
    25    case
    26       h# 00  of  ." card disabled; "  endof
    27       h# 10  of  ." CMD state; "      endof
    28       h# 20  of  ." data transfer; "  endof
    29       h# 30  of  ." reserved; "       endof
    30    endcase
    31 ;
    32 : .sdio-flags  ( flags -- )
    33    dup SDIO_FLAG_MASK and 0=  if  drop exit  then
    34    ." IO_RW_DIRECT response = "
    35    dup h# 80 and  if  ." CRC error; "            then
    36    dup h# 40 and  if  ." illegal command; "      then
    37    dup h# 30 and      .io-state
    38    dup h# 08 and  if  ." error; "                then
    39    dup h# 02 and  if  ." invalid function; "     then
    40    dup h# 01 and  if  ." argument out of range"  then
    41    cr
    42 ;
    43 
    44 : sdio-reg@  ( reg# function# -- value )
    45    " io-b@" $call-parent  .sdio-flags
    46 ;
    47 
    48 : sdio-reg!  ( value reg# function# -- )
    49    " io-b!" $call-parent  .sdio-flags
    50 ;
    51 
    52 : sdio-reg!@  ( value reg# function# -- value' )
    53    " io-b!@" $call-parent  .sdio-flags
    54 ;
    55 
    56 : sdio-scratch@  ( -- value )
    57    h# 34 1 sdio-reg@                        ( lo )
    58    h# 35 1 sdio-reg@                        ( lo hi )
    59    bwjoin                                   ( value )
    60 ;
    61 
    62199: sdio-poll-dl-ready  ( -- ready? )
    63200   false d# 100 0  do
    64       h# 20 1 sdio-reg@                     \ card status register
     201      card-status-reg 1 sdio-reg@
    65202      h# 9 tuck and =  if  drop true leave  then
    66203      d# 100 usec
     
    69206;
    70207
     208: sdio-fw!  ( adr len -- actual )
     209   >r >r ioport 1 true r> r> fw-blksz false " r/w-ioblocks" $call-parent
     210;
     211
     212: init-device  ( -- )
     213   ioport-reg 3 bounds  do  i 1 sdio-reg@  loop         \ Read the IO port
     214   0 bljoin to ioport
     215
     216   7 0 sdio-reg@  h# 20 or  7 0 sdio-reg!       \ Enable async interrupt mode
     217
     218   2 2 0 sdio-reg!      \ Enable IO function 1 (2 = 1 << 1)
     219   3 4 0 sdio-reg!      \ Enable interrupts (1) for function 1 (1 << 1)
     220
     221   mv8787?  if
     222      \ Set host interrupt reset to "read to clear"
     223      host-int-rsr-reg 1 sdio-reg@  h# 3f or  host-int-rsr-reg 1 sdio-reg!
     224
     225\     3  host-int-mask-reg 1 sdio-reg!  \ Enable upload (1) and download (2)
     226
     227      \ Set Dnld/upld to "auto reset"
     228      card-misc-cfg-reg 1 sdio-reg@   h# 10 or  card-misc-cfg-reg 1 sdio-reg!
     229   then
     230;
     231
    71232: sdio-blocks@  ( adr len -- actual )
    72233   >r >r
    73    ioport 1 true  r> r>  blksz true  " r/w-ioblocks" $call-parent  ( actual )
    74 ;
    75 
    76 : sdio-blocks!  ( adr len -- actual )
    77    >r >r ioport 1 true r> r> blksz false " r/w-ioblocks" $call-parent
    78 ;
    79 
    80 : packet-out  ( adr len -- error? )  tuck sdio-blocks! <>  ;
    81 : packet-out-async  ( adr len -- )  sdio-blocks! drop  ;
    82 
    83 : sdio-fw!  ( adr len -- actual )
    84    >r >r ioport 1 true r> r> fw-blksz false " r/w-ioblocks" $call-parent
    85 ;
    86 
    87 : rx-ready?  ( -- len )
    88    5 1 sdio-reg@                                \ Read interrupt status reg
    89    dup 0=  if  exit  then
    90    dup invert 3 and 5 1 sdio-reg!               \ Clear UP_LD bit
    91    1 and  if
    92       sdio-scratch@                             \ Read payload length
    93    else
    94       0
    95    then
    96 ;
     234   rx-port# ioport +  1 true  r> r>  blksz true  " r/w-ioblocks" $call-parent  ( actual )
     235;
     236
     237\ : sdio-blocks!  ( adr len -- actual )
     238\    >r >r x-get-write-port ioport + 1 true r> r> blksz false " r/w-ioblocks" $call-parent
     239\ ;
     240
     241\ 1 is the function number
     242: (sdio-blocks!)  ( adr len port# -- actual )
     243   ioport +  -rot    ( port#  adr len )
     244   1 true  2swap     ( port#  function# inc?  adr len )
     245   blksz false " r/w-ioblocks" $call-parent
     246;
     247
     248\ 0 is the control port number
     249: packet-out  ( adr len -- error? )  tuck  get-ctrl-port  (sdio-blocks!)  <>  ;
     250
     251: packet-out-async  ( adr len -- )  get-write-port  (sdio-blocks!) drop  ;
    97252
    98253: read-poll  ( -- )
     
    104259;
    105260
    106 : init-device  ( -- )
    107    3 0  do  i 1 sdio-reg@  loop         \ Read the IO port
    108    0 bljoin to ioport
    109 
    110    7 0 sdio-reg@  h# 20 or  7 0 sdio-reg!       \ Enable async interrupt mode
    111 
    112    2 2 0 sdio-reg!                      \ Enable IO function
    113    3 4 0 sdio-reg!                      \ Enable interrupts
    114 ;
    115261
    116262headers
  • dev/mmc/sdhci/sdhci.fth

    r3212 r3337  
    931931;
    932932
     933\ To dynamically probe, get the number of functions from bits 30..28 of OCR
     9340 instance value sdio-ocr  \ Contains info about voltages and functions
     935
    933936: set-sdio-voltage  ( -- )
    934937   0 io-send-op-cond                       \ Cmd 5: get card voltage
    935    h# ff.ffff and io-send-op-cond drop     \ Cmd 5: set card voltage
     938   h# ff.ffff and io-send-op-cond          \ Cmd 5: set card voltage
     939   to sdio-ocr
    936940;
    937941
     
    10201024   card-power-off
    10211025\  unmap-regs
     1026;
     1027
     1028: .io-state  ( flags & 30 -- )
     1029   case
     1030      h# 00  of  ." card disabled; "  endof
     1031      h# 10  of  ." CMD state; "      endof
     1032      h# 20  of  ." data transfer; "  endof
     1033      h# 30  of  ." reserved; "       endof
     1034   endcase
     1035;
     1036\ The following are CMD52 (SDIO) variants
     1037\ Flags: 80:CRC_ERROR  40:ILLEGAL_COMMAND  30:IO_STATE (see spec)
     1038\        08:ERROR  04:reserved  02:INVALID_FUNCTION#  01:OUT_OF_RANGE
     1039
     1040h# cf constant SDIO_FLAG_MASK
     1041
     1042: .sdio-flags  ( flags -- )
     1043   dup SDIO_FLAG_MASK and 0=  if  drop exit  then
     1044   ." IO_RW_DIRECT response = "
     1045   dup h# 80 and  if  ." CRC error; "            then
     1046   dup h# 40 and  if  ." illegal command; "      then
     1047   dup h# 30 and      .io-state
     1048   dup h# 08 and  if  ." error; "                then
     1049   dup h# 02 and  if  ." invalid function; "     then
     1050   dup h# 01 and  if  ." argument out of range"  then
     1051   cr
     1052;
     1053
     1054: sdio-reg@  ( reg# func# -- b )  io-b@  .sdio-flags  ;
     1055: sdio-reg!  ( b reg# func# -- )  io-b!  .sdio-flags  ;
     1056
     1057\ Can fetch a tuple list from this offset in function 0
     1058: sdio-cis-ptr  ( function# -- reg# )
     1059   h# 100 * 9 +  3 bounds do  i 0 sdio-reg@  loop  0 bljoin
     1060;
     1061
     1062: cis@+  ( offset -- offset' byte )  dup 1+  swap 0 sdio-reg@  ;
     1063: skip-tuple  ( offset -- offset' )
     1064   cis@+  0  ?do  cis@+  drop  loop  ( code offset' )
     1065;
     1066
     10670 instance value sdio-card-id
     1068: parse-funcid  ( offset -- offset' )
     1069   cis@+ drop            ( offset )  \ Skip length
     1070   cis@+ >r  cis@+ >r  cis@+ >r  cis@+ >r  ( offset  r: ven.low,high prod.low,high )
     1071   r> r> swap bwjoin  r> r> swap bwjoin    ( offset product vendor )
     1072   wljoin to sdio-card-id                  ( vendor.product )
     1073;
     1074
     10750 value sdio-card-blocksize
     10760 value sdio-card-speed
     1077: parse-funce  ( offset -- offset' )
     1078   cis@+ drop     ( offset' )  \ Skip length
     1079   cis@+ 0=  if   ( offset' )  \ Function 0
     1080      cis@+ >r  cis@+  r> swap bwjoin  to sdio-card-blocksize  ( offset' )
     1081      cis@+ to sdio-card-speed     
     1082   else           ( offset )   \ Not function 0
     1083      2-          ( offset' )  \ Back up to length
     1084      skip-tuple  ( offset' )  \ Skip it
     1085   then           ( offset )
     1086;
     1087
     1088: parse-tuples  ( function# -- )
     1089   sdio-cis-ptr  begin         ( offset )
     1090      cis@+                    ( offset' tuple-code )
     1091      dup h# ff <>
     1092   while                       ( offset tuple-code )
     1093      \ Another potentially interesting tuples si h# 15 from which
     1094      \ you can get strings naming the product.
     1095      case
     1096         h# 20  of  parse-funcid  endof
     1097         h# 22  of  parse-funce   endof
     1098         ( default: offset code )
     1099         swap  skip-tuple  swap
     1100      endcase
     1101   repeat                      ( offset tuple-code )
     1102   2drop
    10221103;
    10231104
     
    10461127   set-timeout
    10471128   4-bit
    1048    22 7 0 io-b!      \ Cmd 52 - Set 4-bit bus width and ECSI bit
    1049    h# cf and 0=
     1129   d# 22 7 0 io-b!    \ Cmd 52 - Set 4-bit bus width and ECSI bit
     1130   h# cf and 0=   ( okay? )
     1131   dup  if
     1132      0 parse-tuples  \ Get the card ID and other info
     1133   then
    10501134;
    10511135
     
    11301214   4 pick write-blksz          ( reg# function# inc? addr len r: in? )
    11311215   iodma-setup                 ( reg# function# inc? r: in? )
    1132    wait-write-done  if  -1 exit  then
     1216   wait-write-done  if  r> 2drop 2drop  -1 exit  then
    11331217   r>  if                      ( reg# function# inc? )
    11341218      io-read-blocks
  • dev/mmc/sdhci/slot.fth

    r3026 r3337  
    330 " #address-cells" integer-property
    440 " #size-cells" integer-property
    5 : open  true  ;
    6 : close  ;
     5: open 
     6   [ifdef] my-clock-on  my-clock-on  [then]
     7   true
     8;
     9: close
     10   [ifdef] my-clock-off  my-clock-off  [then]
     11;
    712
    813: r/w-blocks " r/w-blocks" $call-parent  ;
     
    2833: io-b!  " io-b!" $call-parent  ;
    2934: io-b!@  " io-b!@" $call-parent  ;
     35: sdio-reg@  " sdio-reg@" $call-parent  ;
     36: sdio-reg!  " sdio-reg!" $call-parent  ;
     37: sdio-card-id  " sdio-card-id" $call-parent  ;
     38: sdio-card-blocksize  " sdio-card-blocksize" $call-parent  ;
Note: See TracChangeset for help on using the changeset viewer.