linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5 v3] adv7511 EDID probing improvements
@ 2017-01-03 19:41 John Stultz
  2017-01-03 19:41 ` [PATCH 1/5 v3] drm/bridge: adv7511: Use work_struct to defer hotplug handing to out of irq context John Stultz
                   ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: John Stultz @ 2017-01-03 19:41 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, David Airlie, Archit Taneja, Wolfram Sang,
	Lars-Peter Clausen, Laurent Pinchart, dri-devel

Hope everyone had a good newyears!

Wanted to re-send out v3 of this patch set improving the EDID
probing on the adv7511 used on HiKey, for consideration for
merging for 4.11

The first three patches are fixups that are hopefully straight
forward, integrating feedback I got from Laurant.

The last two patches try to clean up and resue code, which as
a side effect avoids an issue I'm seeing where something is
going wrong with the regmap cache state for the
ADV7511_REG_EDID_I2C_ADDR(0x43) register which results in
i2c_transfer errors if we don't do the
regcache_sync/_mark_dirty() calls. I suspect there might be a
better solution there, but have not gotten any other suggestions
so I wanted to go ahead and submit these.

Thoughts and feedback would be appreciated!

thanks
-john

New in v3:
* Addressed naming improvements and drm_kms_helper_hotplug_event
  usage corrections as suggested by Laurent.

Cc: David Airlie <airlied@linux.ie>
Cc: Archit Taneja <architt@codeaurora.org>
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org

Archit Taneja (1):
  drm/bridge: adv7511: Enable HPD interrupts to support hotplug and
    improve monitor detection

John Stultz (4):
  drm/bridge: adv7511: Use work_struct to defer hotplug handing to out
    of irq context
  drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event()
  drm/bridge: adv7511: Rework adv7511_power_on/off() so they can be
    reused internally
  drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID

 drivers/gpu/drm/bridge/adv7511/adv7511.h     |  2 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 62 +++++++++++++++++++---------
 2 files changed, 44 insertions(+), 20 deletions(-)

-- 
2.7.4

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

* [PATCH 1/5 v3] drm/bridge: adv7511: Use work_struct to defer hotplug handing to out of irq context
  2017-01-03 19:41 [PATCH 0/5 v3] adv7511 EDID probing improvements John Stultz
@ 2017-01-03 19:41 ` John Stultz
  2017-01-03 19:41 ` [PATCH 2/5 v3] drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event() John Stultz
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 20+ messages in thread
From: John Stultz @ 2017-01-03 19:41 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, David Airlie, Archit Taneja, Wolfram Sang,
	Lars-Peter Clausen, Laurent Pinchart, dri-devel

I was recently seeing issues with EDID probing, where
the logic to wait for the EDID read bit to be set by the
IRQ wasn't happening and the code would time out and fail.

Digging deeper, I found this was due to the fact that
IRQs were disabled as we were running in IRQ context from
the HPD signal.

Thus this patch changes the logic to handle the HPD signal
via a work_struct so we can be out of irq context.

With this patch, the EDID probing on hotplug does not time
out.

Cc: David Airlie <airlied@linux.ie>
Cc: Archit Taneja <architt@codeaurora.org>
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
v3: Rename irq_work to hpd_work and remove extra whitespace, as
    suggested by Laurent

 drivers/gpu/drm/bridge/adv7511/adv7511.h     |  2 ++
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 11 ++++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 992d76c..0396791 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -317,6 +317,8 @@ struct adv7511 {
 	bool edid_read;
 
 	wait_queue_head_t wq;
+	struct work_struct hpd_work;
+
 	struct drm_bridge bridge;
 	struct drm_connector connector;
 
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 8dba729..4fcea44 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -402,6 +402,13 @@ static bool adv7511_hpd(struct adv7511 *adv7511)
 	return false;
 }
 
+static void adv7511_hpd_work(struct work_struct *work)
+{
+	struct adv7511 *adv7511 = container_of(work, struct adv7511, hpd_work);
+
+	drm_helper_hpd_irq_event(adv7511->connector.dev);
+}
+
 static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
 {
 	unsigned int irq0, irq1;
@@ -419,7 +426,7 @@ static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
 	regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
 
 	if (process_hpd && irq0 & ADV7511_INT0_HPD && adv7511->bridge.encoder)
-		drm_helper_hpd_irq_event(adv7511->connector.dev);
+		schedule_work(&adv7511->hpd_work);
 
 	if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) {
 		adv7511->edid_read = true;
@@ -1006,6 +1013,8 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
 			goto err_i2c_unregister_edid;
 	}
 
+	INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);
+
 	if (i2c->irq) {
 		init_waitqueue_head(&adv7511->wq);
 
-- 
2.7.4

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

* [PATCH 2/5 v3] drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event()
  2017-01-03 19:41 [PATCH 0/5 v3] adv7511 EDID probing improvements John Stultz
  2017-01-03 19:41 ` [PATCH 1/5 v3] drm/bridge: adv7511: Use work_struct to defer hotplug handing to out of irq context John Stultz
