linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] drm/bridge: ti-sn65dsi86: Support EDID reading
@ 2020-10-29  1:11 Stephen Boyd
  2020-10-29  1:11 ` [PATCH 1/4] drm/bridge: ti-sn65dsi86: Combine register accesses in ti_sn_aux_transfer() Stephen Boyd
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Stephen Boyd @ 2020-10-29  1:11 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: linux-kernel, dri-devel, Douglas Anderson, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul

This patch series cleans up the DDC code a little bit so that
it is more efficient time wise and supports grabbing the EDID
of the eDP panel over the aux channel. I timed this on a board
I have on my desk and it takes about 20ms to grab the EDID out
of the panel and make sure it is valid.

The first two patches seem less controversial so I stuck them at
the beginning. The third patch does the EDID reading and caches
it so we don't have to keep grabbing it over and over again. And
finally the last patch updates the reply field so that short
reads and nacks over the channel are reflected properly instead of
treating them as some sort of error that can't be discerned.

I was thinking about making a patch to update the drm bridge connector
code to fallback to using the DDC of the bridge if it's available. Does
that code already exist? It would be nice to not even have to implement
the bridge func get_edid() function in the future if the DDC is
implemented and we're using the new bridge connector code.

Stephen Boyd (4):
  drm/bridge: ti-sn65dsi86: Combine register accesses in
    ti_sn_aux_transfer()
  drm/bridge: ti-sn65dsi86: Make polling a busy loop
  drm/bridge: ti-sn65dsi86: Read EDID blob over DDC
  drm/bridge: ti-sn65dsi86: Update reply on aux failures

 drivers/gpu/drm/bridge/ti-sn65dsi86.c | 101 ++++++++++++++++++--------
 1 file changed, 69 insertions(+), 32 deletions(-)

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec@siol.net>
Cc: Sean Paul <seanpaul@chromium.org>

base-commit: 3650b228f83adda7e5ee532e2b90429c03f7b9ec
-- 
Sent by a computer, using git, on the internet


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] drm/bridge: ti-sn65dsi86: Combine register accesses in ti_sn_aux_transfer()
  2020-10-29  1:11 [PATCH 0/4] drm/bridge: ti-sn65dsi86: Support EDID reading Stephen Boyd
@ 2020-10-29  1:11 ` Stephen Boyd
  2020-10-29 16:10   ` Doug Anderson
  2020-10-30  1:18   ` Stephen Boyd
  2020-10-29  1:11 ` [PATCH 2/4] drm/bridge: ti-sn65dsi86: Make polling a busy loop Stephen Boyd
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 11+ messages in thread
From: Stephen Boyd @ 2020-10-29  1:11 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: linux-kernel, dri-devel, Douglas Anderson, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul

These register reads and writes are sometimes directly next to each
other in the register address space. Let's use regmap bulk read/write
APIs to get the data with one transfer instead of multiple i2c
transfers. This helps cut down on the number of transfers in the case of
something like reading an EDID where we read in blocks of 16 bytes at a
time and the last for loop here is sending an i2c transfer for each of
those 16 bytes, one at a time. Ouch!

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec@siol.net>
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 drivers/gpu/drm/bridge/ti-sn65dsi86.c | 50 ++++++++++++---------------
 1 file changed, 22 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index ecdf9b01340f..87726b9e446f 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -17,6 +17,8 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 
+#include <asm/unaligned.h>
+
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
@@ -72,6 +74,7 @@
 #define SN_AUX_ADDR_19_16_REG			0x74
 #define SN_AUX_ADDR_15_8_REG			0x75
 #define SN_AUX_ADDR_7_0_REG			0x76
+#define SN_AUX_ADDR_MASK			GENMASK(19, 0)
 #define SN_AUX_LENGTH_REG			0x77
 #define SN_AUX_CMD_REG				0x78
 #define  AUX_CMD_SEND				BIT(0)
@@ -841,11 +844,13 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
 	struct ti_sn_bridge *pdata = aux_to_ti_sn_bridge(aux);
 	u32 request = msg->request & ~DP_AUX_I2C_MOT;
 	u32 request_val = AUX_CMD_REQ(msg->request);
-	u8 *buf = (u8 *)msg->buffer;
+	u8 *buf = msg->buffer;
+	unsigned int len = msg->size;
 	unsigned int val;
-	int ret, i;
+	int ret;
+	u8 addr_len[SN_AUX_LENGTH_REG + 1 - SN_AUX_ADDR_19_16_REG];
 
-	if (msg->size > SN_AUX_MAX_PAYLOAD_BYTES)
+	if (len > SN_AUX_MAX_PAYLOAD_BYTES)
 		return -EINVAL;
 
 	switch (request) {
@@ -859,19 +864,14 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
 		return -EINVAL;
 	}
 
-	regmap_write(pdata->regmap, SN_AUX_ADDR_19_16_REG,
-		     (msg->address >> 16) & 0xF);
-	regmap_write(pdata->regmap, SN_AUX_ADDR_15_8_REG,
-		     (msg->address >> 8) & 0xFF);
-	regmap_write(pdata->regmap, SN_AUX_ADDR_7_0_REG, msg->address & 0xFF);
-
-	regmap_write(pdata->regmap, SN_AUX_LENGTH_REG, msg->size);
+	BUILD_BUG_ON(sizeof(addr_len) != sizeof(__be32));
+	put_unaligned_be32((msg->address & SN_AUX_ADDR_MASK) << 8 | len,
+			   addr_len);
+	regmap_bulk_write(pdata->regmap, SN_AUX_ADDR_19_16_REG, addr_len,
+			  ARRAY_SIZE(addr_len));
 
-	if (request == DP_AUX_NATIVE_WRITE || request == DP_AUX_I2C_WRITE) {
-		for (i = 0; i < msg->size; i++)
-			regmap_write(pdata->regmap, SN_AUX_WDATA_REG(i),
-				     buf[i]);
-	}
+	if (request == DP_AUX_NATIVE_WRITE || request == DP_AUX_I2C_WRITE)
+		regmap_bulk_write(pdata->regmap, SN_AUX_WDATA_REG(0), buf, len);
 
 	/* Clear old status bits before start so we don't get confused */
 	regmap_write(pdata->regmap, SN_AUX_CMD_STATUS_REG,
@@ -895,21 +895,15 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
 		 || (val & AUX_IRQ_STATUS_AUX_SHORT))
 		return -ENXIO;
 
-	if (request == DP_AUX_NATIVE_WRITE || request == DP_AUX_I2C_WRITE)
-		return msg->size;
+	if (request == DP_AUX_NATIVE_WRITE || request == DP_AUX_I2C_WRITE ||
+	    len == 0)
+		return len;
 
-	for (i = 0; i < msg->size; i++) {
-		unsigned int val;
-		ret = regmap_read(pdata->regmap, SN_AUX_RDATA_REG(i),
-				  &val);
-		if (ret)
-			return ret;
-
-		WARN_ON(val & ~0xFF);
-		buf[i] = (u8)(val & 0xFF);
-	}
+	ret = regmap_bulk_read(pdata->regmap, SN_AUX_RDATA_REG(0), buf, len);
+	if (ret)
+		return ret;
 
-	return msg->size;
+	return len;
 }
 
 static int ti_sn_bridge_parse_dsi_host(struct ti_sn_bridge *pdata)
-- 
Sent by a computer, using git, on the internet


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/4] drm/bridge: ti-sn65dsi86: Make polling a busy loop
  2020-10-29  1:11 [PATCH 0/4] drm/bridge: ti-sn65dsi86: Support EDID reading Stephen Boyd
  2020-10-29  1:11 ` [PATCH 1/4] drm/bridge: ti-sn65dsi86: Combine register accesses in ti_sn_aux_transfer() Stephen Boyd
