diff mbox series

drm/mcde: Retry DSI read/write transactions

Message ID 20200730081306.34783-1-linus.walleij@linaro.org
State New
Headers show
Series drm/mcde: Retry DSI read/write transactions | expand

Commit Message

Linus Walleij July 30, 2020, 8:13 a.m. UTC
The vendor driver makes a few retries on read DSI
transactions, something that is needed especially in
case of read (such as reading the panel MTP ID) while
the panel is running in video mode. This happens on
the Samsung s6e63m0 panel on the Golden device.

Retry reads and writes alike two times.

Cc: Stephan Gerhold <stephan@gerhold.net>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

---
 drivers/gpu/drm/mcde/mcde_dsi.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

-- 
2.26.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Comments

Stephan Gerhold July 30, 2020, 9:25 a.m. UTC | #1
On Thu, Jul 30, 2020 at 10:13:06AM +0200, Linus Walleij wrote:
> The vendor driver makes a few retries on read DSI

> transactions, something that is needed especially in

> case of read (such as reading the panel MTP ID) while

> the panel is running in video mode. This happens on

> the Samsung s6e63m0 panel on the Golden device.

> 


So this fixes reads from the panel for samsung-golden?

> Retry reads and writes alike two times.

> 

> Cc: Stephan Gerhold <stephan@gerhold.net>

> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

> ---

>  drivers/gpu/drm/mcde/mcde_dsi.c | 21 +++++++++++++++++++--

>  1 file changed, 19 insertions(+), 2 deletions(-)

> 

> diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c

> index 337c4c5e3947..76fecd7ab658 100644

> --- a/drivers/gpu/drm/mcde/mcde_dsi.c

> +++ b/drivers/gpu/drm/mcde/mcde_dsi.c

> @@ -207,8 +207,8 @@ static int mcde_dsi_host_detach(struct mipi_dsi_host *host,

>  	 (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \

>  	 (type == MIPI_DSI_DCS_READ))

>  

> -static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host,

> -				      const struct mipi_dsi_msg *msg)

> +static ssize_t mcde_dsi_host_transfer_commit(struct mipi_dsi_host *host,

> +					     const struct mipi_dsi_msg *msg)

>  {

>  	struct mcde_dsi *d = host_to_mcde_dsi(host);

>  	const u32 loop_delay_us = 10; /* us */

> @@ -353,6 +353,23 @@ static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host,

>  	return ret;

>  }

>  

> +static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host,

> +				      const struct mipi_dsi_msg *msg)

> +{

> +	struct mcde_dsi *d = host_to_mcde_dsi(host);

> +	int retries = 2;

> +	ssize_t ret;

> +

> +	while (retries--) {

> +		ret = mcde_dsi_host_transfer_commit(host, msg);

> +		if (ret >= 0)

> +			return ret;

> +	}


I wonder if it would be better to do this inside
mcde_dsi_host_transfer_commit() - it seems like the vendor driver only
retries triggering the command, i.e.

	writel(~0, d->regs + DSI_DIRECT_CMD_STS_CLR);
	writel(~0, d->regs + DSI_CMD_MODE_STS_CLR);
	/* Send command */
	writel(1, d->regs + DSI_DIRECT_CMD_SEND);

and does not write all the registers again.

> +

> +	dev_err(d->dev, "gave up transfer after retrying\n");

> +	return ret;

> +}

> +

>  static const struct mipi_dsi_host_ops mcde_dsi_host_ops = {

>  	.attach = mcde_dsi_host_attach,

>  	.detach = mcde_dsi_host_detach,

> -- 

> 2.26.2

> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox series

Patch

diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c
index 337c4c5e3947..76fecd7ab658 100644
--- a/drivers/gpu/drm/mcde/mcde_dsi.c
+++ b/drivers/gpu/drm/mcde/mcde_dsi.c
@@ -207,8 +207,8 @@  static int mcde_dsi_host_detach(struct mipi_dsi_host *host,
 	 (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
 	 (type == MIPI_DSI_DCS_READ))
 
-static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host,
-				      const struct mipi_dsi_msg *msg)
+static ssize_t mcde_dsi_host_transfer_commit(struct mipi_dsi_host *host,
+					     const struct mipi_dsi_msg *msg)
 {
 	struct mcde_dsi *d = host_to_mcde_dsi(host);
 	const u32 loop_delay_us = 10; /* us */
@@ -353,6 +353,23 @@  static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host,
 	return ret;
 }
 
+static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host,
+				      const struct mipi_dsi_msg *msg)
+{
+	struct mcde_dsi *d = host_to_mcde_dsi(host);
+	int retries = 2;
+	ssize_t ret;
+
+	while (retries--) {
+		ret = mcde_dsi_host_transfer_commit(host, msg);
+		if (ret >= 0)
+			return ret;
+	}
+
+	dev_err(d->dev, "gave up transfer after retrying\n");
+	return ret;
+}
+
 static const struct mipi_dsi_host_ops mcde_dsi_host_ops = {
 	.attach = mcde_dsi_host_attach,
 	.detach = mcde_dsi_host_detach,