[openfirmware] [commit] r2138 - cpu/arm/olpc/1.75

repository service svn at openfirmware.info
Fri Jan 21 21:46:15 CET 2011


Author: wmb
Date: Fri Jan 21 21:46:15 2011
New Revision: 2138
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2138

Log:
OLPC XO-1.75 - added barely-tested support for EC reflashing via EDI interconnect.

Added:
   cpu/arm/olpc/1.75/bbedi.fth
   cpu/arm/olpc/1.75/edi.fth
Modified:
   cpu/arm/olpc/1.75/devices.fth

Added: cpu/arm/olpc/1.75/bbedi.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ cpu/arm/olpc/1.75/bbedi.fth	Fri Jan 21 21:46:15 2011	(r2138)
@@ -0,0 +1,217 @@
+\ See license at end of file
+purpose: Bit-banged SPI bus driver for KB3731 EC "EDI" interface
+
+d# 103 constant edi-miso-gpio#
+d# 104 constant edi-cs-gpio#
+d# 105 constant edi-mosi-gpio#
+d# 106 constant edi-clk-gpio#
+
+: edi-cs-on   ( -- )  edi-cs-gpio# gpio-clr  ;
+: edi-cs-off  ( -- )  edi-cs-gpio# gpio-set  ;
+
+: edi-clk-lo  ( -- )  edi-clk-gpio# gpio-clr  ;
+: edi-clk-hi  ( -- )  edi-clk-gpio# gpio-set  ;
+
+0 [if]
+\ All this timing stuff is pointless because the GPIOs are so slow
+\ that the problem is to make the clock go fast enough to satisfy
+\ the initial connection speed requirement.
+
+\ We need to run at between 1 and 2 MHz for the initial connection,
+\ and then we can go faster, up to 16 Mhz.
+\ The half-cycle period for 1-2 MHz is between 250 ns and 500 ns.
+\ Timer0 runs at 6.5 MHz so each tick is about 150 ns.
+\ Two ticks is 300 ns, three is 450 ns.
+code spins  ( count -- )
+   cmp     tos,#0
+   <>  if
+      begin
+         subs    tos,tos,#1
+      0= until
+   then
+   pop     tos,sp 
+c;
+
+d# 150 value edi-dly-spins
+: edi-dly  ( -- )  edi-dly-spins spins  ;
+
+\ CPU clock is 800 Mhz, so 1.25 ns/clock
+\ spins is 2 clocks/spin, so 2.5 ns/spin
+\ Slow clock must be between 1 and 2 MHz, so period is between 1000 and 500 ns.
+\ edi-dly is a half cycle, so edi-dly for slow clock is between 500 and 250 ns.
+\ So we need between 200 and 100 spins for slow edi-dly
+\ Fast clock can be up to 16 Mhz, so full-cycle period of 62.5 ns, half-cycle
+\ period of >= 31.25 ns, so >= 12.5 spins at 2.5. ns/spin.
+
+: slow-edi-clock  ( -- )  d# 150 to edi-dly-spins  ;
+: fast-edi-clock  ( -- )  d# 13 to edi-dly-spins  ;
+
+code edi-bit!  ( flag -- )
+   mov   r0,#0x200
+   set   r1,#0xd4019100
+   cmp   tos,#0
+   streq r0,[r1,#0x24]  \ Clr MOSI if flag is 0
+   strne r0,[r1,#0x18]  \ Set MOSI if flag is non0
+   mov   r0,#0x400
+   str   r0,[r1,#0x18]  \ Set CLK
+   str   r0,[r1,#0x24]  \ Clr CLK
+   pop tos,sp
+c;
+
+[ifndef] edi-bit!
+: edi-bit!  ( flag -- )
+   edi-mosi-gpio#  swap  if  gpio-set  else  gpio-clr  then
+   edi-clk-hi
+   edi-dly
+   edi-clk-lo
+   edi-dly
+;
+[then]
+
+[ifndef] edi-bit!
+: edi-bit!  ( flag -- )
+   if
+      [ edi-mosi-gpio# >gpio-pin h# 18 + ] dliteral l!  \ Fast gpio-set
+   else
+      [ edi-mosi-gpio# >gpio-pin h# 24 + ] dliteral l!  \ Fast gpio-clr
+   then
+   [ edi-clk-gpio# >gpio-pin h# 18 + ] dliteral l!  \ Fast gpio-set
+\   edi-dly
+   [ edi-clk-gpio# >gpio-pin h# 24 + ] dliteral l!  \ Fast gpio-set
+\   edi-dly
+;
+[then]
+
+: edi-out  ( b -- )
+   8 0  do                   ( b )
+      dup h# 80 and edi-bit! ( b )
+      2*                     ( b' )
+   loop                      ( b )
+   drop                      ( )
+;   
+: edi-bit@  ( -- flag )
+   edi-clk-hi
+   edi-dly
+   edi-miso-gpio# gpio-pin@
+   edi-clk-lo
+   edi-dly
+;
+: edi-in-h  ( b -- )
+   0                         ( b )
+   8 0  do                   ( b )
+      2* edi-bit@ 1 and or   ( b' )
+   loop                      ( b )
+;   
+[else]
+code edi-out0  ( byte -- )
+   mov   r2,#8
+   mov   r0,#0x200         \ MOSI mask
+   set   r1,#0xd4019100    \ GPIO register address
+   mov   r4,#0x400         \ CLK mask
+   begin
+      ands  r3,tos,#0x80   \ Test bit
+
+      strne r0,[r1,#0x18]  \ Set MOSI if bit is non0
+      streq r0,[r1,#0x24]  \ Clr MOSI if bit is 0
+
+      str   r4,[r1,#0x18]  \ Set CLK
+      str   r4,[r1,#0x24]  \ Clr CLK
+
+      add   tos,tos,tos    \ Left shift TOS      
+   decs r2,1
+   0= until
+
+   pop tos,sp
+c;
+code edi-out  ( byte -- )
+   mov   r2,#8
+   mov   r0,#0x200         \ MOSI mask
+   set   r1,#0xd4019100    \ GPIO register address
+   mov   r4,#0x400         \ CLK mask
+   mov   r5,#0x600         \ CLK and MOSI mask
+   begin
+      ands  r3,tos,#0x80   \ Test bit
+
+      strne r5,[r1,#0x18]  \ Set MOSI and CLK in the same operation if bit is non0
+      streq r0,[r1,#0x24]  \ Clr MOSI
+      streq r4,[r1,#0x18]  \ Set CLK
+
+      str   r4,[r1,#0x24]  \ Clr CLK
+
+      add   tos,tos,tos    \ Left shift TOS      
+   decs r2,1
+   0= until
+
+   pop tos,sp
+c;
+code edi-in  ( -- byte )
+   psh   tos,sp
+   mov   tos,#0            \ Initial byte value
+   mov   r2,#8
+   mov   r3,#0x100
+   set   r1,#0xd4019100    \ GPIO register address
+   mov   r4,#0x400         \ CLK mask
+   begin
+      add   tos,tos,tos    \ Left shift byte
+
+      str   r4,[r1,#0x18]  \ Set CLK
+
+      \ This delay is necessary to let the MMP2 GPIO pin clock in the
+      \ data value.  Without the delay, bit values get lost.
+      mov   r7,#0x160      \ Delay spins
+      begin
+         decs r7,#1
+      0= until
+
+      ldr   r0,[r1]        \ Read pin register
+      str   r0,[r3],#4
+      str   r4,[r1,#0x24]  \ Clr CLK
+      ands  r0,r0,#0x80    \ Test MISO bit
+      incne tos,1          \ Set bit in byte
+
+   decs r2,1
+   0= until
+c;
+
+[then]
+
+
+: edi-spi-start  ( -- )
+   ['] edi-in      to spi-in
+   ['] edi-out     to spi-out
+   ['] edi-cs-on   to spi-cs-on
+   ['] edi-cs-off  to spi-cs-off
+   d# 16 to spi-us
+   ['] noop to spi-reprogrammed
+
+\  use-edi-flash-read   \ Defined later
+
+   edi-clk-lo  edi-cs-off
+;
+
+: use-edi-spi  ( -- )  ['] edi-spi-start  to spi-start  ;
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 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/1.75/devices.fth
==============================================================================
--- cpu/arm/olpc/1.75/devices.fth	Fri Jan 21 21:43:11 2011	(r2137)
+++ cpu/arm/olpc/1.75/devices.fth	Fri Jan 21 21:46:15 2011	(r2138)
@@ -308,6 +308,9 @@
 fload ${BP}/cpu/arm/olpc/1.75/accelerometer.fth
 fload ${BP}/cpu/arm/olpc/1.75/compass.fth
 
+fload ${BP}/cpu/arm/olpc/1.75/bbedi.fth
+fload ${BP}/cpu/arm/olpc/1.75/edi.fth
+
 warning @ warning off
 : stand-init
    stand-init

Added: cpu/arm/olpc/1.75/edi.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ cpu/arm/olpc/1.75/edi.fth	Fri Jan 21 21:46:15 2011	(r2138)
@@ -0,0 +1,266 @@
+\ See license at end of file
+purpose: Access and FLASH programming for KB3731 EC via its "EDI" interface
+
+\ The following code depends on externally-privided low-level SPI bus
+\ access primitives that are defined in "bbedi.fth" for the "native"
+\ case (EC and CPU on the same machine).  They can also be implemented
+\ for tethered programming from a different machine like an XO-1.5.
+\
+\ Low-level primitives:
+\  spi-start  ( -- )      - Init SPI bus
+\  spi-cs-on  ( -- )      - Assert SPI-bus CS#
+\  spi-cs-off ( -- )      - Deassert SPI-bus CS#
+\  spi-out    ( byte -- ) - Send byte
+\  spi-in     ( -- byte ) - Receive byte
+
+h# 128 constant /flash-page
+
+: edi-cmd,adr  ( offset cmd -- )   \ Send command plus 3 address bytes
+   spi-cs-on     ( offset cmd )
+   spi-out       ( offset )
+   lbsplit drop  spi-out spi-out spi-out  ( )
+;
+: edi-b!  ( byte offset -- )  \ Write byte to address inside EC chip
+   h# 40 edi-cmd,adr spi-out spi-cs-off
+;
+[ifndef] edi-wait-b
+: edi-wait-b  ( -- b )  \ Wait for and receive EC response byte
+   d# 10 0  do 
+      spi-in h# 50 =  if
+         spi-in           ( b )
+         spi-cs-off       ( b )
+         unloop exit
+      then
+   loop
+   true abort" EDI byte in timeout"
+;
+[then]
+: edi-b@  ( offset -- b )  \ Read byte from address inside EC chip
+   h# 30 edi-cmd,adr  edi-wait-b
+;
+: edi-next-b@  ( -- b )  \ Read the next EC byte - auto-increment address
+   spi-cs-on  h# 33 spi-out  edi-wait-b
+;
+: edi-disable  ( -- )  \ Turn off the EC EDI interface
+   spi-cs-on
+   h# f3 spi-out
+   spi-in      ( b )
+   spi-cs-off
+   h# 8c <>  if
+      ." Unexpected response from edi-disable" cr
+   then 
+;
+
+0 [if]
+: edi-w@  ( offset -- w )  \ Read 16-bit word from address inside EC chip
+   dup 1+  edi-b@         ( offset b.low )
+   swap edi-b@            ( b.low b.high )
+   bwjoin
+;
+[else]
+: edi-w@  ( offset -- w )  \ Read 16-bit word from address inside EC chip
+   edi-b@ edi-next-b@ swap bwjoin
+;
+[then]
+: reset-8051  ( -- )  \ Reset 8-5
+   h# f010 edi-b@  1 or  h# f010 edi-b!
+;
+: unreset-8051  ( -- )  \ Reset 8-5
+   h# f010 edi-b@  1 invert and  h# f010 edi-b!
+;
+
+\ 0 in bit 0 selects masked ROM as code source for 8051, 1 selects FLASH
+\ The 8051 should be in reset mode when changing that bit.
+: select-flash  ( -- )  \ Setup for access to FLASH inside the EC
+   h# f011 edi-b@  1 or  h# f011 edi-b!
+;
+
+: probe-rdid  ( -- found? )  \ Verify that the EC is the one we think it is
+   select-flash
+   h# f01c ['] edi-w@ catch  if   ( x )
+      drop false exit             ( -- false )
+   then                           ( id )
+
+   1 invert and  h# 3730 =
+;
+
+: wait-flash-busy  ( -- )  \ Wait for an erase/programming operation to complete
+   get-msecs  h# 1000 +    ( limit )
+   begin                   ( limit )
+      h# fea0 edi-b@       ( limit b )
+      h# 80 and  if        ( limit )
+         drop exit
+      then                 ( limit )
+      dup get-msecs - 0<=  ( limit timeout? )
+   until                   ( limit )
+   drop
+   true abort" EDI FLASH busy timeout"
+;
+
+: flash-cmd  ( b -- )  h# fea7 edi-b!  ;
+
+: set-offset  ( offset -- )
+   wbsplit                          ( offset-low offset-hi )
+   h# fea9 edi-b!  h# fea8 edi-b!   ( )
+;
+
+: erase-page  ( offset -- )
+   wait-flash-busy     ( offset )
+   set-offset          ( )
+   h# 20 flash-cmd     ( )
+;
+
+: erase-chip  ( -- )  wait-flash-busy  h# 60 flash-cmd  wait-flash-busy  ;
+
+: send-byte  ( b offset -- )  set-offset  h# feaa edi-b!  2 flash-cmd  ;
+
+: program-page  ( adr offset -- )
+   \ Clear HVPL
+   wait-flash-busy  h# 80 flash-cmd  ( adr offset )
+
+   \ Fill the page buffer
+   swap  /flash-page  bounds  do  ( offset )
+      i c@  over  send-byte       ( offset )
+      1+                          ( offset' )
+   loop                           ( offset )
+   drop                           ( )
+
+   \ Commit the buffer to the FLASH memory
+   wait-flash-busy                ( )  \ Redundant wait?
+   h# 70 flash-cmd                ( )
+   wait-flash-busy                ( )
+;
+: edi-read-flash  ( adr len offset -- )
+   over 0=  if  3drop exit  then  ( adr len offset )
+   edi-b@                         ( adr len byte )
+   third c!                       ( adr len )
+   1 /string  bounds  ?do         ( )
+      edi-next-b@ i c!            ( )
+   loop                           ( )
+;
+: edi-open  ( -- )
+   \ slow-edi-clock   \ Target speed between 1 and 2 MHz
+   spi-start
+   reset-8051
+   \ fast-edi-clock   \ Target speed up to 16 MHz
+   \ reset
+;
+0 [if]
++// IO3731 internal register locations
++#define E51_RST         0xf010  // 8051 Reset Control
++#define CODE_SEL        0xf011  // Code Source selection
++#define CHIP_ID_H       0xf01c  // Chip ID High Byte
++#define CHIP_ID_L       0xf01d  // Chip ID Low Byte
++#define IOSCCR		0xf02b  // Internal OSC Control
++#define LVD_TRIM	0xf035  // Low Voltage Detect Trim
++#define XBIEFCFG        0xfea0  // XBI Embedded Flash Configuration
++#define XBIEFSIG1       0xfea1  // XBI Embedded Flash signals 1 in FW mode
++#define XBIEFSIG2       0xfea2  // XBI Embedded Flash signals 2 in FW mode
++#define XBIPUMP         0xfea3  // XBI Pump IP trimming bits
++#define XBIFM           0xfea4  // XBI Flash IP trimming bits
++#define XBIVR           0xfea5  // XBI VR IP trimming bits
++#define XBIMISC         0xfea6  // XBI MISC Reg
++#define XBIEFCMD        0xfea7  // XBI Embedded Flash Command Port
++#define XBIEFA0         0xfea8  // XBI Embedded Flash Address high
++#define XBIEFA1         0xfea9  // XBI Embedded Flash Address low
++#define XBIEFDO         0xfeaa  // XBI Embedded Flash Output Data Port
++#define XBIEFDI         0xfeab  // XBI Embedded Flash Input Data Port
++
++
++// IO3731 embedded flash command support:
++#define PAGE_LATCH     0x02  // Page latch
++#define READ           0x03  // Read
++#define ERASEPAGE      0x20  // Erase selected page
++#define ERASECHIP      0x60  // Erase whole e-flash
++#define PROGRAMPAGE    0x70  // Program selected page
++#define CLEARPAGELATCH 0x80  // Clear HVPL data
++#define READTRIMDATA   0x90  // Read Trim data from special rows
+[then]
+: trim@  ( offset -- b )
+   set-offset
+   h# 90 flash-cmd
+   wait-flash-busy
+   h# feab edi-b@
+;
+: trim-tune  ( -- )
+\   firmware-id  0=  if
+      \ Read trim data and write to register (for ENE macros)
+      h# 100 trim@  h# 5a =  if
+         \ Low Voltage Detect TRIM register
+         h# f035 edi-b@               ( val )
+         h# 1f invert and             ( val' )
+         h# 101 trim@ h# 1f and  or   ( val' )
+         h# f035 edi-b!               ( )
+
+         \ Int Oscillator Control register - HKCOMOS32K
+         h# f02b edi-b@               ( val )
+         h# 0f invert and             ( val' )
+         h# 102 trim@ h# 0f and  or   ( val' )
+         h# f02b edi-b!               ( )
+      then
+
+      \ Read trim data and write to register (for HHNEC macros)
+      h# 1ff trim@  0<>  if
+         \ XBIMISC register - S[4:0]
+         h# fea6 edi-b@               ( val )
+         h# 1f invert and             ( val' )
+         h# 1f0 trim@ h# 1f and  or   ( val' )
+         h# fea6 edi-b!               ( )
+         
+         \ XBI Pump IP register - Pdac[3:0] | Ndac[3:0]
+         h# 1f1 trim@ 4 lshift        ( val )
+         h# 1f2 trim@ h# 0f and or    ( val' )
+         h# fea3 edi-b!               ( )
+         
+         \ XBI Flash IP register - Bdac[3:0]
+         h# fea4 edi-b@               ( val )
+         h# 0f invert and             ( val' )
+         h# 1f4 trim@ h# 0f and  or   ( val' )
+         h# fea4 edi-b!               ( )
+         
+         \ XB VR IP register - Tctrim[3:0] | Abstrim[3:0]  (Vref temp coef and absolute value)
+         h# 1f5 trim@ 4 lshift        ( val )
+         h# 1f6 trim@ h# 0f and or    ( val' )
+         h# fea5 edi-b!               ( )
+         
+         \ XBI Flash IP register - Itim[3:0] - Must be last
+         h# fea4 edi-b@               ( val )
+         h# f0 invert and             ( val' )
+         h# 1f4 trim@ 4 lshift  or    ( val' )
+         h# fea4 edi-b!               ( )
+         
+         3 us  \ Required after Itim[3:0] update
+
+         \ XBI Embedded Flash Configuration register
+         h# 10 h# fea0 edi-b!    \ Set FLASH clock
+
+         h# fea0 edi-b@  h# d0  =  if
+            ." Warning - XBIECFG is 0xd0" cr
+         then
+      then
+\   then
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 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



More information about the openfirmware mailing list