@ 2020-10-29  1:11 ` Stephen Boyd
  2020-10-29 16:11   ` Doug Anderson
  2020-10-29  1:11 ` [PATCH 3/4] drm/bridge: ti-sn65dsi86: Read EDID blob over DDC Stephen Boyd
  2020-10-29  1:11 ` [PATCH 4/4] drm/bridge: ti-sn65dsi86: Update reply on aux failures Stephen Boyd
  3 siblings, 1 reply; 11+ messages in thread
From: Stephen Boyd @ 2020-10-29  1:11 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: linux-kernel, dri-devel, Douglas Anderson, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul

There's no reason we need to wait here to poll a register over i2c. The
i2c bus is inherently slow and delays are practically part of the
protocol because we have to wait for the device to respond to any
request for a register. Let's rely on the sleeping of the i2c controller
instead of adding any sort of delay here in the bridge driver.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec@siol.net>
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 drivers/gpu/drm/bridge/ti-sn65dsi86.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index 87726b9e446f..8276fa50138f 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -881,9 +881,9 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
 
 	regmap_write(pdata->regmap, SN_AUX_CMD_REG, request_val | AUX_CMD_SEND);
 
+	/* Zero delay loop because i2c transactions are slow already */
 	ret = regmap_read_poll_timeout(pdata->regmap, SN_AUX_CMD_REG, val,
-				       !(val & AUX_CMD_SEND), 200,
-				       50 * 1000);
+				       !(val & AUX_CMD_SEND), 0, 50 * 1000);
 	if (ret)
 		return ret;
 