@ 2017-01-03 19:41 ` John Stultz
  2017-01-16 15:47   ` Laurent Pinchart
  2017-01-03 19:41 ` [PATCH 3/5 v3] drm/bridge: adv7511: Enable HPD interrupts to support hotplug and improve monitor detection John Stultz
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: John Stultz @ 2017-01-03 19:41 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, David Airlie, Archit Taneja, Wolfram Sang,
	Lars-Peter Clausen, Laurent Pinchart, dri-devel

In chasing down a previous issue with EDID probing from calling
drm_helper_hpd_irq_event() from irq context, Laurent noticed
that the DRM documentation suggests that
drm_kms_helper_hotplug_event() should be used instead.

Thus this patch replaces drm_helper_hpd_irq_event() with
drm_kms_helper_hotplug_event(), which requires we update the
connector.status entry and only call _hotplug_event() when the
status changes.

Cc: David Airlie <airlied@linux.ie>
Cc: Archit Taneja <architt@codeaurora.org>
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
v3: Update connector.status value and only call __hotplug_event()
    when that status changes, as suggested by Laurent.

 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 4fcea44..d93d66f 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -405,8 +405,22 @@ static bool adv7511_hpd(struct adv7511 *adv7511)
 static void adv7511_hpd_work(struct work_struct *work)
 {
 	struct adv7511 *adv7511 = container_of(work, struct adv7511, hpd_work);
+	enum drm_connector_status status;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val);
+	if (ret < 0)
+		status = connector_status_disconnected;
+	else if (val & ADV7511_STATUS_HPD)
+		status = connector_status_connected;
+	else
+		status = connector_status_disconnected;
+
+	if (adv7511->connector.status != status)
+		drm_kms_helper_hotplug_event(adv7511->connector.dev);
 
-	drm_helper_hpd_irq_event(adv7511->connector.dev);
+	adv7511->connector.status = status;
 }
 
 static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
-- 
2.7.4

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

* [PATCH 3/5 v3] drm/bridge: adv7511: Enable HPD interrupts to support hotplug and improve monitor detection
  2017-01-03 19:41 [PATCH 0/5 v3] adv7511 EDID probing improvements John Stultz
  2017-01-03 19:41 ` [PATCH 1/5 v3] drm/bridge: adv7511: Use work_struct to defer hotplug handing to out of irq context John Stultz
  2017-01-03 19:41 ` [PATCH 2/5 v3] drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event() John Stultz
@ 2017-01-03 19:41 ` John Stultz
  2017-01-03 19:41 ` [PATCH 4/5 v3] drm/bridge: adv7511: Rework adv7511_power_on/off() so they can be reused internally John Stultz
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 20+ messages in thread
From: John Stultz @ 2017-01-03 19:41 UTC (permalink / raw)
  To: lkml
  Cc: Archit Taneja, David Airlie, Wolfram Sang, Lars-Peter Clausen,
	Laurent Pinchart, dri-devel, John Stultz

From: Archit Taneja <architt@codeaurora.org>

On some adv7511 implementations, we can get some spurious
disconnect signals which can cause monitor probing to fail.

This patch enables HPD (hot plug detect) interrupt support
which allows the monitor to be properly re-initialized when
the spurious disconnect signal goes away.

This also enables proper hotplug support.

Cc: David Airlie <airlied@linux.ie>
Cc: Archit Taneja <architt@codeaurora.org>
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Originally-by: Archit Taneja <architt@codeaurora.org>
[jstultz: Added proper commit message]
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index d93d66f..4b90975 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -338,7 +338,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
 		 * Still, let's be safe and stick to the documentation.
 		 */
 		regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0),
-			     ADV7511_INT0_EDID_READY);
+			     ADV7511_INT0_EDID_READY | ADV7511_INT0_HPD);
 		regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1),
 			     ADV7511_INT1_DDC_ERROR);
 	}
@@ -846,6 +846,10 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge)
 	if (adv->type == ADV7533)
 		ret = adv7533_attach_dsi(adv);
 
+	if (adv->i2c_main->irq)
+		regmap_write(adv->regmap, ADV7511_REG_INT_ENABLE(0),
+				ADV7511_INT0_HPD);
+
 	return ret;
 }
 
-- 
2.7.4

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

* [PATCH 4/5 v3] drm/bridge: adv7511: Rework adv7511_power_on/off() so they can be reused internally
  2017-01-03 19:41 [PATCH 0/5 v3] adv7511 EDID probing improvements John Stultz
                   ` (2 preceding siblings ...)
  2017-01-03 19:41 ` [PATCH 3/5 v3] drm/bridge: adv7511: Enable HPD interrupts to support hotplug and improve monitor detection John Stultz
@ 2017-01-03 19:41 ` John Stultz
  2017-01-16 15:50   ` Laurent Pinchart
  2017-01-03 19:41 ` [PATCH 5/5 v3] drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID John Stultz
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: John Stultz @ 2017-01-03 19:41 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, David Airlie, Archit Taneja, Wolfram Sang,
	Lars-Peter Clausen, Laurent Pinchart, dri-devel

In chasing down issues with EDID probing, I found some
duplicated but incomplete logic used to power the chip on and
off.

This patch refactors the adv7511_power_on/off functions, so
they can be used for internal needs.

Cc: David Airlie <airlied@linux.ie>
Cc: Archit Taneja <architt@codeaurora.org>
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 4b90975..dbdb71c 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -325,7 +325,7 @@ static void adv7511_set_link_config(struct adv7511 *adv7511,
 	adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
 }
 
-static void adv7511_power_on(struct adv7511 *adv7511)
+static void __adv7511_power_on(struct adv7511 *adv7511)
 {
 	adv7511->current_edid_segment = -1;
 
@@ -359,24 +359,30 @@ static void adv7511_power_on(struct adv7511 *adv7511)
 	 * Most of the registers are reset during power down or when HPD is low.
 	 */
 	regcache_sync(adv7511->regmap);
+}
 
+static void adv7511_power_on(struct adv7511 *adv7511)
+{
+	__adv7511_power_on(adv7511);
 	if (adv7511->type == ADV7533)
 		adv7533_dsi_power_on(adv7511);
-
 	adv7511->powered = true;
 }
 
-static void adv7511_power_off(struct adv7511 *adv7511)
+static void __adv7511_power_off(struct adv7511 *adv7511)
 {
 	/* TODO: setup additional power down modes */
 	regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
 			   ADV7511_POWER_POWER_DOWN,
 			   ADV7511_POWER_POWER_DOWN);
 	regcache_mark_dirty(adv7511->regmap);
+}
 
+static void adv7511_power_off(struct adv7511 *adv7511)
+{
+	__adv7511_power_off(adv7511);
 	if (adv7511->type == ADV7533)
 		adv7533_dsi_power_off(adv7511);
-
 	adv7511->powered = false;
 }
 
-- 
2.7.4

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

* [PATCH 5/5 v3] drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID
  2017-01-03 19:41 [PATCH 0/5 v3] adv7511 EDID probing improvements John Stultz
                   ` (3 preceding siblings ...)
  2017-01-03 19:41 ` [PATCH 4/5 v3] drm/bridge: adv7511: Rework adv7511_power_on/off() so they can be reused internally John Stultz
@ 2017-01-03 19:41 ` John Stultz
  2017-01-16 16:03   ` Laurent Pinchart
  2017-01-11  8:48 ` [PATCH 0/5 v3] adv7511 EDID probing improvements Archit Taneja
  2017-01-16 15:57 ` Laurent Pinchart
  6 siblings, 1 reply; 20+ messages in thread
From: John Stultz @ 2017-01-03 19:41 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, David Airlie, Archit Taneja, Wolfram Sang,
	Lars-Peter Clausen, Laurent Pinchart, dri-devel

