diff options
| -rw-r--r-- | Documentation/devicetree/bindings/spi/qcom,spi-qup.txt | 8 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/spi/spi-rockchip.txt | 4 | ||||
| -rw-r--r-- | drivers/spi/spi-qup.c | 336 | ||||
| -rw-r--r-- | drivers/spi/spi-rockchip.c | 36 | ||||
| -rw-r--r-- | drivers/spi/spi-rspi.c | 124 | ||||
| -rw-r--r-- | drivers/spi/spi-s3c64xx.c | 4 | ||||
| -rw-r--r-- | drivers/spi/spi-sc18is602.c | 2 |
7 files changed, 468 insertions, 46 deletions
diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt index e2c88df2cc15..5c090771c016 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt | |||
| @@ -33,6 +33,11 @@ Optional properties: | |||
| 33 | nodes. If unspecified, a single SPI device without a chip | 33 | nodes. If unspecified, a single SPI device without a chip |
| 34 | select can be used. | 34 | select can be used. |
| 35 | 35 | ||
| 36 | - dmas: Two DMA channel specifiers following the convention outlined | ||
| 37 | in bindings/dma/dma.txt | ||
| 38 | - dma-names: Names for the dma channels, if present. There must be at | ||
| 39 | least one channel named "tx" for transmit and named "rx" for | ||
| 40 | receive. | ||
| 36 | 41 | ||
| 37 | SPI slave nodes must be children of the SPI master node and can contain | 42 | SPI slave nodes must be children of the SPI master node and can contain |
| 38 | properties described in Documentation/devicetree/bindings/spi/spi-bus.txt | 43 | properties described in Documentation/devicetree/bindings/spi/spi-bus.txt |
| @@ -51,6 +56,9 @@ Example: | |||
| 51 | clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>; | 56 | clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>; |
| 52 | clock-names = "core", "iface"; | 57 | clock-names = "core", "iface"; |
| 53 | 58 | ||
| 59 | dmas = <&blsp1_bam 13>, <&blsp1_bam 12>; | ||
| 60 | dma-names = "rx", "tx"; | ||
| 61 | |||
| 54 | pinctrl-names = "default"; | 62 | pinctrl-names = "default"; |
| 55 | pinctrl-0 = <&spi8_default>; | 63 | pinctrl-0 = <&spi8_default>; |
| 56 | 64 | ||
diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.txt b/Documentation/devicetree/bindings/spi/spi-rockchip.txt index 467dec441c62..0c491bda4c65 100644 --- a/Documentation/devicetree/bindings/spi/spi-rockchip.txt +++ b/Documentation/devicetree/bindings/spi/spi-rockchip.txt | |||
| @@ -24,6 +24,9 @@ Optional Properties: | |||
| 24 | - dmas: DMA specifiers for tx and rx dma. See the DMA client binding, | 24 | - dmas: DMA specifiers for tx and rx dma. See the DMA client binding, |
| 25 | Documentation/devicetree/bindings/dma/dma.txt | 25 | Documentation/devicetree/bindings/dma/dma.txt |
| 26 | - dma-names: DMA request names should include "tx" and "rx" if present. | 26 | - dma-names: DMA request names should include "tx" and "rx" if present. |
| 27 | - rx-sample-delay-ns: nanoseconds to delay after the SCLK edge before sampling | ||
| 28 | Rx data (may need to be fine tuned for high capacitance lines). | ||
| 29 | No delay (0) by default. | ||
| 27 | 30 | ||
| 28 | 31 | ||
| 29 | Example: | 32 | Example: |
| @@ -33,6 +36,7 @@ Example: | |||
| 33 | reg = <0xff110000 0x1000>; | 36 | reg = <0xff110000 0x1000>; |
| 34 | dmas = <&pdma1 11>, <&pdma1 12>; | 37 | dmas = <&pdma1 11>, <&pdma1 12>; |
| 35 | dma-names = "tx", "rx"; | 38 | dma-names = "tx", "rx"; |
| 39 | rx-sample-delay-ns = <10>; | ||
| 36 | #address-cells = <1>; | 40 | #address-cells = <1>; |
| 37 | #size-cells = <0>; | 41 | #size-cells = <0>; |
| 38 | interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; | 42 | interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; |
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index 2b2c359f5a50..810a7fae3479 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 23 | #include <linux/pm_runtime.h> | 23 | #include <linux/pm_runtime.h> |
| 24 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
| 25 | #include <linux/dmaengine.h> | ||
| 26 | #include <linux/dma-mapping.h> | ||
| 25 | 27 | ||
| 26 | #define QUP_CONFIG 0x0000 | 28 | #define QUP_CONFIG 0x0000 |
| 27 | #define QUP_STATE 0x0004 | 29 | #define QUP_STATE 0x0004 |
| @@ -116,6 +118,8 @@ | |||
| 116 | 118 | ||
| 117 | #define SPI_NUM_CHIPSELECTS 4 | 119 | #define SPI_NUM_CHIPSELECTS 4 |
| 118 | 120 | ||
| 121 | #define SPI_MAX_DMA_XFER (SZ_64K - 64) | ||
| 122 | |||
| 119 | /* high speed mode is when bus rate is greater then 26MHz */ | 123 | /* high speed mode is when bus rate is greater then 26MHz */ |
| 120 | #define SPI_HS_MIN_RATE 26000000 | 124 | #define SPI_HS_MIN_RATE 26000000 |
| 121 | #define SPI_MAX_RATE 50000000 | 125 | #define SPI_MAX_RATE 50000000 |
| @@ -140,9 +144,14 @@ struct spi_qup { | |||
| 140 | struct completion done; | 144 | struct completion done; |
| 141 | int error; | 145 | int error; |
| 142 | int w_size; /* bytes per SPI word */ | 146 | int w_size; /* bytes per SPI word */ |
| 147 | int n_words; | ||
| 143 | int tx_bytes; | 148 | int tx_bytes; |
| 144 | int rx_bytes; | 149 | int rx_bytes; |
| 145 | int qup_v1; | 150 | int qup_v1; |
| 151 | |||
| 152 | int use_dma; | ||
| 153 | struct dma_slave_config rx_conf; | ||
| 154 | struct dma_slave_config tx_conf; | ||
| 146 | }; | 155 | }; |
| 147 | 156 | ||
| 148 | 157 | ||
| @@ -198,7 +207,6 @@ static int spi_qup_set_state(struct spi_qup *controller, u32 state) | |||
| 198 | return 0; | 207 | return 0; |
| 199 | } | 208 | } |
| 200 | 209 | ||
| 201 | |||
| 202 | static void spi_qup_fifo_read(struct spi_qup *controller, | 210 | static void spi_qup_fifo_read(struct spi_qup *controller, |
| 203 | struct spi_transfer *xfer) | 211 | struct spi_transfer *xfer) |
| 204 | { | 212 | { |
| @@ -266,6 +274,107 @@ static void spi_qup_fifo_write(struct spi_qup *controller, | |||
| 266 | } | 274 | } |
| 267 | } | 275 | } |
| 268 | 276 | ||
| 277 | static void spi_qup_dma_done(void *data) | ||
| 278 | { | ||
| 279 | struct spi_qup *qup = data; | ||
| 280 | |||
| 281 | complete(&qup->done); | ||
| 282 | } | ||
| 283 | |||
| 284 | static int spi_qup_prep_sg(struct spi_master *master, struct spi_transfer *xfer, | ||
| 285 | enum dma_transfer_direction dir, | ||
| 286 | dma_async_tx_callback callback) | ||
| 287 | { | ||
| 288 | struct spi_qup *qup = spi_master_get_devdata(master); | ||
| 289 | unsigned long flags = DMA_PREP_INTERRUPT | DMA_PREP_FENCE; | ||
| 290 | struct dma_async_tx_descriptor *desc; | ||
| 291 | struct scatterlist *sgl; | ||
| 292 | struct dma_chan *chan; | ||
| 293 | dma_cookie_t cookie; | ||
| 294 | unsigned int nents; | ||
| 295 | |||
| 296 | if (dir == DMA_MEM_TO_DEV) { | ||
| 297 | chan = master->dma_tx; | ||
| 298 | nents = xfer->tx_sg.nents; | ||
| 299 | sgl = xfer->tx_sg.sgl; | ||
| 300 | } else { | ||
| 301 | chan = master->dma_rx; | ||
| 302 | nents = xfer->rx_sg.nents; | ||
| 303 | sgl = xfer->rx_sg.sgl; | ||
| 304 | } | ||
| 305 | |||
| 306 | desc = dmaengine_prep_slave_sg(chan, sgl, nents, dir, flags); | ||
| 307 | if (!desc) | ||
| 308 | return -EINVAL; | ||
| 309 | |||
| 310 | desc->callback = callback; | ||
| 311 | desc->callback_param = qup; | ||
| 312 | |||
| 313 | cookie = dmaengine_submit(desc); | ||
| 314 | |||
| 315 | return dma_submit_error(cookie); | ||
| 316 | } | ||
| 317 | |||
| 318 | static void spi_qup_dma_terminate(struct spi_master *master, | ||
| 319 | struct spi_transfer *xfer) | ||
| 320 | { | ||
| 321 | if (xfer->tx_buf) | ||
| 322 | dmaengine_terminate_all(master->dma_tx); | ||
| 323 | if (xfer->rx_buf) | ||
| 324 | dmaengine_terminate_all(master->dma_rx); | ||
| 325 | } | ||
| 326 | |||
| 327 | static int spi_qup_do_dma(struct spi_master *master, struct spi_transfer *xfer) | ||
| 328 | { | ||
| 329 | dma_async_tx_callback rx_done = NULL, tx_done = NULL; | ||
| 330 | int ret; | ||
| 331 | |||
| 332 | if (xfer->rx_buf) | ||
| 333 | rx_done = spi_qup_dma_done; | ||
| 334 | else if (xfer->tx_buf) | ||
| 335 | tx_done = spi_qup_dma_done; | ||
| 336 | |||
| 337 | if (xfer->rx_buf) { | ||
| 338 | ret = spi_qup_prep_sg(master, xfer, DMA_DEV_TO_MEM, rx_done); | ||
| 339 | if (ret) | ||
| 340 | return ret; | ||
| 341 | |||
| 342 | dma_async_issue_pending(master->dma_rx); | ||
| 343 | } | ||
| 344 | |||
| 345 | if (xfer->tx_buf) { | ||
| 346 | ret = spi_qup_prep_sg(master, xfer, DMA_MEM_TO_DEV, tx_done); | ||
| 347 | if (ret) | ||
| 348 | return ret; | ||
| 349 | |||
| 350 | dma_async_issue_pending(master->dma_tx); | ||
| 351 | } | ||
| 352 | |||
| 353 | return 0; | ||
| 354 | } | ||
| 355 | |||
| 356 | static int spi_qup_do_pio(struct spi_master *master, struct spi_transfer *xfer) | ||
| 357 | { | ||
| 358 | struct spi_qup *qup = spi_master_get_devdata(master); | ||
| 359 | int ret; | ||
| 360 | |||
| 361 | ret = spi_qup_set_state(qup, QUP_STATE_RUN); | ||
| 362 | if (ret) { | ||
| 363 | dev_warn(qup->dev, "cannot set RUN state\n"); | ||
| 364 | return ret; | ||