-- 
Sent by a computer, using git, on the internet


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/4] drm/bridge: ti-sn65dsi86: Read EDID blob over DDC
  2020-10-29  1:11 [PATCH 0/4] drm/bridge: ti-sn65dsi86: Support EDID reading Stephen Boyd
  2020-10-29  1:11 ` [PATCH 1/4] drm/bridge: ti-sn65dsi86: Combine register accesses in ti_sn_aux_transfer() Stephen Boyd
  2020-10-29  1:11 ` [PATCH 2/4] drm/bridge: ti-sn65dsi86: Make polling a busy loop Stephen Boyd
@ 2020-10-29  1:11 ` Stephen Boyd
  2020-10-29 16:11   ` Doug Anderson
  2020-10-29  1:11 ` [PATCH 4/4] drm/bridge: ti-sn65dsi86: Update reply on aux failures Stephen Boyd
  3 siblings, 1 reply; 11+ messages in thread
From: Stephen Boyd @ 2020-10-29  1:11 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: linux-kernel, dri-devel, Douglas Anderson, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul

Use the DDC connection to read the EDID from the eDP panel instead of
relying on the panel to tell us the modes.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec@siol.net>
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 drivers/gpu/drm/bridge/ti-sn65dsi86.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index 8276fa50138f..6b6e98ca2881 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -119,6 +119,7 @@
  * @debugfs:      Used for managing our debugfs.
  * @host_node:    Remote DSI node.
  * @dsi:          Our MIPI DSI source.
+ * @edid:         Detected EDID of eDP panel.
  * @refclk:       Our reference clock.
  * @panel:        Our panel.
  * @enable_gpio:  The GPIO we toggle to enable the bridge.
@@ -144,6 +145,7 @@ struct ti_sn_bridge {
 	struct drm_bridge		bridge;
 	struct drm_connector		connector;
 	struct dentry			*debugfs;
+	struct edid			*edid;
 	struct device_node		*host_node;
 	struct mipi_dsi_device		*dsi;
 	struct clk			*refclk;
@@ -265,6 +267,23 @@ connector_to_ti_sn_bridge(struct drm_connector *connector)
 static int ti_sn_bridge_connector_get_modes(struct drm_connector *connector)
 {
 	struct ti_sn_bridge *pdata = connector_to_ti_sn_bridge(connector);
+	struct edid *edid = pdata->edid;
+	int num, ret;
+
+	if (!edid) {
+		pm_runtime_get_sync(pdata->dev);
+		edid = pdata->edid = drm_get_edid(connector, &pdata->aux.ddc);
+		pm_runtime_put(pdata->dev);
+	}
+
+	if (edid && drm_edid_is_valid(edid)) {
+		ret = drm_connector_update_edid_property(connector, edid);
+		if (!ret) {
+			num = drm_add_edid_modes(connector, edid);
+			if (num)
+				return num;
+		}
+	}
 
 	return drm_panel_get_modes(pdata->panel, connector);
 }
@@ -1245,6 +1264,7 @@ static int ti_sn_bridge_remove(struct i2c_client *client)
 	if (!pdata)
 		return -EINVAL;
 
+	kfree(pdata->edid);
 	ti_sn_debugfs_remove(pdata);
 
 	of_node_put(pdata->host_node);
-- 
Sent by a computer, using git, on the internet


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/4] drm/bridge: ti-sn65dsi86: Update reply on aux failures
  2020-10-29  1:11 [PATCH 0/4] drm/bridge: ti-sn65dsi86: Support EDID reading Stephen Boyd
                   ` (2 preceding siblings ...)
  2020-10-29  1:11 ` [PATCH 3/4] drm/bridge: ti-sn65dsi86: Read EDID blob over DDC Stephen Boyd
@ 2020-10-29  1:11 ` Stephen Boyd
  2020-10-29 16:22   ` Doug Anderson
  3 siblings, 1 reply; 11+ messages in thread
From: Stephen Boyd @ 2020-10-29  1:11 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: linux-kernel, dri-devel, Douglas Anderson, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul

We should be setting the drm_dp_aux_msg::reply field if a NACK or a
SHORT reply happens. Update the error bit handling logic in
ti_sn_aux_transfer() to handle these cases and notify upper layers that
such errors have happened. This helps the retry logic understand that a
timeout has happened, or to shorten the read length if the panel isn't
able to handle the longest read possible.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec@siol.net>
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 drivers/gpu/drm/bridge/ti-sn65dsi86.c | 31 +++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index 6b6e98ca2881..19737bc01b8f 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -878,6 +878,7 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
 	case DP_AUX_NATIVE_READ:
 	case DP_AUX_I2C_READ:
 		regmap_write(pdata->regmap, SN_AUX_CMD_REG, request_val);
+		msg->reply = 0; /* Assume it's good */
 		break;
 	default:
 		return -EINVAL;
@@ -909,10 +910,32 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
 	ret = regmap_read(pdata->regmap, SN_AUX_CMD_STATUS_REG, &val);
 	if (ret)
 		return ret;
-	else if ((val & AUX_IRQ_STATUS_NAT_I2C_FAIL)
-		 || (val & AUX_IRQ_STATUS_AUX_RPLY_TOUT)
-		 || (val & AUX_IRQ_STATUS_AUX_SHORT))
-		return -ENXIO;
+
+	if (val & AUX_IRQ_STATUS_AUX_RPLY_TOUT) {
+		/*
+		 * The hardware tried the message seven times per the DP spec
+		 * but it hit a timeout. We ignore defers here because they're
+		 * handled in hardware.
+		 */
+		return -ETIMEDOUT;
+	}
+	if (val & AUX_IRQ_STATUS_AUX_SHORT) {
+		ret = regmap_read(pdata->regmap, SN_AUX_LENGTH_REG, &len);
+		if (ret)
+			return ret;
+	} else if (val & AUX_IRQ_STATUS_NAT_I2C_FAIL) {
+		switch (request) {
+		case DP_AUX_I2C_WRITE:
+		case DP_AUX_I2C_READ:
+			msg->reply |= DP_AUX_I2C_REPLY_NACK;
+			break;
+		case DP_AUX_NATIVE_READ:
+		case DP_AUX_NATIVE_WRITE:
+			msg->reply |= DP_AUX_NATIVE_REPLY_NACK;
+			break;
+		}
+		return 0;
+	}
 
 	if (request == DP_AUX_NATIVE_WRITE || request == DP_AUX_I2C_WRITE ||
 	    len == 0)
-- 
Sent by a computer, using git, on the internet


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] drm/bridge: ti-sn65dsi86: Combine register accesses in ti_sn_aux_transfer()
  2020-10-29  1:11 ` [PATCH 1/4] drm/bridge: ti-sn65dsi86: Combine register accesses in ti_sn_aux_transfer() Stephen Boyd