I've found that by just turning the chip on and off via the
POWER_DOWN register, I end up getting i2c_transfer errors
on HiKey.

Investigating further, it seems some of the register state
in the regmap cache is somehow getting lost. Using the logic
in __adv7511_power_on/off() which syncs and dirtys the cache
avoids this issue.

Thus this patch changes the EDID probing logic so that we
re-use the __adv7511_power_on/off() calls.

Cc: David Airlie <airlied@linux.ie>
Cc: Archit Taneja <architt@codeaurora.org>
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index dbdb71c..24573e0 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -572,24 +572,13 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
 	unsigned int count;
 
 	/* Reading the EDID only works if the device is powered */
-	if (!adv7511->powered) {
-		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
-				   ADV7511_POWER_POWER_DOWN, 0);
-		if (adv7511->i2c_main->irq) {
-			regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0),
-				     ADV7511_INT0_EDID_READY);
-			regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1),
-				     ADV7511_INT1_DDC_ERROR);
-		}
-		adv7511->current_edid_segment = -1;
-	}
+	if (!adv7511->powered)
+		__adv7511_power_on(adv7511);
 
 	edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511);
 
 	if (!adv7511->powered)
-		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
-				   ADV7511_POWER_POWER_DOWN,
-				   ADV7511_POWER_POWER_DOWN);
+		__adv7511_power_off(adv7511);
 
 	kfree(adv7511->edid);
 	adv7511->edid = edid;
-- 
2.7.4

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

* Re: [PATCH 0/5 v3] adv7511 EDID probing improvements
  2017-01-03 19:41 [PATCH 0/5 v3] adv7511 EDID probing improvements John Stultz
                   ` (4 preceding siblings ...)
  2017-01-03 19:41 ` [PATCH 5/5 v3] drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID John Stultz
@ 2017-01-11  8:48 ` Archit Taneja
  2017-01-12  0:06   ` John Stultz
  2017-01-16 15:57 ` Laurent Pinchart
  6 siblings, 1 reply; 20+ messages in thread
From: Archit Taneja @ 2017-01-11  8:48 UTC (permalink / raw)
  To: John Stultz, lkml
  Cc: David Airlie, Wolfram Sang, Lars-Peter Clausen, Laurent Pinchart,
	dri-devel

Hi,

On 01/04/2017 01:11 AM, John Stultz wrote:
> Hope everyone had a good newyears!
>
> Wanted to re-send out v3 of this patch set improving the EDID
> probing on the adv7511 used on HiKey, for consideration for
> merging for 4.11
>
> The first three patches are fixups that are hopefully straight
> forward, integrating feedback I got from Laurant.
>
> The last two patches try to clean up and resue code, which as
> a side effect avoids an issue I'm seeing where something is
> going wrong with the regmap cache state for the
> ADV7511_REG_EDID_I2C_ADDR(0x43) register which results in
> i2c_transfer errors if we don't do the
> regcache_sync/_mark_dirty() calls. I suspect there might be a
> better solution there, but have not gotten any other suggestions
> so I wanted to go ahead and submit these.
>
> Thoughts and feedback would be appreciated!

Tested on DB410c on 4.10-rc3. Works well for me.

Thanks,
Archit

>
> thanks
> -john
>
> New in v3:
> * Addressed naming improvements and drm_kms_helper_hotplug_event
>   usage corrections as suggested by Laurent.
>
> Cc: David Airlie <airlied@linux.ie>
> Cc: Archit Taneja <architt@codeaurora.org>
> Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: dri-devel@lists.freedesktop.org
>
> Archit Taneja (1):
>   drm/bridge: adv7511: Enable HPD interrupts to support hotplug and
>     improve monitor detection
>
> John Stultz (4):
>   drm/bridge: adv7511: Use work_struct to defer hotplug handing to out
>     of irq context
>   drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event()
>   drm/bridge: adv7511: Rework adv7511_power_on/off() so they can be
>     reused internally
>   drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID
>
>  drivers/gpu/drm/bridge/adv7511/adv7511.h     |  2 +
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 62 +++++++++++++++++++---------
>  2 files changed, 44 insertions(+), 20 deletions(-)
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH 0/5 v3] adv7511 EDID probing improvements
  2017-01-11  8:48 ` [PATCH 0/5 v3] adv7511 EDID probing improvements Archit Taneja
@ 2017-01-12  0:06   ` John Stultz
  2017-01-12  4:22     ` Archit Taneja
  0 siblings, 1 reply; 20+ messages in thread
From: John Stultz @ 2017-01-12  0:06 UTC (permalink / raw)
  To: Archit Taneja
  Cc: lkml, David Airlie, Wolfram Sang, Lars-Peter Clausen,
	Laurent Pinchart, dri-devel

On Wed, Jan 11, 2017 at 12:48 AM, Archit Taneja <architt@codeaurora.org> wrote:
> Hi,
>
> On 01/04/2017 01:11 AM, John Stultz wrote:
>>
>> Hope everyone had a good newyears!
>>
>> Wanted to re-send out v3 of this patch set improving the EDID
>> probing on the adv7511 used on HiKey, for consideration for
>> merging for 4.11
>>
>> The first three patches are fixups that are hopefully straight
>> forward, integrating feedback I got from Laurant.
>>
>> The last two patches try to clean up and resue code, which as
>> a side effect avoids an issue I'm seeing where something is
>> going wrong with the regmap cache state for the
>> ADV7511_REG_EDID_I2C_ADDR(0x43) register which results in
>> i2c_transfer errors if we don't do the
>> regcache_sync/_mark_dirty() calls. I suspect there might be a
>> better solution there, but have not gotten any other suggestions
>> so I wanted to go ahead and submit these.
>>
>> Thoughts and feedback would be appreciated!
>
>
> Tested on DB410c on 4.10-rc3. Works well for me.

Archit: Thanks for the testing! Is there anything else you need from
me (or others) to queue this for 4.11? Or should I be submitting it to
someone else?

thanks
-john

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

* Re: [PATCH 0/5 v3] adv7511 EDID probing improvements
  2017-01-12  0:06   ` John Stultz
@ 2017-01-12  4:22     ` Archit Taneja
  0 siblings, 0 replies; 20+ messages in thread
