mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-09-25 15:51:27 +02:00
spi: rockchip_sfc: Using read_poll
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>
This commit is contained in:
parent
51f29239b7
commit
24c627b57a
@ -285,33 +285,38 @@ err_init:
|
|||||||
return ret;
|
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 ret = 0;
|
||||||
int level;
|
u32 status;
|
||||||
|
|
||||||
if (wr)
|
ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
|
||||||
level = (fsr & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
|
status & SFC_FSR_TXLV_MASK,
|
||||||
else
|
timeout_us);
|
||||||
level = (fsr & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
|
if (ret) {
|
||||||
|
dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n");
|
||||||
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int wr, u32 timeout)
|
|
||||||
{
|
|
||||||
unsigned long tbase = get_timer(0);
|
|
||||||
int level;
|
|
||||||
|
|
||||||
while (!(level = rockchip_sfc_get_fifo_level(sfc, wr))) {
|
|
||||||
if (get_timer(tbase) > timeout) {
|
|
||||||
debug("%s fifo timeout\n", wr ? "write" : "read");
|
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
udelay(1);
|
|
||||||
|
return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
u32 status;
|
||||||
|
|
||||||
|
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)
|
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;
|
dwords = len >> 2;
|
||||||
while (dwords) {
|
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)
|
if (tx_level < 0)
|
||||||
return tx_level;
|
return tx_level;
|
||||||
write_words = min_t(u32, tx_level, dwords);
|
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 */
|
/* write the rest non word aligned bytes */
|
||||||
if (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)
|
if (tx_level < 0)
|
||||||
return tx_level;
|
return tx_level;
|
||||||
memcpy(&tmp, buf, bytes);
|
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 */
|
/* word aligned access only */
|
||||||
dwords = len >> 2;
|
dwords = len >> 2;
|
||||||
while (dwords) {
|
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)
|
if (rx_level < 0)
|
||||||
return rx_level;
|
return rx_level;
|
||||||
read_words = min_t(u32, rx_level, dwords);
|
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 */
|
/* read the rest non word aligned bytes */
|
||||||
if (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)
|
if (rx_level < 0)
|
||||||
return rx_level;
|
return rx_level;
|
||||||
tmp = readl(sfc->regbase + SFC_DATA);
|
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)
|
static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)
|
||||||
{
|
{
|
||||||
unsigned long tbase = get_timer(0);
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u32 timeout = timeout_us;
|
u32 status;
|
||||||
|
|
||||||
while (readl(sfc->regbase + SFC_SR) & SFC_SR_IS_BUSY) {
|
ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
|
||||||
if (get_timer(tbase) > timeout) {
|
!(status & SFC_SR_IS_BUSY),
|
||||||
printf("wait sfc idle timeout\n");
|
timeout_us);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(sfc->dev, "wait sfc idle timeout\n");
|
||||||
rockchip_sfc_reset(sfc);
|
rockchip_sfc_reset(sfc);
|
||||||
|
|
||||||
return -ETIMEDOUT;
|
ret = -EIO;
|
||||||
}
|
|
||||||
|
|
||||||
udelay(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user