@ 2020-10-29 16:10   ` Doug Anderson
  2020-10-30  1:18   ` Stephen Boyd
  1 sibling, 0 replies; 11+ messages in thread
From: Doug Anderson @ 2020-10-29 16:10 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Andrzej Hajda, Neil Armstrong, LKML, dri-devel, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul, Sam Ravnborg

Hi,

On Wed, Oct 28, 2020 at 6:11 PM Stephen Boyd <swboyd@chromium.org> wrote:
>
> These register reads and writes are sometimes directly next to each
> other in the register address space. Let's use regmap bulk read/write
> APIs to get the data with one transfer instead of multiple i2c
> transfers. This helps cut down on the number of transfers in the case of
> something like reading an EDID where we read in blocks of 16 bytes at a
> time and the last for loop here is sending an i2c transfer for each of
> those 16 bytes, one at a time. Ouch!
>
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec@siol.net>
> Cc: Sean Paul <seanpaul@chromium.org>

+Sam Ravnborg has helped land a few changes to this bridge drive in
the past, so maybe good to CC him if you have future spins?

> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 50 ++++++++++++---------------
>  1 file changed, 22 insertions(+), 28 deletions(-)

Since we already did some early reviews off-list, it's not a surprise
that I have no comments.  ;-)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] drm/bridge: ti-sn65dsi86: Make polling a busy loop
  2020-10-29  1:11 ` [PATCH 2/4] drm/bridge: ti-sn65dsi86: Make polling a busy loop Stephen Boyd
@ 2020-10-29 16:11   ` Doug Anderson
  0 siblings, 0 replies; 11+ messages in thread