From: Archit Taneja @ 2017-01-12  4:22 UTC (permalink / raw)
  To: John Stultz, Laurent Pinchart
  Cc: lkml, David Airlie, Wolfram Sang, Lars-Peter Clausen, dri-devel



On 01/12/2017 05:36 AM, John Stultz wrote:
> On Wed, Jan 11, 2017 at 12:48 AM, Archit Taneja <architt@codeaurora.org> wrote:
>> Hi,
>>
>> On 01/04/2017 01:11 AM, John Stultz wrote:
>>>
>>> Hope everyone had a good newyears!
>>>
>>> Wanted to re-send out v3 of this patch set improving the EDID
>>> probing on the adv7511 used on HiKey, for consideration for
>>> merging for 4.11
>>>
>>> The first three patches are fixups that are hopefully straight
>>> forward, integrating feedback I got from Laurant.
>>>
>>> The last two patches try to clean up and resue code, which as
>>> a side effect avoids an issue I'm seeing where something is
>>> going wrong with the regmap cache state for the
>>> ADV7511_REG_EDID_I2C_ADDR(0x43) register which results in
>>> i2c_transfer errors if we don't do the
>>> regcache_sync/_mark_dirty() calls. I suspect there might be a
>>> better solution there, but have not gotten any other suggestions
>>> so I wanted to go ahead and submit these.
>>>
>>> Thoughts and feedback would be appreciated!
>>
>>
>> Tested on DB410c on 4.10-rc3. Works well for me.
>
> Archit: Thanks for the testing! Is there anything else you need from
> me (or others) to queue this for 4.11? Or should I be submitting it to
> someone else?

A final Ack/Test from Laurent for ADV7511 would be nice. I'll be the one
queuing it to drm-misc for 4.11.

Thanks,
Archit


>
> thanks
> -john
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH 2/5 v3] drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event()
  2017-01-03 19:41 ` [PATCH 2/5 v3] drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event() John Stultz
@ 2017-01-16 15:47   ` Laurent Pinchart
  2017-01-16 15:56     ` Laurent Pinchart
  0 siblings, 1 reply; 20+ messages in thread
From: Laurent Pinchart @ 2017-01-16 15:47 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, David Airlie, Archit Taneja, Wolfram Sang,
	Lars-Peter Clausen, dri-devel

Hi John,

Thank you for the patch.

On Tuesday 03 Jan 2017 11:41:39 John Stultz wrote:
> In chasing down a previous issue with EDID probing from calling
> drm_helper_hpd_irq_event() from irq context, Laurent noticed
> that the DRM documentation suggests that
> drm_kms_helper_hotplug_event() should be used instead.
> 
> Thus this patch replaces drm_helper_hpd_irq_event() with
> drm_kms_helper_hotplug_event(), which requires we update the
> connector.status entry and only call _hotplug_event() when the
> status changes.
> 
> Cc: David Airlie <airlied@linux.ie>
> Cc: Archit Taneja <architt@codeaurora.org>
> Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: John Stultz <john.stultz@linaro.org>
> ---
> v3: Update connector.status value and only call __hotplug_event()
>     when that status changes, as suggested by Laurent.
> 
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 4fcea44..d93d66f
> 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -405,8 +405,22 @@ static bool adv7511_hpd(struct adv7511 *adv7511)
>  static void adv7511_hpd_work(struct work_struct *work)
>  {
>  	struct adv7511 *adv7511 = container_of(work, struct adv7511, 
hpd_work);
> +	enum drm_connector_status status;
> +	unsigned int val;
> +	int ret;
> +
> +	ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val);
> +	if (ret < 0)
> +		status = connector_status_disconnected;
> +	else if (val & ADV7511_STATUS_HPD)
> +		status = connector_status_connected;
> +	else
> +		status = connector_status_disconnected;
> +
> +	if (adv7511->connector.status != status)
> +		drm_kms_helper_hotplug_event(adv7511->connector.dev);
> 
> -	drm_helper_hpd_irq_event(adv7511->connector.dev);
> +	adv7511->connector.status = status;

Shouldn't you update the status before calling drm_kms_helper_hotplug_event() 
? Doing it after not only creates a small race condition as 
drm_kms_helper_hotplug_event() sends an event to userspace that could result 
in an ioctl call to retrieve the status, but the status is also checked by 
drm_setup_crtcs() called by drm_fb_helper_hotplug_event().

>  }
> 
>  static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 4/5 v3] drm/bridge: adv7511: Rework adv7511_power_on/off() so they can be reused internally
  2017-01-03 19:41 ` [PATCH 4/5 v3] drm/bridge: adv7511: Rework adv7511_power_on/off() so they can be reused internally John Stultz
@ 2017-01-16 15:50   ` Laurent Pinchart
  0 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2017-01-16 15:50 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, David Airlie, Archit Taneja, Wolfram Sang,
	Lars-Peter Clausen, dri-devel

Hi John,

Thank you for the patch.

On Tuesday 03 Jan 2017 11:41:41 John Stultz wrote:
> In chasing down issues with EDID probing, I found some
> duplicated but incomplete logic used to power the chip on and
> off.
> 
> This patch refactors the adv7511_power_on/off functions, so
> they can be used for internal needs.
> 
> Cc: David Airlie <airlied@linux.ie>
> Cc: Archit Taneja <architt@codeaurora.org>
> Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: John Stultz <john.stultz@linaro.org>
> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 4b90975..dbdb71c
> 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -325,7 +325,7 @@ static void adv7511_set_link_config(struct adv7511
> *adv7511, adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
>  }
> 
> -static void adv7511_power_on(struct adv7511 *adv7511)
> +static void __adv7511_power_on(struct adv7511 *adv7511)
>  {
>  	adv7511->current_edid_segment = -1;
> 
> @@ -359,24 +359,30 @@ static void adv7511_power_on(struct adv7511 *adv7511)
>  	 * Most of the registers are reset during power down or when HPD is 
low.
>  	 */
>  	regcache_sync(adv7511->regmap);
> +}
> 
> +static void adv7511_power_on(struct adv7511 *adv7511)
> +{
> +	__adv7511_power_on(adv7511);
>  	if (adv7511->type == ADV7533)
>  		adv7533_dsi_power_on(adv7511);
> -
>  	adv7511->powered = true;
>  }
> 
> -static void adv7511_power_off(struct adv7511 *adv7511)
> +static void __adv7511_power_off(struct adv7511 *adv7511)
>  {
>  	/* TODO: setup additional power down modes */
>  	regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
>  			   ADV7511_POWER_POWER_DOWN,
>  			   ADV7511_POWER_POWER_DOWN);
>  	regcache_mark_dirty(adv7511->regmap);
> +}
> 
> +static void adv7511_power_off(struct adv7511 *adv7511)
> +{
> +	__adv7511_power_off(adv7511);
>  	if (adv7511->type == ADV7533)
>  		adv7533_dsi_power_off(adv7511);
> -
>  	adv7511->powered = false;
>  }

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 2/5 v3] drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event()
  2017-01-16 15:47   ` Laurent Pinchart
