upstream u-boot with additional patches for our devices/boards:
https://lists.denx.de/pipermail/u-boot/2017-March/282789.html (AXP crashes) ;
Gbit ethernet patch for some LIME2 revisions ;
with SPI flash support
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
6.6 KiB
201 lines
6.6 KiB
13 years ago
|
The U-Boot Driver Model Project
|
||
|
===============================
|
||
|
SPI analysis
|
||
|
============
|
||
|
Viktor Krivak <viktor.krivak@gmail.com>
|
||
|
2012-03-03
|
||
|
|
||
|
I) Overview
|
||
|
-----------
|
||
|
|
||
|
1) The SPI driver
|
||
|
-----------------
|
||
|
|
||
|
At this moment U-Boot provides standard API that consist of 7 functions:
|
||
|
|
||
|
void spi_init(void);
|
||
|
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
|
||
|
unsigned int max_hz, unsigned int mode);
|
||
|
void spi_free_slave(struct spi_slave *slave);
|
||
|
int spi_claim_bus(struct spi_slave *slave);
|
||
|
void spi_release_bus(struct spi_slave *slave);
|
||
|
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
|
||
|
const void *dout, void *din, unsigned long flags);
|
||
|
int spi_cs_is_valid(unsigned int bus, unsigned int cs);
|
||
|
void spi_cs_activate(struct spi_slave *slave);
|
||
|
void spi_cs_deactivate(struct spi_slave *slave);
|
||
|
void spi_set_speed(struct spi_slave *slave, uint hz);
|
||
|
|
||
|
Method spi_init() is usually empty. All necessary configuration are sets by
|
||
|
spi_setup_slave(). But this configuration is usually stored only in memory.
|
||
|
No real hardware sets are made. All hardware settings are provided by method
|
||
|
spi_claim_bus(). This method claims the bus and it can't be claimed again
|
||
|
until it's release. That's mean all calls of method spi_claim_bus() will
|
||
|
fail. But lots of cpu implementation don't meet this behaviour.
|
||
|
Method spi_release_bus() does exact opposite. It release bus directly by
|
||
|
some hardware sets. spi_free_slave() only free memory allocated by
|
||
|
spi_setup_slave(). Method spi_xfer() do actually read and write operation
|
||
|
throw specified bus and cs. Other methods are self explanatory.
|
||
|
|
||
|
2) Current limitations
|
||
|
----------------------
|
||
|
|
||
|
Theoretically at this moment api allows use more then one bus per device at
|
||
|
the time. But in real this can be achieved only when all buses have their
|
||
|
own base addresses in memory.
|
||
|
|
||
|
|
||
|
II) Approach
|
||
|
------------
|
||
|
|
||
|
1) Claiming bus
|
||
|
---------------
|
||
|
|
||
|
The current api cannot be used because struct spi_slave have to be in
|
||
|
private data. In that case user are prohibited to use different bus on one
|
||
|
device at same time. But when base memory address for bus are different.
|
||
|
It's possible make more instance of this driver. Otherwise it can't can be
|
||
|
done because of hardware limitation.
|
||
|
|
||
|
2) API change
|
||
|
-------------
|
||
|
|
||
|
Method spi_init() is moved to probe. Methods spi_setup_slave() and
|
||
|
spi_claim_bus() are joined to one method. This method checks if desired bus
|
||
|
exists and is available then configure necessary hardware and claims bus.
|
||
|
Method spi_release_bus() and spi_free_slave() are also joined to meet this
|
||
|
new approach. Other function remain same. Only struct spi_slave was change
|
||
|
to instance.
|
||
|
|
||
|
struct ops {
|
||
|
int (*spi_request_bus)(struct instance *i, unsigned int bus,
|
||
|
unsigned int cs, unsigned int max_hz,
|
||
|
unsigned int mode);
|
||
|
void (*spi_release_bus)(struct instance *i);
|
||
|
int (*spi_xfer) (struct instance *i, unsigned int bitlen,
|
||
|
const void *dout, void *din, unsigned long flags);
|
||
|
int (*spi_cs_is_valid)(struct instance *i, unsigned int bus,
|
||
|
unsigned int cs);
|
||
|
void (*spi_cs_activate)(struct instance *i);
|
||
|
void (*spi_cs_deactivate)(struct instance *i);
|
||
|
void (*spi_set_speed)(struct instance *i, uint hz);
|
||
|
}
|
||
|
|
||
|
3) Legacy API
|
||
|
-------------
|
||
|
|
||
|
To easy conversion of the whole driver. Original and new api can exist next
|
||
|
to each other. New API is designed to be only a wrapper that extracts
|
||
|
necessary information from private_data and use old api. When driver can
|
||
|
use more than one bus at the time. New API require multiple instance. One
|
||
|
for each bus. In this case spi_slave have to be copied in each instance.
|
||
|
|
||
|
4) Conversion TIME-LINE
|
||
|
-----------------------
|
||
|
|
||
|
To prevent build corruption api conversion have to be processed in several
|
||
|
independent steps. In first step all old API methods are renamed. After that
|
||
|
new API and core function are implemented. Next step is conversion of all
|
||
|
board init methods to set platform data. After all these steps it is possible
|
||
|
to start conversion of all remaining calls. This procedure guarantees that
|
||
|
build procedure and binaries are never broken.
|
||
|
|
||
|
III) Analysis of in-tree drivers
|
||
|
--------------------------------
|
||
|
|
||
|
1) altera_spi.c
|
||
|
---------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
2) andes_spi.c
|
||
|
--------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
3) andes_spi.h
|
||
|
--------------
|
||
|
Support file for andes_spi.c. No conversion is needed.
|
||
|
|
||
|
4) armada100_spi.c
|
||
|
------------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
5) atmel_dataflash_spi.c
|
||
|
------------------------
|
||
|
Wrong placement. Will be moved to another location.
|
||
|
|
||
|
6) atmel_spi.c
|
||
|
--------------
|
||
|
Supports more than one bus. Need some minor change.
|
||
|
|
||
|
7) atmel_spi.h
|
||
|
--------------
|
||
|
Support file for andes_spi.c. No conversion is needed.
|
||
|
|
||
|
8) bfin_spi.c
|
||
|
-------------
|
||
|
Supports more than one bus. Need some minor change.
|
||
|
|
||
|
9) cf_spi.c
|
||
|
-----------
|
||
|
Cooperate with some cpu specific methods from other files. Hard conversion.
|
||
|
|
||
|
10) davinci_spi.c
|
||
|
-----------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
11) davinci_spi.h
|
||
|
-----------------
|
||
|
Support file for davinci_spi.h. No conversion is needed.
|
||
|
|
||
|
12) fsl_espi.c
|
||
|
--------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
13) kirkwood_spi.c
|
||
|
------------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
14) mpc8xxx_spi.c
|
||
|
-----------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
15) mpc52xx_spi.c
|
||
|
-----------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
16) mxc_spi.c
|
||
|
-------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
17) mxs_spi.c
|
||
|
-------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
18) oc_tiny_spi.c
|
||
|
-----------------
|
||
|
Supports more than one bus. Need some minor change.
|
||
|
|
||
|
19) omap3_spi.c
|
||
|
---------------
|
||
|
Supports more than one bus. Need some minor change.
|
||
|
|
||
|
20) omap3_spi.h
|
||
|
---------------
|
||
|
Support file for omap3_spi.c. No conversion is needed.
|
||
|
|
||
|
21) sh_spi.c
|
||
|
------------
|
||
|
All methods have designated structure. Simple conversion possible.
|
||
|
|
||
|
22) sh_spi.h
|
||
|
------------
|
||
|
Support file for sh_spi.h. No conversion is needed.
|
||
|
|
||
|
23) soft_spi.c
|
||
|
--------------
|
||
|
Use many board specific method linked from other files. Need careful debugging.
|
||
|
|
||
|
24) tegra2_spi.c
|
||
|
----------------
|
||
|
Some hardware specific problem when releasing bus.
|