From: Doug Anderson @ 2020-10-29 16:11 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Andrzej Hajda, Neil Armstrong, LKML, dri-devel, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul, Sam Ravnborg

Hi,

On Wed, Oct 28, 2020 at 6:12 PM Stephen Boyd <swboyd@chromium.org> wrote:
>
> There's no reason we need to wait here to poll a register over i2c. The
> i2c bus is inherently slow and delays are practically part of the
> protocol because we have to wait for the device to respond to any
> request for a register. Let's rely on the sleeping of the i2c controller
> instead of adding any sort of delay here in the bridge driver.
>
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec@siol.net>
> Cc: Sean Paul <seanpaul@chromium.org>
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Since we already did some early reviews off-list, it's not a surprise
that I have no comments.  ;-)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] drm/bridge: ti-sn65dsi86: Read EDID blob over DDC
  2020-10-29  1:11 ` [PATCH 3/4] drm/bridge: ti-sn65dsi86: Read EDID blob over DDC Stephen Boyd
@ 2020-10-29 16:11   ` Doug Anderson
  0 siblings, 0 replies; 11+ messages in thread
From: Doug Anderson @ 2020-10-29 16:11 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Andrzej Hajda, Neil Armstrong, LKML, dri-devel, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul

Hi,

On Wed, Oct 28, 2020 at 6:12 PM Stephen Boyd <swboyd@chromium.org> wrote:
>
> Use the DDC connection to read the EDID from the eDP panel instead of
> relying on the panel to tell us the modes.
>
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec@siol.net>
> Cc: Sean Paul <seanpaul@chromium.org>
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)