@ 2017-01-16 15:56     ` Laurent Pinchart
  2017-01-16 19:31       ` John Stultz
  0 siblings, 1 reply; 20+ messages in thread
From: Laurent Pinchart @ 2017-01-16 15:56 UTC (permalink / raw)
  To: dri-devel; +Cc: John Stultz, lkml, Wolfram Sang

On Monday 16 Jan 2017 17:47:46 Laurent Pinchart wrote:
> Hi John,
> 
> Thank you for the patch.
> 
> On Tuesday 03 Jan 2017 11:41:39 John Stultz wrote:
> > In chasing down a previous issue with EDID probing from calling
> > drm_helper_hpd_irq_event() from irq context, Laurent noticed
> > that the DRM documentation suggests that
> > drm_kms_helper_hotplug_event() should be used instead.
> > 
> > Thus this patch replaces drm_helper_hpd_irq_event() with
> > drm_kms_helper_hotplug_event(), which requires we update the
> > connector.status entry and only call _hotplug_event() when the
> > status changes.
> > 
> > Cc: David Airlie <airlied@linux.ie>
> > Cc: Archit Taneja <architt@codeaurora.org>
> > Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
> > Cc: Lars-Peter Clausen <lars@metafoo.de>
> > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Cc: dri-devel@lists.freedesktop.org
> > Signed-off-by: John Stultz <john.stultz@linaro.org>
> > ---
> > v3: Update connector.status value and only call __hotplug_event()
> > 
> >     when that status changes, as suggested by Laurent.
> >  
> >  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 16 +++++++++++++++-
> >  1 file changed, 15 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 4fcea44..d93d66f
> > 100644
> > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > @@ -405,8 +405,22 @@ static bool adv7511_hpd(struct adv7511 *adv7511)
> > 
> >  static void adv7511_hpd_work(struct work_struct *work)
> >  {
> >  
> >  	struct adv7511 *adv7511 = container_of(work, struct adv7511,
> 
> hpd_work);
> 
> > +	enum drm_connector_status status;
> > +	unsigned int val;
> > +	int ret;
> > +
> > +	ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val);
> > +	if (ret < 0)
> > +		status = connector_status_disconnected;
> > +	else if (val & ADV7511_STATUS_HPD)
> > +		status = connector_status_connected;
> > +	else
> > +		status = connector_status_disconnected;
> > +
> > +	if (adv7511->connector.status != status)
> > +		drm_kms_helper_hotplug_event(adv7511->connector.dev);
> > 
> > -	drm_helper_hpd_irq_event(adv7511->connector.dev);
> > +	adv7511->connector.status = status;
> 
> Shouldn't you update the status before calling
> drm_kms_helper_hotplug_event() ? Doing it after not only creates a small
> race condition as
> drm_kms_helper_hotplug_event() sends an event to userspace that could result
> in an ioctl call to retrieve the status, but the status is also checked by
> drm_setup_crtcs() called by drm_fb_helper_hotplug_event().

With

        if (adv7511->connector.status != status) {
                adv7511->connector.status = status;
                drm_kms_helper_hotplug_event(adv7511->connector.dev);
        }

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> >  }
> >  
> >  static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 0/5 v3] adv7511 EDID probing improvements
  2017-01-03 19:41 [PATCH 0/5 v3] adv7511 EDID probing improvements John Stultz
                   ` (5 preceding siblings ...)
  2017-01-11  8:48 ` [PATCH 0/5 v3] adv7511 EDID probing improvements Archit Taneja
@ 2017-01-16 15:57 ` Laurent Pinchart
  6 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2017-01-16 15:57 UTC (permalink / raw)
  To: dri-devel; +Cc: John Stultz, lkml, Wolfram Sang

Hi John,

Thank you for the patches.

On Tuesday 03 Jan 2017 11:41:37 John Stultz wrote:
> Hope everyone had a good newyears!
> 
> Wanted to re-send out v3 of this patch set improving the EDID
> probing on the adv7511 used on HiKey, for consideration for
> merging for 4.11
> 
> The first three patches are fixups that are hopefully straight
> forward, integrating feedback I got from Laurant.
> 
> The last two patches try to clean up and resue code, which as
> a side effect avoids an issue I'm seeing where something is
> going wrong with the regmap cache state for the
> ADV7511_REG_EDID_I2C_ADDR(0x43) register which results in
> i2c_transfer errors if we don't do the
> regcache_sync/_mark_dirty() calls. I suspect there might be a
> better solution there, but have not gotten any other suggestions
> so I wanted to go ahead and submit these.
> 
> Thoughts and feedback would be appreciated!

For the whole series,

Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> New in v3:
> * Addressed naming improvements and drm_kms_helper_hotplug_event
>   usage corrections as suggested by Laurent.
> 
> Cc: David Airlie <airlied@linux.ie>
> Cc: Archit Taneja <architt@codeaurora.org>
> Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: dri-devel@lists.freedesktop.org
> 
> Archit Taneja (1):
>   drm/bridge: adv7511: Enable HPD interrupts to support hotplug and
>     improve monitor detection
> 
> John Stultz (4):
>   drm/bridge: adv7511: Use work_struct to defer hotplug handing to out
>     of irq context
>   drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event()
>   drm/bridge: adv7511: Rework adv7511_power_on/off() so they can be
>     reused internally
>   drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID
> 
>  drivers/gpu/drm/bridge/adv7511/adv7511.h     |  2 +
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 62
> +++++++++++++++++++--------- 2 files changed, 44 insertions(+), 20
> deletions(-)

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 5/5 v3] drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID
  2017-01-03 19:41 ` [PATCH 5/5 v3] drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID John Stultz
@ 2017-01-16 16:03   ` Laurent Pinchart
  2017-01-16 20:14     ` John Stultz
  0 siblings, 1 reply; 20+ messages in thread
