The burst length can be adjusted according to the transmission
length to improve the transmission rate
Signed-off-by: Jon Lin <[email protected]>
---
drivers/spi/spi-rockchip.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 9b8a5e1233c0..63593a5b87fa 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -384,6 +384,19 @@ static void rockchip_spi_dma_txcb(void *data)
spi_finalize_current_transfer(ctlr);
}
+static u32 rockchip_spi_calc_burst_size(u32 data_len)
+{
+ u32 i;
+
+ /* burst size: 1, 2, 4, 8 */
+ for (i = 1; i < 8; i <<= 1) {
+ if (data_len & i)
+ break;
+ }
+
+ return i;
+}
+
static int rockchip_spi_prepare_dma(struct rockchip_spi *rs,
struct spi_controller *ctlr, struct spi_transfer *xfer)
{
@@ -397,7 +410,8 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs,
.direction = DMA_DEV_TO_MEM,
.src_addr = rs->dma_addr_rx,
.src_addr_width = rs->n_bytes,
- .src_maxburst = 1,
+ .src_maxburst = rockchip_spi_calc_burst_size(xfer->len /
+ rs->n_bytes),
};
dmaengine_slave_config(ctlr->dma_rx, &rxconf);
@@ -525,7 +539,8 @@ static void rockchip_spi_config(struct rockchip_spi *rs,
writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
writel_relaxed(rs->fifo_len / 2, rs->regs + ROCKCHIP_SPI_DMATDLR);
- writel_relaxed(0, rs->regs + ROCKCHIP_SPI_DMARDLR);
+ writel_relaxed(rockchip_spi_calc_burst_size(xfer->len / rs->n_bytes) - 1,
+ rs->regs + ROCKCHIP_SPI_DMARDLR);
writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR);
/* the hardware only supports an even clock divisor, so
--
2.17.1
The RXFLR is possible larger than rx_left in Rockchip SPI, fix it.
Signed-off-by: Jon Lin <[email protected]>
---
drivers/spi/spi-rockchip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index a451dacab5cf..1f5e613b67d9 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -291,7 +291,7 @@ static void rockchip_spi_pio_writer(struct rockchip_spi *rs)
static void rockchip_spi_pio_reader(struct rockchip_spi *rs)
{
u32 words = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
- u32 rx_left = rs->rx_left - words;
+ u32 rx_left = rs->rx_left > words ? rs->rx_left - words : 0;
/* the hardware doesn't allow us to change fifo threshold
* level while spi is enabled, so instead make sure to leave
--
2.17.1
The FIFO depth of SPI V2 is 64 instead of 32, add support for it.
Signed-off-by: Jon Lin <[email protected]>
---
drivers/spi/spi-rockchip.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 63593a5b87fa..a451dacab5cf 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -39,8 +39,9 @@
#define ROCKCHIP_SPI_RISR 0x0034
#define ROCKCHIP_SPI_ICR 0x0038
#define ROCKCHIP_SPI_DMACR 0x003c
-#define ROCKCHIP_SPI_DMATDLR 0x0040
-#define ROCKCHIP_SPI_DMARDLR 0x0044
+#define ROCKCHIP_SPI_DMATDLR 0x0040
+#define ROCKCHIP_SPI_DMARDLR 0x0044
+#define ROCKCHIP_SPI_VERSION 0x0048
#define ROCKCHIP_SPI_TXDR 0x0400
#define ROCKCHIP_SPI_RXDR 0x0800
@@ -156,6 +157,8 @@
#define ROCKCHIP_SPI_MAX_TRANLEN 0xffff
#define ROCKCHIP_SPI_MAX_CS_NUM 2
+#define ROCKCHIP_SPI_VER2_TYPE1 0x05EC0002
+#define ROCKCHIP_SPI_VER2_TYPE2 0x00110002
struct rockchip_spi {
struct device *dev;
@@ -206,17 +209,17 @@ static inline void wait_for_idle(struct rockchip_spi *rs)
static u32 get_fifo_len(struct rockchip_spi *rs)
{
- u32 fifo;
+ u32 ver;
- for (fifo = 2; fifo < 32; fifo++) {
- writel_relaxed(fifo, rs->regs + ROCKCHIP_SPI_TXFTLR);
- if (fifo != readl_relaxed(rs->regs + ROCKCHIP_SPI_TXFTLR))
- break;
- }
-
- writel_relaxed(0, rs->regs + ROCKCHIP_SPI_TXFTLR);
+ ver = readl_relaxed(rs->regs + ROCKCHIP_SPI_VERSION);
- return (fifo == 31) ? 0 : fifo;
+ switch (ver) {
+ case ROCKCHIP_SPI_VER2_TYPE1:
+ case ROCKCHIP_SPI_VER2_TYPE2:
+ return 64;
+ default:
+ return 32;
+ }
}
static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
--
2.17.1
Hi Jon,
Am Mittwoch, 22. Juli 2020, 08:52:57 CEST schrieb Jon Lin:
> The RXFLR is possible larger than rx_left in Rockchip SPI, fix it.
>
> Signed-off-by: Jon Lin <[email protected]>
> ---
> drivers/spi/spi-rockchip.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
> index a451dacab5cf..1f5e613b67d9 100644
> --- a/drivers/spi/spi-rockchip.c
> +++ b/drivers/spi/spi-rockchip.c
> @@ -291,7 +291,7 @@ static void rockchip_spi_pio_writer(struct rockchip_spi *rs)
> static void rockchip_spi_pio_reader(struct rockchip_spi *rs)
> {
> u32 words = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
> - u32 rx_left = rs->rx_left - words;
> + u32 rx_left = rs->rx_left > words ? rs->rx_left - words : 0;
I guess for future readability of the code braces might be nice, like
u32 rx_left = (rs->rx_left > words) ? rs->rx_left - words : 0;
But I stumbled onto (and fixed similarly) that issue yesterday as well, so
Reviewed-by: Heiko Stuebner <[email protected]>
Heiko