Since we already did some early reviews off-list, it's not a surprise
that I have no comments.  ;-)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] drm/bridge: ti-sn65dsi86: Update reply on aux failures
  2020-10-29  1:11 ` [PATCH 4/4] drm/bridge: ti-sn65dsi86: Update reply on aux failures Stephen Boyd
@ 2020-10-29 16:22   ` Doug Anderson
  2020-10-29 20:24     ` Stephen Boyd
  0 siblings, 1 reply; 11+ messages in thread
From: Doug Anderson @ 2020-10-29 16:22 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Andrzej Hajda, Neil Armstrong, LKML, dri-devel, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul, Sam Ravnborg

Hi,

On Wed, Oct 28, 2020 at 6:12 PM Stephen Boyd <swboyd@chromium.org> wrote:
>
> We should be setting the drm_dp_aux_msg::reply field if a NACK or a
> SHORT reply happens.

I don't think you update the "reply" field for SHORT, right?  You just
return a different size?


> Update the error bit handling logic in
> ti_sn_aux_transfer() to handle these cases and notify upper layers that
> such errors have happened. This helps the retry logic understand that a
> timeout has happened, or to shorten the read length if the panel isn't
> able to handle the longest read possible.
>
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec@siol.net>
> Cc: Sean Paul <seanpaul@chromium.org>
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 31 +++++++++++++++++++++++----
>  1 file changed, 27 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> index 6b6e98ca2881..19737bc01b8f 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> @@ -878,6 +878,7 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
>         case DP_AUX_NATIVE_READ:
>         case DP_AUX_I2C_READ:
>                 regmap_write(pdata->regmap, SN_AUX_CMD_REG, request_val);
> +               msg->reply = 0; /* Assume it's good */
>                 break;
>         default:
>                 return -EINVAL;
> @@ -909,10 +910,32 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
>         ret = regmap_read(pdata->regmap, SN_AUX_CMD_STATUS_REG, &val);
>         if (ret)
>                 return ret;
> -       else if ((val & AUX_IRQ_STATUS_NAT_I2C_FAIL)
> -                || (val & AUX_IRQ_STATUS_AUX_RPLY_TOUT)
> -                || (val & AUX_IRQ_STATUS_AUX_SHORT))
> -               return -ENXIO;
> +
> +       if (val & AUX_IRQ_STATUS_AUX_RPLY_TOUT) {
> +               /*
> +                * The hardware tried the message seven times per the DP spec
> +                * but it hit a timeout. We ignore defers here because they're
> +                * handled in hardware.
> +                */
> +               return -ETIMEDOUT;
> +       }
> +       if (val & AUX_IRQ_STATUS_AUX_SHORT) {
> +               ret = regmap_read(pdata->regmap, SN_AUX_LENGTH_REG, &len);
> +               if (ret)
> +                       return ret;

IIUC, your digging through the code showed that in order to fully
handle the "SHORT" case you also needed to add support for
"DP_AUX_I2C_WRITE_STATUS_UPDATE", right?

Even without handling "DP_AUX_I2C_WRITE_STATUS_UPDATE" though, this
patch seems to be an improvement and I'd support landing it.

Oh, I guess one other thing: I think this is all from code inspection,
right?  You didn't manage to reproduce anything that would tickle one
of these code paths?  Might be worth mentioning, even if "after the
cut"?

-Doug

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] drm/bridge: ti-sn65dsi86: Update reply on aux failures
  2020-10-29 16:22   ` Doug Anderson
@ 2020-10-29 20:24     ` Stephen Boyd
  0 siblings, 0 replies; 11+ messages in thread
From: Stephen Boyd @ 2020-10-29 20:24 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Andrzej Hajda, Neil Armstrong, LKML, dri-devel, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul, Sam Ravnborg

Quoting Doug Anderson (2020-10-29 09:22:55)
> Hi,
> 
> On Wed, Oct 28, 2020 at 6:12 PM Stephen Boyd <swboyd@chromium.org> wrote:
> >
> > We should be setting the drm_dp_aux_msg::reply field if a NACK or a
> > SHORT reply happens.
> 
> I don't think you update the "reply" field for SHORT, right?  You just
> return a different size?

Correct.

> 
> 
> > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> > index 6b6e98ca2881..19737bc01b8f 100644
> > --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> > @@ -909,10 +910,32 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
> >         ret = regmap_read(pdata->regmap, SN_AUX_CMD_STATUS_REG, &val);
> >         if (ret)
> >                 return ret;
> > -       else if ((val & AUX_IRQ_STATUS_NAT_I2C_FAIL)
> > -                || (val & AUX_IRQ_STATUS_AUX_RPLY_TOUT)
> > -                || (val & AUX_IRQ_STATUS_AUX_SHORT))
> > -               return -ENXIO;
> > +
> > +       if (val & AUX_IRQ_STATUS_AUX_RPLY_TOUT) {
> > +               /*
> > +                * The hardware tried the message seven times per the DP spec
> > +                * but it hit a timeout. We ignore defers here because they're
> > +                * handled in hardware.
> > +                */
> > +               return -ETIMEDOUT;
> > +       }
> > +       if (val & AUX_IRQ_STATUS_AUX_SHORT) {
> > +               ret = regmap_read(pdata->regmap, SN_AUX_LENGTH_REG, &len);
> > +               if (ret)
> > +                       return ret;
> 
> IIUC, your digging through the code showed that in order to fully
> handle the "SHORT" case you also needed to add support for
> "DP_AUX_I2C_WRITE_STATUS_UPDATE", right?

Oh yeah. If a short reply happens and it is aux over i2c then
drm_dp_i2c_msg_write_status_update() is called and
DP_AUX_I2C_WRITE_STATUS_UPDATE is set and then we try a transfer again.
We need to handle that type of request in this ti_sn_aux_transfer()
function.

> 
> Even without handling "DP_AUX_I2C_WRITE_STATUS_UPDATE" though, this
> patch seems to be an improvement and I'd support landing it.
> 
> Oh, I guess one other thing: I think this is all from code inspection,
> right?  You didn't manage to reproduce anything that would tickle one
> of these code paths?  Might be worth mentioning, even if "after the
> cut"?
> 

Yes, just code inspection. I can add that detail to the commit text.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] drm/bridge: ti-sn65dsi86: Combine register accesses in ti_sn_aux_transfer()
  2020-10-29  1:11 ` [PATCH 1/4] drm/bridge: ti-sn65dsi86: Combine register accesses in ti_sn_aux_transfer() Stephen Boyd
  2020-10-29 16:10   ` Doug Anderson
@ 2020-10-30  1:18   ` Stephen Boyd
  1 sibling, 0 replies; 11+ messages in thread