From: Laurent Pinchart @ 2017-01-16 16:03 UTC (permalink / raw)
  To: dri-devel; +Cc: John Stultz, lkml, Wolfram Sang

Hi John,

Thank you for the patch.

On Tuesday 03 Jan 2017 11:41:42 John Stultz wrote:
> I've found that by just turning the chip on and off via the
> POWER_DOWN register, I end up getting i2c_transfer errors
> on HiKey.
> 
> Investigating further, it seems some of the register state
> in the regmap cache is somehow getting lost. Using the logic
> in __adv7511_power_on/off() which syncs and dirtys the cache
> avoids this issue.
> 
> Thus this patch changes the EDID probing logic so that we
> re-use the __adv7511_power_on/off() calls.

regcache_sync() is quite costly as it will write a bunch of registers. 
Wouldn't it be more efficient to only write the registers that are needed for 
EDID access ?

> Cc: David Airlie <airlied@linux.ie>
> Cc: Archit Taneja <architt@codeaurora.org>
> Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: John Stultz <john.stultz@linaro.org>
> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 17 +++--------------
>  1 file changed, 3 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index dbdb71c..24573e0
> 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -572,24 +572,13 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
>  	unsigned int count;
> 
>  	/* Reading the EDID only works if the device is powered */
> -	if (!adv7511->powered) {
> -		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
> -				   ADV7511_POWER_POWER_DOWN, 0);
> -		if (adv7511->i2c_main->irq) {
> -			regmap_write(adv7511->regmap, 
ADV7511_REG_INT_ENABLE(0),
> -				     ADV7511_INT0_EDID_READY);
> -			regmap_write(adv7511->regmap, 
ADV7511_REG_INT_ENABLE(1),
> -				     ADV7511_INT1_DDC_ERROR);
> -		}
> -		adv7511->current_edid_segment = -1;
> -	}
> +	if (!adv7511->powered)
> +		__adv7511_power_on(adv7511);
> 
>  	edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511);
> 
>  	if (!adv7511->powered)
> -		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
> -				   ADV7511_POWER_POWER_DOWN,
> -				   ADV7511_POWER_POWER_DOWN);
> +		__adv7511_power_off(adv7511);
> 
>  	kfree(adv7511->edid);
>  	adv7511->edid = edid;

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 2/5 v3] drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event()
  2017-01-16 15:56     ` Laurent Pinchart
@ 2017-01-16 19:31       ` John Stultz
  0 siblings, 0 replies; 20+ messages in thread
From: John Stultz @ 2017-01-16 19:31 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: dri-devel, lkml, Wolfram Sang

On Mon, Jan 16, 2017 at 7:56 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Monday 16 Jan 2017 17:47:46 Laurent Pinchart wrote:
>> Hi John,
>>
>> Thank you for the patch.
>>
>> On Tuesday 03 Jan 2017 11:41:39 John Stultz wrote:
>> > In chasing down a previous issue with EDID probing from calling
>> > drm_helper_hpd_irq_event() from irq context, Laurent noticed
>> > that the DRM documentation suggests that
>> > drm_kms_helper_hotplug_event() should be used instead.
>> >
>> > Thus this patch replaces drm_helper_hpd_irq_event() with
>> > drm_kms_helper_hotplug_event(), which requires we update the
>> > connector.status entry and only call _hotplug_event() when the
>> > status changes.
>> >
>> > Cc: David Airlie <airlied@linux.ie>
>> > Cc: Archit Taneja <architt@codeaurora.org>
>> > Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
>> > Cc: Lars-Peter Clausen <lars@metafoo.de>
>> > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>> > Cc: dri-devel@lists.freedesktop.org
>> > Signed-off-by: John Stultz <john.stultz@linaro.org>
>> > ---
>> > v3: Update connector.status value and only call __hotplug_event()
>> >
>> >     when that status changes, as suggested by Laurent.
>> >
>> >  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 16 +++++++++++++++-
>> >  1 file changed, 15 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> > b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 4fcea44..d93d66f
>> > 100644
>> > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> > @@ -405,8 +405,22 @@ static bool adv7511_hpd(struct adv7511 *adv7511)
>> >
>> >  static void adv7511_hpd_work(struct work_struct *work)
>> >  {
>> >
>> >     struct adv7511 *adv7511 = container_of(work, struct adv7511,
>>
>> hpd_work);
>>
>> > +   enum drm_connector_status status;
>> > +   unsigned int val;
>> > +   int ret;
>> > +
>> > +   ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val);
>> > +   if (ret < 0)
>> > +           status = connector_status_disconnected;
>> > +   else if (val & ADV7511_STATUS_HPD)
>> > +           status = connector_status_connected;
>> > +   else
>> > +           status = connector_status_disconnected;
>> > +
>> > +   if (adv7511->connector.status != status)
>> > +           drm_kms_helper_hotplug_event(adv7511->connector.dev);
>> >
>> > -   drm_helper_hpd_irq_event(adv7511->connector.dev);
>> > +   adv7511->connector.status = status;
>>
>> Shouldn't you update the status before calling
>> drm_kms_helper_hotplug_event() ? Doing it after not only creates a small
>> race condition as
>> drm_kms_helper_hotplug_event() sends an event to userspace that could result
>> in an ioctl call to retrieve the status, but the status is also checked by
>> drm_setup_crtcs() called by drm_fb_helper_hotplug_event().
>
> With
>
>         if (adv7511->connector.status != status) {
>                 adv7511->connector.status = status;
>                 drm_kms_helper_hotplug_event(adv7511->connector.dev);
>         }
>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Thanks so much for catching this! I'll respin the patches with this
fix and resend a v4.

thanks again!
-john

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

