There is sometimes a need to be able to read from the other end for instance to identify panels. Signed-off-by: Richard Röjfors <richard@xxxxxxxxxxxxx> --- drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 50 ++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c index 662b6cb5d3f0..88403954f3c4 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c @@ -719,6 +719,53 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, return dw_mipi_dsi_gen_pkt_hdr_write(dsi, hdr_val); } +static int dw_mipi_dsi_dcs_read(struct dw_mipi_dsi *dsi, + const struct mipi_dsi_msg *msg) +{ + int ret; + int bytes_read = 0; + u32 status; + + ret = dw_mipi_dsi_dcs_short_write(dsi, msg); + if (ret < 0) { + DRM_DEV_ERROR(dsi->dev, "failed to issue read command\n"); + return ret; + } + + /* Loop and empty the RX FIFO */ + do { + u32 val; + + /* Wait for data to reach the fifo or command termination */ + ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, + val, ((val & GEN_PLD_R_EMPTY)) == 0 || + ((val & GEN_RD_CMD_BUSY) == 0), + 1000, CMD_PKT_STATUS_TIMEOUT_US); + if (ret < 0) { + DRM_DEV_ERROR(dsi->dev, + "failed to read payload from FIFO\n"); + return ret; + } + + status = dsi_read(dsi, DSI_CMD_PKT_STATUS); + + if ((status & GEN_PLD_R_EMPTY) == 0) { + int i; + u8 *rx_buf = msg->rx_buf; + + val = dsi_read(dsi, DSI_GEN_PLD_DATA); + + for (i = 0; i < sizeof(u32) && bytes_read < msg->rx_len; + i++) { + rx_buf[bytes_read++] = val & 0xff; + val >>= 8; + } + } + } while ((status & GEN_PLD_R_EMPTY) == 0); + + return bytes_read; +} + static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, const struct mipi_dsi_msg *msg) { @@ -736,6 +783,9 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, case MIPI_DSI_DCS_LONG_WRITE: ret = dw_mipi_dsi_dcs_long_write(dsi, msg); break; + case MIPI_DSI_DCS_READ: + ret = dw_mipi_dsi_dcs_read(dsi, msg); + break; default: DRM_DEV_ERROR(dsi->dev, "unsupported message type 0x%02x\n", msg->type); -- 2.19.1 _______________________________________________ Linux-rockchip mailing list Linux-rockchip@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/linux-rockchip