Viktor Krivak | 707a5e2 | 2012-08-08 01:42:22 +0000 | [diff] [blame] | 1 | The U-Boot Driver Model Project |
| 2 | =============================== |
| 3 | SPI analysis |
| 4 | ============ |
| 5 | Viktor Krivak <viktor.krivak@gmail.com> |
| 6 | 2012-03-03 |
| 7 | |
| 8 | I) Overview |
| 9 | ----------- |
| 10 | |
| 11 | 1) The SPI driver |
| 12 | ----------------- |
| 13 | |
| 14 | At this moment U-Boot provides standard API that consist of 7 functions: |
| 15 | |
| 16 | void spi_init(void); |
| 17 | struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, |
| 18 | unsigned int max_hz, unsigned int mode); |
| 19 | void spi_free_slave(struct spi_slave *slave); |
| 20 | int spi_claim_bus(struct spi_slave *slave); |
| 21 | void spi_release_bus(struct spi_slave *slave); |
| 22 | int spi_xfer(struct spi_slave *slave, unsigned int bitlen, |
| 23 | const void *dout, void *din, unsigned long flags); |
| 24 | int spi_cs_is_valid(unsigned int bus, unsigned int cs); |
| 25 | void spi_cs_activate(struct spi_slave *slave); |
| 26 | void spi_cs_deactivate(struct spi_slave *slave); |
| 27 | void spi_set_speed(struct spi_slave *slave, uint hz); |
| 28 | |
| 29 | Method spi_init() is usually empty. All necessary configuration are sets by |
| 30 | spi_setup_slave(). But this configuration is usually stored only in memory. |
| 31 | No real hardware sets are made. All hardware settings are provided by method |
| 32 | spi_claim_bus(). This method claims the bus and it can't be claimed again |
| 33 | until it's release. That's mean all calls of method spi_claim_bus() will |
| 34 | fail. But lots of cpu implementation don't meet this behaviour. |
| 35 | Method spi_release_bus() does exact opposite. It release bus directly by |
| 36 | some hardware sets. spi_free_slave() only free memory allocated by |
| 37 | spi_setup_slave(). Method spi_xfer() do actually read and write operation |
| 38 | throw specified bus and cs. Other methods are self explanatory. |
| 39 | |
| 40 | 2) Current limitations |
| 41 | ---------------------- |
| 42 | |
| 43 | Theoretically at this moment api allows use more then one bus per device at |
| 44 | the time. But in real this can be achieved only when all buses have their |
| 45 | own base addresses in memory. |
| 46 | |
| 47 | |
| 48 | II) Approach |
| 49 | ------------ |
| 50 | |
| 51 | 1) Claiming bus |
| 52 | --------------- |
| 53 | |
| 54 | The current api cannot be used because struct spi_slave have to be in |
| 55 | private data. In that case user are prohibited to use different bus on one |
| 56 | device at same time. But when base memory address for bus are different. |
| 57 | It's possible make more instance of this driver. Otherwise it can't can be |
| 58 | done because of hardware limitation. |
| 59 | |
| 60 | 2) API change |
| 61 | ------------- |
| 62 | |
| 63 | Method spi_init() is moved to probe. Methods spi_setup_slave() and |
| 64 | spi_claim_bus() are joined to one method. This method checks if desired bus |
| 65 | exists and is available then configure necessary hardware and claims bus. |
| 66 | Method spi_release_bus() and spi_free_slave() are also joined to meet this |
| 67 | new approach. Other function remain same. Only struct spi_slave was change |
| 68 | to instance. |
| 69 | |
| 70 | struct ops { |
| 71 | int (*spi_request_bus)(struct instance *i, unsigned int bus, |
| 72 | unsigned int cs, unsigned int max_hz, |
| 73 | unsigned int mode); |
| 74 | void (*spi_release_bus)(struct instance *i); |
| 75 | int (*spi_xfer) (struct instance *i, unsigned int bitlen, |
| 76 | const void *dout, void *din, unsigned long flags); |
| 77 | int (*spi_cs_is_valid)(struct instance *i, unsigned int bus, |
| 78 | unsigned int cs); |
| 79 | void (*spi_cs_activate)(struct instance *i); |
| 80 | void (*spi_cs_deactivate)(struct instance *i); |
| 81 | void (*spi_set_speed)(struct instance *i, uint hz); |
| 82 | } |
| 83 | |
| 84 | 3) Legacy API |
| 85 | ------------- |
| 86 | |
| 87 | To easy conversion of the whole driver. Original and new api can exist next |
| 88 | to each other. New API is designed to be only a wrapper that extracts |
| 89 | necessary information from private_data and use old api. When driver can |
| 90 | use more than one bus at the time. New API require multiple instance. One |
| 91 | for each bus. In this case spi_slave have to be copied in each instance. |
| 92 | |
| 93 | 4) Conversion TIME-LINE |
| 94 | ----------------------- |
| 95 | |
| 96 | To prevent build corruption api conversion have to be processed in several |
| 97 | independent steps. In first step all old API methods are renamed. After that |
| 98 | new API and core function are implemented. Next step is conversion of all |
| 99 | board init methods to set platform data. After all these steps it is possible |
| 100 | to start conversion of all remaining calls. This procedure guarantees that |
| 101 | build procedure and binaries are never broken. |
| 102 | |
| 103 | III) Analysis of in-tree drivers |
| 104 | -------------------------------- |
| 105 | |
| 106 | 1) altera_spi.c |
| 107 | --------------- |
| 108 | All methods have designated structure. Simple conversion possible. |
| 109 | |
| 110 | 2) andes_spi.c |
| 111 | -------------- |
| 112 | All methods have designated structure. Simple conversion possible. |
| 113 | |
| 114 | 3) andes_spi.h |
| 115 | -------------- |
| 116 | Support file for andes_spi.c. No conversion is needed. |
| 117 | |
| 118 | 4) armada100_spi.c |
| 119 | ------------------ |
| 120 | All methods have designated structure. Simple conversion possible. |
| 121 | |
| 122 | 5) atmel_dataflash_spi.c |
| 123 | ------------------------ |
| 124 | Wrong placement. Will be moved to another location. |
| 125 | |
| 126 | 6) atmel_spi.c |
| 127 | -------------- |
| 128 | Supports more than one bus. Need some minor change. |
| 129 | |
| 130 | 7) atmel_spi.h |
| 131 | -------------- |
| 132 | Support file for andes_spi.c. No conversion is needed. |
| 133 | |
| 134 | 8) bfin_spi.c |
| 135 | ------------- |
| 136 | Supports more than one bus. Need some minor change. |
| 137 | |
| 138 | 9) cf_spi.c |
| 139 | ----------- |
| 140 | Cooperate with some cpu specific methods from other files. Hard conversion. |
| 141 | |
| 142 | 10) davinci_spi.c |
| 143 | ----------------- |
| 144 | All methods have designated structure. Simple conversion possible. |
| 145 | |
| 146 | 11) davinci_spi.h |
| 147 | ----------------- |
| 148 | Support file for davinci_spi.h. No conversion is needed. |
| 149 | |
| 150 | 12) fsl_espi.c |
| 151 | -------------- |
| 152 | All methods have designated structure. Simple conversion possible. |
| 153 | |
| 154 | 13) kirkwood_spi.c |
| 155 | ------------------ |
| 156 | All methods have designated structure. Simple conversion possible. |
| 157 | |
| 158 | 14) mpc8xxx_spi.c |
| 159 | ----------------- |
| 160 | All methods have designated structure. Simple conversion possible. |
| 161 | |
| 162 | 15) mpc52xx_spi.c |
| 163 | ----------------- |
| 164 | All methods have designated structure. Simple conversion possible. |
| 165 | |
| 166 | 16) mxc_spi.c |
| 167 | ------------- |
| 168 | All methods have designated structure. Simple conversion possible. |
| 169 | |
| 170 | 17) mxs_spi.c |
| 171 | ------------- |
| 172 | All methods have designated structure. Simple conversion possible. |
| 173 | |
| 174 | 18) oc_tiny_spi.c |
| 175 | ----------------- |
| 176 | Supports more than one bus. Need some minor change. |
| 177 | |
| 178 | 19) omap3_spi.c |
| 179 | --------------- |
| 180 | Supports more than one bus. Need some minor change. |
| 181 | |
| 182 | 20) omap3_spi.h |
| 183 | --------------- |
| 184 | Support file for omap3_spi.c. No conversion is needed. |
| 185 | |
| 186 | 21) sh_spi.c |
| 187 | ------------ |
| 188 | All methods have designated structure. Simple conversion possible. |
| 189 | |
| 190 | 22) sh_spi.h |
| 191 | ------------ |
| 192 | Support file for sh_spi.h. No conversion is needed. |
| 193 | |
| 194 | 23) soft_spi.c |
| 195 | -------------- |
| 196 | Use many board specific method linked from other files. Need careful debugging. |
| 197 | |
| 198 | 24) tegra2_spi.c |
| 199 | ---------------- |
| 200 | Some hardware specific problem when releasing bus. |