* Re: [PATCH 5/5 v3] drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID
  2017-01-16 16:03   ` Laurent Pinchart
@ 2017-01-16 20:14     ` John Stultz
  2017-01-16 22:25       ` Laurent Pinchart
  0 siblings, 1 reply; 20+ messages in thread
From: John Stultz @ 2017-01-16 20:14 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: dri-devel, lkml, Wolfram Sang

On Mon, Jan 16, 2017 at 8:03 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi John,
>
> Thank you for the patch.
>
> On Tuesday 03 Jan 2017 11:41:42 John Stultz wrote:
>> I've found that by just turning the chip on and off via the
>> POWER_DOWN register, I end up getting i2c_transfer errors
>> on HiKey.
>>
>> Investigating further, it seems some of the register state
>> in the regmap cache is somehow getting lost. Using the logic
>> in __adv7511_power_on/off() which syncs and dirtys the cache
>> avoids this issue.
>>
>> Thus this patch changes the EDID probing logic so that we
>> re-use the __adv7511_power_on/off() calls.
>
> regcache_sync() is quite costly as it will write a bunch of registers.
> Wouldn't it be more efficient to only write the registers that are needed for
> EDID access ?

So yes, you've mentioned this concern before, and I did spend some
time to narrow which lost-register state (0x43
 - ADV7511_REG_EDID_I2C_ADDR) was causing the trouble with i2c
trasnfer errors I was seeing:
  https://lkml.org/lkml/2016/11/22/677

However, I didn't get much feedback on that, and it seems (to me at
least) concerning that we are losing the underlying state of a
register in the cache, so just syncing that one register back to the
hardware might solve the issue I was seeing, but I worry what other
registers might also be out of sync.

The comment above the regmap_sync in adv7511_power_on after all states:
   "Most of the registers are reset during power down or when HPD is low."

So it seems like if we're setting the power down (and setting HPD in
cases where Archit had a patch to add HPD pulsing to the
adv7511_get_modes path), it seems reasonable to do the same
regmap_sync()?

But, I'm not really picky here, and I'm very open to other approaches
(including something like the patch in the link above) if you have
suggestions/preferences. I just want it to work reliably on my
hardware. :)

And just so I can better understand it, can you explain some about the
impact of your efficiency concerns?

thanks
-john

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

* Re: [PATCH 5/5 v3] drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID
  2017-01-16 20:14     ` John Stultz
@ 2017-01-16 22:25       ` Laurent Pinchart
  2017-01-16 23:16         ` [RFC][PATCH] drm/bridge: adv7511: Re-write the i2c address as it may have been lost John Stultz
  0 siblings, 1 reply; 20+ messages in thread
From: Laurent Pinchart @ 2017-01-16 22:25 UTC (permalink / raw)
  To: John Stultz; +Cc: dri-devel, lkml, Wolfram Sang

Hi John,

On Monday 16 Jan 2017 12:14:48 John Stultz wrote:
> On Mon, Jan 16, 2017 at 8:03 AM, Laurent Pinchart wrote:
> > On Tuesday 03 Jan 2017 11:41:42 John Stultz wrote:
> >> I've found that by just turning the chip on and off via the
> >> POWER_DOWN register, I end up getting i2c_transfer errors
> >> on HiKey.
> >> 
> >> Investigating further, it seems some of the register state
> >> in the regmap cache is somehow getting lost. Using the logic
> >> in __adv7511_power_on/off() which syncs and dirtys the cache
> >> avoids this issue.
> >> 
> >> Thus this patch changes the EDID probing logic so that we
> >> re-use the __adv7511_power_on/off() calls.
> > 
> > regcache_sync() is quite costly as it will write a bunch of registers.
> > Wouldn't it be more efficient to only write the registers that are needed
> > for EDID access ?
> 
> So yes, you've mentioned this concern before, and I did spend some
> time to narrow which lost-register state (0x43
>  - ADV7511_REG_EDID_I2C_ADDR) was causing the trouble with i2c
> trasnfer errors I was seeing:
>   https://lkml.org/lkml/2016/11/22/677
> 
> However, I didn't get much feedback on that, and it seems (to me at
> least) concerning that we are losing the underlying state of a
> register in the cache, so just syncing that one register back to the
> hardware might solve the issue I was seeing, but I worry what other
> registers might also be out of sync.
>
> The comment above the regmap_sync in adv7511_power_on after all states:
>    "Most of the registers are reset during power down or when HPD is low."

You're right that most registers will be out of sync.

> So it seems like if we're setting the power down (and setting HPD in
> cases where Archit had a patch to add HPD pulsing to the
> adv7511_get_modes path), it seems reasonable to do the same
> regmap_sync()?

It would be if we had to keep the device powered up, but we're powering it 
down right after reading the EDID. I don't think there's a need to reconfigure 
it completely, only setting the registers needed to read the EDID should be 
enough.

> But, I'm not really picky here, and I'm very open to other approaches
> (including something like the patch in the link above) if you have
> suggestions/preferences. I just want it to work reliably on my
> hardware. :)
>
> And just so I can better understand it, can you explain some about the
> impact of your efficiency concerns?

I'm not too picky either :-) If we can't find a reliable way to read the EDID 
by just configuring the registers we need, we could go for a full 
reconfiguration. However, restoring the value of all cached registers will 
result in lots of I2C writes, which are time-consuming operations. EDID read 
would be sped up if we could avoid that.

-- 
Regards,

Laurent Pinchart

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

* [RFC][PATCH] drm/bridge: adv7511: Re-write the i2c address as it may have been lost
  2017-01-16 22:25       ` Laurent Pinchart
@ 2017-01-16 23:16         ` John Stultz
  2017-01-16 23:36           ` Laurent Pinchart
  0 siblings, 1 reply; 20+ messages in thread
From: John Stultz @ 2017-01-16 23:16 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, David Airlie, Archit Taneja, Wolfram Sang,
	Lars-Peter Clausen, Laurent Pinchart, dri-devel

Laurent: Would something like the following be preferred? Seems
to work as well for me..

thanks
-john


I've found that by just turning the chip on and off via the
POWER_DOWN register, I end up getting i2c_transfer errors on
HiKey.

Investigating further, it seems some of the register state in
the regmap cache is somehow getting lost, likely as the device
registers were reset during power off.

Thus this patch simply re-writes the i2c address to the
ADV7511_REG_EDID_I2C_ADDR register to ensure its properly set
before we try to read the EDID data.

Cc: David Airlie <airlied@linux.ie>
Cc: Archit Taneja <architt@codeaurora.org>
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 405e460..32c59cb 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -567,6 +567,8 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
 
 	/* Reading the EDID only works if the device is powered */
 	if (!adv7511->powered) {
+		unsigned int edid_i2c_addr = (adv7511->i2c_main->addr << 1) + 4;
+
 		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
 				   ADV7511_POWER_POWER_DOWN, 0);
 		if (adv7511->i2c_main->irq) {
@@ -576,6 +578,9 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
 				     ADV7511_INT1_DDC_ERROR);
 		}
 		adv7511->current_edid_segment = -1;
+
+		/* Reset the EDID_I2C_ADDR register as it may have been cleared */
+		regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr);
 	}
 
 	edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511);
-- 
2.7.4

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

* Re: [RFC][PATCH] drm/bridge: adv7511: Re-write the i2c address as it may have been lost
  2017-01-16 23:16         ` [RFC][PATCH] drm/bridge: adv7511: Re-write the i2c address as it may have been lost John Stultz
