drm/rockchip: dw-mipi-dsi: Support MIPI_DSI_DCS_READ

Message ID 20181205130243.5810-1-richard@puffinpack.se
State New
Headers show
Series
  • drm/rockchip: dw-mipi-dsi: Support MIPI_DSI_DCS_READ
Related show

Commit Message

Richard Röjfors Dec. 5, 2018, 1:02 p.m.
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@puffinpack.se>
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 50 ++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

Comments

Heiko Stuebner Dec. 7, 2018, 2:58 p.m. | #1
Hi Richard,

Am Mittwoch, 5. Dezember 2018, 14:02:43 CET schrieb Richard Röjfors:
> 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@puffinpack.se>

The Rockchip dsi driver got converted to use the generic dw-mipi-dsi
bridge - will be part of 4.21. And there the different methods seem to
be implemented already.

So this patch does not seem to be relevant anymore. Please wait for 4.21-rc1
or check linux-next, if there is still functionality missing.

Also as a general note, please check scripts/get_maintainer.pl when
sending patches, as that should have also listed the dri-devel list, which
missing here.


Thanks
Heiko
Richard Röjfors Dec. 11, 2018, 1:34 p.m. | #2
Hi Heiko,

On Fri, Dec 7, 2018 at 3:58 PM Heiko Stuebner <heiko@sntech.de> wrote:
>
> The Rockchip dsi driver got converted to use the generic dw-mipi-dsi
> bridge - will be part of 4.21. And there the different methods seem to
> be implemented already.
>
> So this patch does not seem to be relevant anymore. Please wait for 4.21-rc1
> or check linux-next, if there is still functionality missing.

Thanks, I didn't know about the conversion, but it makes sense!

BR
--Richard

Patch

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);