* [PATCH v3 1/2] spi: rockchip_sfc: Implement set_speed logic
@ 2021-09-17 13:14 Jon Lin
2021-09-17 13:14 ` [PATCH v3 2/2] spi: rockchip_sfc: Using read_poll Jon Lin
2021-10-09 15:04 ` [PATCH v3 1/2] spi: rockchip_sfc: Implement set_speed logic Kever Yang
0 siblings, 2 replies; 4+ messages in thread
From: Jon Lin @ 2021-09-17 13:14 UTC (permalink / raw)
To: jagan; +Cc: u-boot, macromorgan, jon.lin, kever.yang, sjg
Set clock related processing into set_speed logic. And Optimize
printing format.
Tested-by: Chris Morgan <macromorgan@hotmail.com>
Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
---
Changes in v3:
- Remove useless headfile
- Fix misspelling
drivers/spi/rockchip_sfc.c | 82 ++++++++++++++++++--------------------
1 file changed, 39 insertions(+), 43 deletions(-)
diff --git a/drivers/spi/rockchip_sfc.c b/drivers/spi/rockchip_sfc.c
index 4e2b861f22..94222df5ce 100644
--- a/drivers/spi/rockchip_sfc.c
+++ b/drivers/spi/rockchip_sfc.c
@@ -116,6 +116,7 @@
/* Master trigger */
#define SFC_DMA_TRIGGER 0x80
+#define SFC_DMA_TRIGGER_START 1
/* Src or Dst addr for master */
#define SFC_DMA_ADDR 0x84
@@ -163,14 +164,12 @@
#define SFC_DMA_TRANS_THRETHOLD (0x40)
/* Maximum clock values from datasheet suggest keeping clock value under
- * 150MHz. No minimum or average value is suggested, but the U-boot BSP driver
- * has a minimum of 10MHz and a default of 80MHz which seems reasonable.
+ * 150MHz. No minimum or average value is suggested.
*/
-#define SFC_MIN_SPEED_HZ (10 * 1000 * 1000)
-#define SFC_DEFAULT_SPEED_HZ (80 * 1000 * 1000)
-#define SFC_MAX_SPEED_HZ (150 * 1000 * 1000)
+#define SFC_MAX_SPEED (150 * 1000 * 1000)
struct rockchip_sfc {
+ struct udevice *dev;
void __iomem *regbase;
struct clk hclk;
struct clk clk;
@@ -197,8 +196,6 @@ static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
/* Still need to clear the masked interrupt from RISR */
writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
- debug("reset\n");
-
return err;
}
@@ -261,15 +258,11 @@ static int rockchip_sfc_probe(struct udevice *bus)
#if CONFIG_IS_ENABLED(CLK)
ret = clk_enable(&sfc->hclk);
if (ret)
- debug("Enable ahb clock fail %s: %d\n", bus->name, ret);
+ dev_dbg(sfc->dev, "sfc Enable ahb clock fail %s: %d\n", bus->name, ret);
ret = clk_enable(&sfc->clk);
if (ret)
- debug("Enable clock fail for %s: %d\n", bus->name, ret);
-
- ret = clk_set_rate(&sfc->clk, SFC_DEFAULT_SPEED_HZ);
- if (ret)
- debug("Could not set sfc clock for %s: %d\n", bus->name, ret);
+ dev_dbg(sfc->dev, "sfc Enable clock fail for %s: %d\n", bus->name, ret);
#endif
ret = rockchip_sfc_init(sfc);
@@ -278,7 +271,8 @@ static int rockchip_sfc_probe(struct udevice *bus)
sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
sfc->version = rockchip_sfc_get_version(sfc);
- sfc->speed = SFC_DEFAULT_SPEED_HZ;
+ sfc->max_freq = SFC_MAX_SPEED;
+ sfc->dev = bus;
return 0;
@@ -411,11 +405,11 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE;
cmd |= plat->cs << SFC_CMD_CS_SHIFT;
- debug("addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
- op->addr.nbytes, op->addr.buswidth,
- op->dummy.nbytes, op->dummy.buswidth);
- debug("ctrl=%x cmd=%x addr=%llx len=%x\n",
- ctrl, cmd, op->addr.val, len);
+ dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
+ op->addr.nbytes, op->addr.buswidth,
+ op->dummy.nbytes, op->dummy.buswidth);
+ dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n",
+ ctrl, cmd, op->addr.val, len);
writel(ctrl, sfc->regbase + SFC_CTRL);
writel(cmd, sfc->regbase + SFC_CMD);
@@ -492,7 +486,7 @@ static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t d
{
writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR);
- writel(0x1, sfc->regbase + SFC_DMA_TRIGGER);
+ writel(SFC_DMA_TRIGGER_START, sfc->regbase + SFC_DMA_TRIGGER);
return len;
}
@@ -500,7 +494,7 @@ static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t d
static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc,
const struct spi_mem_op *op, u32 len)
{
- debug("xfer_poll len=%x\n", len);
+ dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n", len);
if (op->data.dir == SPI_MEM_DATA_OUT)
return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len);
@@ -516,7 +510,7 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
void *dma_buf;
int ret;
- debug("xfer_dma len=%x\n", len);
+ dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);
if (op->data.dir == SPI_MEM_DATA_OUT) {
dma_buf = (void *)op->data.buf.out;
@@ -564,33 +558,16 @@ static int rockchip_sfc_exec_op(struct spi_slave *mem,
u32 len = min_t(u32, op->data.nbytes, sfc->max_iosize);
int ret;
-#if CONFIG_IS_ENABLED(CLK)
- if (unlikely(mem->max_hz != sfc->speed)) {
- ret = clk_set_rate(&sfc->clk, clamp(mem->max_hz, (uint)SFC_MIN_SPEED_HZ,
- (uint)SFC_MAX_SPEED_HZ));
- if (ret < 0) {
- printf("set_freq=%dHz fail, check if it's the cru support level\n",
- mem->max_hz);
- return ret;
- }
-
- sfc->max_freq = mem->max_hz;
- sfc->speed = mem->max_hz;
- debug("set_freq=%dHz real_freq=%dHz\n", sfc->max_freq, sfc->speed);
- }
-#endif
-
rockchip_sfc_adjust_op_work((struct spi_mem_op *)op);
-
rockchip_sfc_xfer_setup(sfc, mem, op, len);
if (len) {
- if (likely(sfc->use_dma) && !(len & 0x3) && len >= SFC_DMA_TRANS_THRETHOLD)
+ if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD)
ret = rockchip_sfc_xfer_data_dma(sfc, op, len);
else
ret = rockchip_sfc_xfer_data_poll(sfc, op, len);
if (ret != len) {
- printf("xfer data failed ret %d dir %d\n", ret, op->data.dir);
+ dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir);
return -EIO;
}
@@ -604,13 +581,32 @@ static int rockchip_sfc_adjust_op_size(struct spi_slave *mem, struct spi_mem_op
struct rockchip_sfc *sfc = dev_get_plat(mem->dev->parent);
op->data.nbytes = min(op->data.nbytes, sfc->max_iosize);
+
return 0;
}
static int rockchip_sfc_set_speed(struct udevice *bus, uint speed)
{
- /* We set up speed later for each transmission.
- */
+ struct rockchip_sfc *sfc = dev_get_plat(bus);
+
+ if (speed > sfc->max_freq)
+ speed = sfc->max_freq;
+
+ if (speed == sfc->speed)
+ return 0;
+
+#if CONFIG_IS_ENABLED(CLK)
+ int ret = clk_set_rate(&sfc->clk, speed);
+
+ if (ret < 0) {
+ dev_err(sfc->dev, "set_freq=%dHz fail, check if it's the cru support level\n",
+ speed);
+ return ret;
+ }
+ sfc->speed = speed;
+#else
+ dev_dbg(sfc->dev, "sfc failed, CLK not support\n");
+#endif
return 0;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v3 2/2] spi: rockchip_sfc: Using read_poll
2021-09-17 13:14 [PATCH v3 1/2] spi: rockchip_sfc: Implement set_speed logic Jon Lin
@ 2021-09-17 13:14 ` Jon Lin
2021-10-09 15:04 ` Kever Yang
2021-10-09 15:04 ` [PATCH v3 1/2] spi: rockchip_sfc: Implement set_speed logic Kever Yang
1 sibling, 1 reply; 4+ messages in thread
From: Jon Lin @ 2021-09-17 13:14 UTC (permalink / raw)
To: jagan; +Cc: u-boot, macromorgan, jon.lin, kever.yang, sjg
Using read_poll logic.
Tested-by: Chris Morgan <macromorgan@hotmail.com>
Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
---
(no changes since v2)
Changes in v2:
- Fix assigned but never used return error codes
drivers/spi/rockchip_sfc.c | 67 ++++++++++++++++++++------------------
1 file changed, 35 insertions(+), 32 deletions(-)
diff --git a/drivers/spi/rockchip_sfc.c b/drivers/spi/rockchip_sfc.c
index 94222df5ce..e098addddc 100644
--- a/drivers/spi/rockchip_sfc.c
+++ b/drivers/spi/rockchip_sfc.c
@@ -285,33 +285,38 @@ err_init:
return ret;
}
-static inline int rockchip_sfc_get_fifo_level(struct rockchip_sfc *sfc, int wr)
+static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
{
- u32 fsr = readl(sfc->regbase + SFC_FSR);
- int level;
+ int ret = 0;
+ u32 status;
- if (wr)
- level = (fsr & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
- else
- level = (fsr & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
+ ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
+ status & SFC_FSR_TXLV_MASK,
+ timeout_us);
+ if (ret) {
+ dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n");
+
+ return -ETIMEDOUT;
+ }
- return level;
+ return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
}
-static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int wr, u32 timeout)
+static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
{
- unsigned long tbase = get_timer(0);
- int level;
+ int ret = 0;
+ u32 status;
- while (!(level = rockchip_sfc_get_fifo_level(sfc, wr))) {
- if (get_timer(tbase) > timeout) {
- debug("%s fifo timeout\n", wr ? "write" : "read");
- return -ETIMEDOUT;
- }
- udelay(1);
+ ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
+ status & SFC_FSR_RXLV_MASK,
+ timeout_us);
+ if (ret) {
+ dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n");
+
+ return -ETIMEDOUT;
}
- return level;
+ return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
}
static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op)
@@ -429,7 +434,7 @@ static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int
dwords = len >> 2;
while (dwords) {
- tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000);
+ tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
if (tx_level < 0)
return tx_level;
write_words = min_t(u32, tx_level, dwords);
@@ -440,7 +445,7 @@ static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int
/* write the rest non word aligned bytes */
if (bytes) {
- tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000);
+ tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
if (tx_level < 0)
return tx_level;
memcpy(&tmp, buf, bytes);
@@ -461,7 +466,7 @@ static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
/* word aligned access only */
dwords = len >> 2;
while (dwords) {
- rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000);
+ rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
if (rx_level < 0)
return rx_level;
read_words = min_t(u32, rx_level, dwords);
@@ -472,7 +477,7 @@ static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
/* read the rest non word aligned bytes */
if (bytes) {
- rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000);
+ rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
if (rx_level < 0)
return rx_level;
tmp = readl(sfc->regbase + SFC_DATA);
@@ -533,19 +538,17 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)
{
- unsigned long tbase = get_timer(0);
int ret = 0;
- u32 timeout = timeout_us;
-
- while (readl(sfc->regbase + SFC_SR) & SFC_SR_IS_BUSY) {
- if (get_timer(tbase) > timeout) {
- printf("wait sfc idle timeout\n");
- rockchip_sfc_reset(sfc);
+ u32 status;
- return -ETIMEDOUT;
- }
+ ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
+ !(status & SFC_SR_IS_BUSY),
+ timeout_us);
+ if (ret) {
+ dev_err(sfc->dev, "wait sfc idle timeout\n");
+ rockchip_sfc_reset(sfc);
- udelay(1);
+ ret = -EIO;
}
return ret;
--
2.17.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v3 1/2] spi: rockchip_sfc: Implement set_speed logic
2021-09-17 13:14 [PATCH v3 1/2] spi: rockchip_sfc: Implement set_speed logic Jon Lin
2021-09-17 13:14 ` [PATCH v3 2/2] spi: rockchip_sfc: Using read_poll Jon Lin
@ 2021-10-09 15:04 ` Kever Yang
1 sibling, 0 replies; 4+ messages in thread
From: Kever Yang @ 2021-10-09 15:04 UTC (permalink / raw)
To: Jon Lin, jagan; +Cc: u-boot, macromorgan, sjg
On 2021/9/17 下午9:14, Jon Lin wrote:
> Set clock related processing into set_speed logic. And Optimize
> printing format.
>
> Tested-by: Chris Morgan <macromorgan@hotmail.com>
> Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Thanks,
- Kever
> ---
>
> Changes in v3:
> - Remove useless headfile
> - Fix misspelling
>
> drivers/spi/rockchip_sfc.c | 82 ++++++++++++++++++--------------------
> 1 file changed, 39 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/spi/rockchip_sfc.c b/drivers/spi/rockchip_sfc.c
> index 4e2b861f22..94222df5ce 100644
> --- a/drivers/spi/rockchip_sfc.c
> +++ b/drivers/spi/rockchip_sfc.c
> @@ -116,6 +116,7 @@
>
> /* Master trigger */
> #define SFC_DMA_TRIGGER 0x80
> +#define SFC_DMA_TRIGGER_START 1
>
> /* Src or Dst addr for master */
> #define SFC_DMA_ADDR 0x84
> @@ -163,14 +164,12 @@
> #define SFC_DMA_TRANS_THRETHOLD (0x40)
>
> /* Maximum clock values from datasheet suggest keeping clock value under
> - * 150MHz. No minimum or average value is suggested, but the U-boot BSP driver
> - * has a minimum of 10MHz and a default of 80MHz which seems reasonable.
> + * 150MHz. No minimum or average value is suggested.
> */
> -#define SFC_MIN_SPEED_HZ (10 * 1000 * 1000)
> -#define SFC_DEFAULT_SPEED_HZ (80 * 1000 * 1000)
> -#define SFC_MAX_SPEED_HZ (150 * 1000 * 1000)
> +#define SFC_MAX_SPEED (150 * 1000 * 1000)
>
> struct rockchip_sfc {
> + struct udevice *dev;
> void __iomem *regbase;
> struct clk hclk;
> struct clk clk;
> @@ -197,8 +196,6 @@ static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
> /* Still need to clear the masked interrupt from RISR */
> writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
>
> - debug("reset\n");
> -
> return err;
> }
>
> @@ -261,15 +258,11 @@ static int rockchip_sfc_probe(struct udevice *bus)
> #if CONFIG_IS_ENABLED(CLK)
> ret = clk_enable(&sfc->hclk);
> if (ret)
> - debug("Enable ahb clock fail %s: %d\n", bus->name, ret);
> + dev_dbg(sfc->dev, "sfc Enable ahb clock fail %s: %d\n", bus->name, ret);
>
> ret = clk_enable(&sfc->clk);
> if (ret)
> - debug("Enable clock fail for %s: %d\n", bus->name, ret);
> -
> - ret = clk_set_rate(&sfc->clk, SFC_DEFAULT_SPEED_HZ);
> - if (ret)
> - debug("Could not set sfc clock for %s: %d\n", bus->name, ret);
> + dev_dbg(sfc->dev, "sfc Enable clock fail for %s: %d\n", bus->name, ret);
> #endif
>
> ret = rockchip_sfc_init(sfc);
> @@ -278,7 +271,8 @@ static int rockchip_sfc_probe(struct udevice *bus)
>
> sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
> sfc->version = rockchip_sfc_get_version(sfc);
> - sfc->speed = SFC_DEFAULT_SPEED_HZ;
> + sfc->max_freq = SFC_MAX_SPEED;
> + sfc->dev = bus;
>
> return 0;
>
> @@ -411,11 +405,11 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
> ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE;
> cmd |= plat->cs << SFC_CMD_CS_SHIFT;
>
> - debug("addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
> - op->addr.nbytes, op->addr.buswidth,
> - op->dummy.nbytes, op->dummy.buswidth);
> - debug("ctrl=%x cmd=%x addr=%llx len=%x\n",
> - ctrl, cmd, op->addr.val, len);
> + dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
> + op->addr.nbytes, op->addr.buswidth,
> + op->dummy.nbytes, op->dummy.buswidth);
> + dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n",
> + ctrl, cmd, op->addr.val, len);
>
> writel(ctrl, sfc->regbase + SFC_CTRL);
> writel(cmd, sfc->regbase + SFC_CMD);
> @@ -492,7 +486,7 @@ static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t d
> {
> writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
> writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR);
> - writel(0x1, sfc->regbase + SFC_DMA_TRIGGER);
> + writel(SFC_DMA_TRIGGER_START, sfc->regbase + SFC_DMA_TRIGGER);
>
> return len;
> }
> @@ -500,7 +494,7 @@ static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t d
> static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc,
> const struct spi_mem_op *op, u32 len)
> {
> - debug("xfer_poll len=%x\n", len);
> + dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n", len);
>
> if (op->data.dir == SPI_MEM_DATA_OUT)
> return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len);
> @@ -516,7 +510,7 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
> void *dma_buf;
> int ret;
>
> - debug("xfer_dma len=%x\n", len);
> + dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);
>
> if (op->data.dir == SPI_MEM_DATA_OUT) {
> dma_buf = (void *)op->data.buf.out;
> @@ -564,33 +558,16 @@ static int rockchip_sfc_exec_op(struct spi_slave *mem,
> u32 len = min_t(u32, op->data.nbytes, sfc->max_iosize);
> int ret;
>
> -#if CONFIG_IS_ENABLED(CLK)
> - if (unlikely(mem->max_hz != sfc->speed)) {
> - ret = clk_set_rate(&sfc->clk, clamp(mem->max_hz, (uint)SFC_MIN_SPEED_HZ,
> - (uint)SFC_MAX_SPEED_HZ));
> - if (ret < 0) {
> - printf("set_freq=%dHz fail, check if it's the cru support level\n",
> - mem->max_hz);
> - return ret;
> - }
> -
> - sfc->max_freq = mem->max_hz;
> - sfc->speed = mem->max_hz;
> - debug("set_freq=%dHz real_freq=%dHz\n", sfc->max_freq, sfc->speed);
> - }
> -#endif
> -
> rockchip_sfc_adjust_op_work((struct spi_mem_op *)op);
> -
> rockchip_sfc_xfer_setup(sfc, mem, op, len);
> if (len) {
> - if (likely(sfc->use_dma) && !(len & 0x3) && len >= SFC_DMA_TRANS_THRETHOLD)
> + if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD)
> ret = rockchip_sfc_xfer_data_dma(sfc, op, len);
> else
> ret = rockchip_sfc_xfer_data_poll(sfc, op, len);
>
> if (ret != len) {
> - printf("xfer data failed ret %d dir %d\n", ret, op->data.dir);
> + dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir);
>
> return -EIO;
> }
> @@ -604,13 +581,32 @@ static int rockchip_sfc_adjust_op_size(struct spi_slave *mem, struct spi_mem_op
> struct rockchip_sfc *sfc = dev_get_plat(mem->dev->parent);
>
> op->data.nbytes = min(op->data.nbytes, sfc->max_iosize);
> +
> return 0;
> }
>
> static int rockchip_sfc_set_speed(struct udevice *bus, uint speed)
> {
> - /* We set up speed later for each transmission.
> - */
> + struct rockchip_sfc *sfc = dev_get_plat(bus);
> +
> + if (speed > sfc->max_freq)
> + speed = sfc->max_freq;
> +
> + if (speed == sfc->speed)
> + return 0;
> +
> +#if CONFIG_IS_ENABLED(CLK)
> + int ret = clk_set_rate(&sfc->clk, speed);
> +
> + if (ret < 0) {
> + dev_err(sfc->dev, "set_freq=%dHz fail, check if it's the cru support level\n",
> + speed);
> + return ret;
> + }
> + sfc->speed = speed;
> +#else
> + dev_dbg(sfc->dev, "sfc failed, CLK not support\n");
> +#endif
> return 0;
> }
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3 2/2] spi: rockchip_sfc: Using read_poll
2021-09-17 13:14 ` [PATCH v3 2/2] spi: rockchip_sfc: Using read_poll Jon Lin
@ 2021-10-09 15:04 ` Kever Yang
0 siblings, 0 replies; 4+ messages in thread
From: Kever Yang @ 2021-10-09 15:04 UTC (permalink / raw)
To: Jon Lin, jagan; +Cc: u-boot, macromorgan, sjg
On 2021/9/17 下午9:14, Jon Lin wrote:
> Using read_poll logic.
>
> Tested-by: Chris Morgan <macromorgan@hotmail.com>
> Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Thanks,
- Kever
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - Fix assigned but never used return error codes
>
> drivers/spi/rockchip_sfc.c | 67 ++++++++++++++++++++------------------
> 1 file changed, 35 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/spi/rockchip_sfc.c b/drivers/spi/rockchip_sfc.c
> index 94222df5ce..e098addddc 100644
> --- a/drivers/spi/rockchip_sfc.c
> +++ b/drivers/spi/rockchip_sfc.c
> @@ -285,33 +285,38 @@ err_init:
> return ret;
> }
>
> -static inline int rockchip_sfc_get_fifo_level(struct rockchip_sfc *sfc, int wr)
> +static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
> {
> - u32 fsr = readl(sfc->regbase + SFC_FSR);
> - int level;
> + int ret = 0;
> + u32 status;
>
> - if (wr)
> - level = (fsr & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
> - else
> - level = (fsr & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
> + ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
> + status & SFC_FSR_TXLV_MASK,
> + timeout_us);
> + if (ret) {
> + dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n");
> +
> + return -ETIMEDOUT;
> + }
>
> - return level;
> + return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
> }
>
> -static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int wr, u32 timeout)
> +static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
> {
> - unsigned long tbase = get_timer(0);
> - int level;
> + int ret = 0;
> + u32 status;
>
> - while (!(level = rockchip_sfc_get_fifo_level(sfc, wr))) {
> - if (get_timer(tbase) > timeout) {
> - debug("%s fifo timeout\n", wr ? "write" : "read");
> - return -ETIMEDOUT;
> - }
> - udelay(1);
> + ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
> + status & SFC_FSR_RXLV_MASK,
> + timeout_us);
> + if (ret) {
> + dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n");
> +
> + return -ETIMEDOUT;
> }
>
> - return level;
> + return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
> }
>
> static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op)
> @@ -429,7 +434,7 @@ static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int
>
> dwords = len >> 2;
> while (dwords) {
> - tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000);
> + tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
> if (tx_level < 0)
> return tx_level;
> write_words = min_t(u32, tx_level, dwords);
> @@ -440,7 +445,7 @@ static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int
>
> /* write the rest non word aligned bytes */
> if (bytes) {
> - tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000);
> + tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
> if (tx_level < 0)
> return tx_level;
> memcpy(&tmp, buf, bytes);
> @@ -461,7 +466,7 @@ static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
> /* word aligned access only */
> dwords = len >> 2;
> while (dwords) {
> - rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000);
> + rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
> if (rx_level < 0)
> return rx_level;
> read_words = min_t(u32, rx_level, dwords);
> @@ -472,7 +477,7 @@ static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
>
> /* read the rest non word aligned bytes */
> if (bytes) {
> - rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000);
> + rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
> if (rx_level < 0)
> return rx_level;
> tmp = readl(sfc->regbase + SFC_DATA);
> @@ -533,19 +538,17 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
>
> static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)
> {
> - unsigned long tbase = get_timer(0);
> int ret = 0;
> - u32 timeout = timeout_us;
> -
> - while (readl(sfc->regbase + SFC_SR) & SFC_SR_IS_BUSY) {
> - if (get_timer(tbase) > timeout) {
> - printf("wait sfc idle timeout\n");
> - rockchip_sfc_reset(sfc);
> + u32 status;
>
> - return -ETIMEDOUT;
> - }
> + ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
> + !(status & SFC_SR_IS_BUSY),
> + timeout_us);
> + if (ret) {
> + dev_err(sfc->dev, "wait sfc idle timeout\n");
> + rockchip_sfc_reset(sfc);
>
> - udelay(1);
> + ret = -EIO;
> }
>
> return ret;
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-10-09 15:05 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-17 13:14 [PATCH v3 1/2] spi: rockchip_sfc: Implement set_speed logic Jon Lin
2021-09-17 13:14 ` [PATCH v3 2/2] spi: rockchip_sfc: Using read_poll Jon Lin
2021-10-09 15:04 ` Kever Yang
2021-10-09 15:04 ` [PATCH v3 1/2] spi: rockchip_sfc: Implement set_speed logic Kever Yang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).