From: Stephen Boyd @ 2020-10-30  1:18 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: linux-kernel, dri-devel, Douglas Anderson, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sean Paul

Quoting Stephen Boyd (2020-10-28 18:11:51)
> @@ -72,6 +74,7 @@
>  #define SN_AUX_ADDR_19_16_REG                  0x74
>  #define SN_AUX_ADDR_15_8_REG                   0x75
>  #define SN_AUX_ADDR_7_0_REG                    0x76
> +#define SN_AUX_ADDR_MASK                       GENMASK(19, 0)
>  #define SN_AUX_LENGTH_REG                      0x77
>  #define SN_AUX_CMD_REG                         0x78
>  #define  AUX_CMD_SEND                          BIT(0)
> @@ -841,11 +844,13 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
>         struct ti_sn_bridge *pdata = aux_to_ti_sn_bridge(aux);
>         u32 request = msg->request & ~DP_AUX_I2C_MOT;
>         u32 request_val = AUX_CMD_REQ(msg->request);
> -       u8 *buf = (u8 *)msg->buffer;
> +       u8 *buf = msg->buffer;
> +       unsigned int len = msg->size;
>         unsigned int val;
> -       int ret, i;
> +       int ret;
> +       u8 addr_len[SN_AUX_LENGTH_REG + 1 - SN_AUX_ADDR_19_16_REG];

I realize now that the SN_AUX_CMD_REG is also here and it has a "go bit"
in it. We can combine another register write here by writing out the
address, length, and request in one go. I rolled that into v2.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-10-30  1:18 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-29  1:11 [PATCH 0/4] drm/bridge: ti-sn65dsi86: Support EDID reading Stephen Boyd
2020-10-29  1:11 ` [PATCH 1/4] drm/bridge: ti-sn65dsi86: Combine register accesses in ti_sn_aux_transfer() Stephen Boyd
2020-10-29 16:10   ` Doug Anderson
2020-10-30  1:18   ` Stephen Boyd
2020-10-29  1:11 ` [PATCH 2/4] drm/bridge: ti-sn65dsi86: Make polling a busy loop Stephen Boyd
2020-10-29 16:11   ` Doug Anderson
2020-10-29  1:11 ` [PATCH 3/4] drm/bridge: ti-sn65dsi86: Read EDID blob over DDC Stephen Boyd
2020-10-29 16:11   ` Doug Anderson
2020-10-29  1:11 ` [PATCH 4/4] drm/bridge: ti-sn65dsi86: Update reply on aux failures Stephen Boyd
2020-10-29 16:22   ` Doug Anderson
2020-10-29 20:24     ` Stephen Boyd

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