@ 2017-01-16 23:36           ` Laurent Pinchart
  2017-01-16 23:39             ` John Stultz
  0 siblings, 1 reply; 20+ messages in thread
From: Laurent Pinchart @ 2017-01-16 23:36 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, David Airlie, Archit Taneja, Wolfram Sang,
	Lars-Peter Clausen, dri-devel

Hi John,

Thank you for the patch.

On Monday 16 Jan 2017 15:16:51 John Stultz wrote:
> Laurent: Would something like the following be preferred? Seems
> to work as well for me..

That looks good to me. Feel free to still de-duplicate the power on/off code 
if you want (but of course without adding the regcache_sync to the common 
power on function this time).

Please see below for an additional comment.

> I've found that by just turning the chip on and off via the
> POWER_DOWN register, I end up getting i2c_transfer errors on
> HiKey.
> 
> Investigating further, it seems some of the register state in
> the regmap cache is somehow getting lost, likely as the device
> registers were reset during power off.
> 
> Thus this patch simply re-writes the i2c address to the
> ADV7511_REG_EDID_I2C_ADDR register to ensure its properly set
> before we try to read the EDID data.
> 
> Cc: David Airlie <airlied@linux.ie>
> Cc: Archit Taneja <architt@codeaurora.org>
> Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: John Stultz <john.stultz@linaro.org>
> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 405e460..32c59cb
> 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -567,6 +567,8 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
> 
>  	/* Reading the EDID only works if the device is powered */
>  	if (!adv7511->powered) {
> +		unsigned int edid_i2c_addr = (adv7511->i2c_main->addr << 1) + 
4;
> +
>  		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
>  				   ADV7511_POWER_POWER_DOWN, 0);
>  		if (adv7511->i2c_main->irq) {
> @@ -576,6 +578,9 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
>  				     ADV7511_INT1_DDC_ERROR);
>  		}
>  		adv7511->current_edid_segment = -1;
> +
> +		/* Reset the EDID_I2C_ADDR register as it may have been 
cleared */
> +		regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, 
edid_i2c_addr);

As powering the device off called regcache_mark_dirty(), this will perform an 
I2C write and cache the value. If we then try to read the EDID a second time 
without going through a full power on/off sequence, I believe that regmap will 
skip the write the second time, as the cache will contain the same value and 
won't be marked as dirty. Should we call regcache_mark_dirty() when powering 
the device down further down this function ?

>  	}
> 
>  	edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511);

-- 
Regards,

Laurent Pinchart

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

* Re: [RFC][PATCH] drm/bridge: adv7511: Re-write the i2c address as it may have been lost
  2017-01-16 23:36           ` Laurent Pinchart
@ 2017-01-16 23:39             ` John Stultz
  0 siblings, 0 replies; 20+ messages in thread
From: John Stultz @ 2017-01-16 23:39 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: lkml, David Airlie, Archit Taneja, Wolfram Sang,
	Lars-Peter Clausen, dri-devel

On Mon, Jan 16, 2017 at 3:36 PM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi John,
>
> Thank you for the patch.
>
> On Monday 16 Jan 2017 15:16:51 John Stultz wrote:
>> Laurent: Would something like the following be preferred? Seems
>> to work as well for me..
>
> That looks good to me. Feel free to still de-duplicate the power on/off code
> if you want (but of course without adding the regcache_sync to the common
> power on function this time).

Ok.  Will do that. Thanks again for the feedback/direction here!

>> @@ -576,6 +578,9 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
>>                                    ADV7511_INT1_DDC_ERROR);
>>               }
>>               adv7511->current_edid_segment = -1;
>> +
>> +             /* Reset the EDID_I2C_ADDR register as it may have been
> cleared */
>> +             regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,
> edid_i2c_addr);
>
> As powering the device off called regcache_mark_dirty(), this will perform an
> I2C write and cache the value. If we then try to read the EDID a second time
> without going through a full power on/off sequence, I believe that regmap will
> skip the write the second time, as the cache will contain the same value and
> won't be marked as dirty. Should we call regcache_mark_dirty() when powering
> the device down further down this function ?

Ah. Right. I had this in my earlier attempt, but thought I was
simplifying things here. I'll correct this in the next revision.

Thanks again!
-john

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

end of thread, other threads:[~2017-01-16 23:39 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-03 19:41 [PATCH 0/5 v3] adv7511 EDID probing improvements John Stultz
2017-01-03 19:41 ` [PATCH 1/5 v3] drm/bridge: adv7511: Use work_struct to defer hotplug handing to out of irq context John Stultz
2017-01-03 19:41 ` [PATCH 2/5 v3] drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event() John Stultz
2017-01-16 15:47   ` Laurent Pinchart
2017-01-16 15:56     ` Laurent Pinchart
2017-01-16 19:31       ` John Stultz
2017-01-03 19:41 ` [PATCH 3/5 v3] drm/bridge: adv7511: Enable HPD interrupts to support hotplug and improve monitor detection John Stultz
2017-01-03 19:41 ` [PATCH 4/5 v3] drm/bridge: adv7511: Rework adv7511_power_on/off() so they can be reused internally John Stultz
2017-01-16 15:50   ` Laurent Pinchart
2017-01-03 19:41 ` [PATCH 5/5 v3] drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID John Stultz
2017-01-16 16:03   ` Laurent Pinchart
2017-01-16 20:14     ` John Stultz
2017-01-16 22:25       ` Laurent Pinchart
2017-01-16 23:16         ` [RFC][PATCH] drm/bridge: adv7511: Re-write the i2c address as it may have been lost John Stultz
2017-01-16 23:36           ` Laurent Pinchart
2017-01-16 23:39             ` John Stultz
2017-01-11  8:48 ` [PATCH 0/5 v3] adv7511 EDID probing improvements Archit Taneja
2017-01-12  0:06   ` John Stultz
2017-01-12  4:22     ` Archit Taneja
2017-01-16 15:57 ` Laurent Pinchart

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