linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] drm: dw-hdmi: update CEC phys addr, EDID and ELD on HPD event
@ 2019-09-01 16:13 Jonas Karlman
  2019-09-01 16:14 ` [PATCH 1/5] drm: dw-hdmi: extract dw_hdmi_connector_update_edid() Jonas Karlman
       [not found] ` <20190901161426.1606-1-jonas@kwiboo.se>
  0 siblings, 2 replies; 12+ messages in thread
From: Jonas Karlman @ 2019-09-01 16:13 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel, Jonas Karlman

This series change dw-hdmi to update CEC phys addr, EDID and ELD on HPD event,
this fixes lost CEC phys addr and stale EDID/ELD when HDMI cable is
unplugged/replugged or AVR is powered on/off.

Patch 1 and 2 extracts code into a dw_hdmi_connector_update_edid() helper
and moves dw_hdmi_connector_detect() to be able to call this helper.

Patch 3 moves CEC phys addr invalidation from dw_hdmi_irq() to
dw_hdmi_connector_detect() and ensure connector EDID property gets updated.
I opted to not use cec_notifier_mutex after the move, please advise.

Patch 4 and 5 ensures ELD gets updated allowing userspace to query the latest
capabilities when a AVR is powered on and EDID gets updated.
This reverts a previous change to make drm_edid_to_eld() static, please advise.

Next step after this would be to add support for signaling
SNDRV_CTL_EVENT_MASK_VALUE to userspace when ELD changes.

Regards,
Jonas

Jonas Karlman (5):
  drm: dw-hdmi: extract dw_hdmi_connector_update_edid()
  drm: dw-hdmi: move dw_hdmi_connector_detect()
  drm: dw-hdmi: update CEC phys addr and EDID on HPD event
  Revert "drm/edid: make drm_edid_to_eld() static"
  drm: dw-hdmi: update ELD on HPD event

 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 57 ++++++++++++++---------
 drivers/gpu/drm/drm_edid.c                |  5 +-
 include/drm/drm_edid.h                    |  1 +
 3 files changed, 38 insertions(+), 25 deletions(-)

-- 
2.17.1


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

* [PATCH 1/5] drm: dw-hdmi: extract dw_hdmi_connector_update_edid()
  2019-09-01 16:13 [PATCH 0/5] drm: dw-hdmi: update CEC phys addr, EDID and ELD on HPD event Jonas Karlman
@ 2019-09-01 16:14 ` Jonas Karlman
  2019-09-02  8:05   ` Neil Armstrong
       [not found] ` <20190901161426.1606-1-jonas@kwiboo.se>
  1 sibling, 1 reply; 12+ messages in thread
From: Jonas Karlman @ 2019-09-01 16:14 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel, Jonas Karlman

Extract code that updates EDID into a dw_hdmi_connector_update_edid()
helper, it will be called from dw_hdmi_connector_detect().

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 521d689413c8..8ab214dc5ae7 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2171,7 +2171,8 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
 }
 
-static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
+static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
+					  bool add_modes)
 {
 	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
@@ -2190,7 +2191,8 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
 		drm_connector_update_edid_property(connector, edid);
 		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
-		ret = drm_add_edid_modes(connector, edid);
+		if (add_modes)
+			ret = drm_add_edid_modes(connector, edid);
 		kfree(edid);
 	} else {
 		dev_dbg(hdmi->dev, "failed to get edid\n");
@@ -2199,6 +2201,11 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 	return ret;
 }
 
+static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
+{
+	return dw_hdmi_connector_update_edid(connector, true);
+}
+
 static void dw_hdmi_connector_force(struct drm_connector *connector)
 {
 	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
-- 
2.17.1


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

* [PATCH 2/5] drm: dw-hdmi: move dw_hdmi_connector_detect()
       [not found] ` <20190901161426.1606-1-jonas@kwiboo.se>
@ 2019-09-01 16:14   ` Jonas Karlman
  2019-09-02  8:05     ` Neil Armstrong
  2019-09-01 16:14   ` [PATCH 3/5] drm: dw-hdmi: update CEC phys addr and EDID on HPD event Jonas Karlman
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Jonas Karlman @ 2019-09-01 16:14 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel, Jonas Karlman

Move dw_hdmi_connector_detect() it will call dw_hdmi_connector_update_edid().

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 30 +++++++++++------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 8ab214dc5ae7..91d86ddd6624 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2156,21 +2156,6 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
 					  hdmi->rxsense);
 }
 
-static enum drm_connector_status
-dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
-{
-	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
-					     connector);
-
-	mutex_lock(&hdmi->mutex);
-	hdmi->force = DRM_FORCE_UNSPECIFIED;
-	dw_hdmi_update_power(hdmi);
-	dw_hdmi_update_phy_mask(hdmi);
-	mutex_unlock(&hdmi->mutex);
-
-	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
-}
-
 static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
 					  bool add_modes)
 {
@@ -2201,6 +2186,21 @@ static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
 	return ret;
 }
 
+static enum drm_connector_status
+dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
+{
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
+					     connector);
+
+	mutex_lock(&hdmi->mutex);
+	hdmi->force = DRM_FORCE_UNSPECIFIED;
+	dw_hdmi_update_power(hdmi);
+	dw_hdmi_update_phy_mask(hdmi);
+	mutex_unlock(&hdmi->mutex);
+
+	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
+}
+
 static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 {
 	return dw_hdmi_connector_update_edid(connector, true);
-- 
2.17.1


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

* [PATCH 3/5] drm: dw-hdmi: update CEC phys addr and EDID on HPD event
       [not found] ` <20190901161426.1606-1-jonas@kwiboo.se>
  2019-09-01 16:14   ` [PATCH 2/5] drm: dw-hdmi: move dw_hdmi_connector_detect() Jonas Karlman
@ 2019-09-01 16:14   ` Jonas Karlman
  2019-09-02  8:10     ` Neil Armstrong
  2019-09-01 16:14   ` [PATCH 4/5] Revert "drm/edid: make drm_edid_to_eld() static" Jonas Karlman
  2019-09-01 16:14   ` [PATCH 5/5] drm: dw-hdmi: update ELD on HPD event Jonas Karlman
  3 siblings, 1 reply; 12+ messages in thread
From: Jonas Karlman @ 2019-09-01 16:14 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel, Jonas Karlman

Update CEC phys addr and EDID on HPD event, fixes lost CEC phys addr and
stale EDID when HDMI cable is unplugged/replugged or AVR is powered on/off.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 91d86ddd6624..0f07be1b5914 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2189,6 +2189,7 @@ static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
 static enum drm_connector_status
 dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
+	enum drm_connector_status status;
 	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
 
@@ -2198,7 +2199,14 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
 
-	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
+	status = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
+
+	if (status == connector_status_connected)
+		dw_hdmi_connector_update_edid(connector, false);
+	else
+		cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
+
+	return status;
 }
 
 static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
@@ -2438,12 +2446,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 		dw_hdmi_setup_rx_sense(hdmi,
 				       phy_stat & HDMI_PHY_HPD,
 				       phy_stat & HDMI_PHY_RX_SENSE);
-
-		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
-			mutex_lock(&hdmi->cec_notifier_mutex);
-			cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
-			mutex_unlock(&hdmi->cec_notifier_mutex);
-		}
 	}
 
 	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
-- 
2.17.1


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

* [PATCH 4/5] Revert "drm/edid: make drm_edid_to_eld() static"
       [not found] ` <20190901161426.1606-1-jonas@kwiboo.se>
  2019-09-01 16:14   ` [PATCH 2/5] drm: dw-hdmi: move dw_hdmi_connector_detect() Jonas Karlman
  2019-09-01 16:14   ` [PATCH 3/5] drm: dw-hdmi: update CEC phys addr and EDID on HPD event Jonas Karlman
@ 2019-09-01 16:14   ` Jonas Karlman
  2019-09-02  8:07     ` Neil Armstrong
  2019-09-01 16:14   ` [PATCH 5/5] drm: dw-hdmi: update ELD on HPD event Jonas Karlman
  3 siblings, 1 reply; 12+ messages in thread
From: Jonas Karlman @ 2019-09-01 16:14 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel, Jonas Karlman

drm_edid_to_eld() is needed to update stale connector ELD on HPD event.

This reverts part of commit 79436a1c9bcc ("drm/edid: make drm_edid_to_eld() static").

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
 drivers/gpu/drm/drm_edid.c | 5 +++--
 include/drm/drm_edid.h     | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 82a4ceed3fcf..47c409af0903 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4069,7 +4069,7 @@ static void clear_eld(struct drm_connector *connector)
 	connector->audio_latency[1] = 0;
 }
 
-/*
+/**
  * drm_edid_to_eld - build ELD from EDID
  * @connector: connector corresponding to the HDMI/DP sink
  * @edid: EDID to parse
@@ -4077,7 +4077,7 @@ static void clear_eld(struct drm_connector *connector)
  * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The
  * HDCP and Port_ID ELD fields are left for the graphics driver to fill in.
  */
-static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
+void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
 {
 	uint8_t *eld = connector->eld;
 	u8 *cea;
@@ -4162,6 +4162,7 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
 	DRM_DEBUG_KMS("ELD size %d, SAD count %d\n",
 		      drm_eld_size(eld), total_sad_count);
 }
+EXPORT_SYMBOL(drm_edid_to_eld);
 
 /**
  * drm_edid_to_sad - extracts SADs from EDID
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index b9719418c3d2..49987818fe23 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -337,6 +337,7 @@ struct drm_connector;
 struct drm_connector_state;
 struct drm_display_mode;
 
+void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid);
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
 int drm_av_sync_delay(struct drm_connector *connector,
-- 
2.17.1


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

* [PATCH 5/5] drm: dw-hdmi: update ELD on HPD event
       [not found] ` <20190901161426.1606-1-jonas@kwiboo.se>
                     ` (2 preceding siblings ...)
  2019-09-01 16:14   ` [PATCH 4/5] Revert "drm/edid: make drm_edid_to_eld() static" Jonas Karlman
@ 2019-09-01 16:14   ` Jonas Karlman
  2019-09-02  8:08     ` Neil Armstrong
  3 siblings, 1 reply; 12+ messages in thread
From: Jonas Karlman @ 2019-09-01 16:14 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel, Jonas Karlman

Update connector ELD on HPD event, fixes stale ELD when
HDMI cable is unplugged/replugged or AVR is powered on/off.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 0f07be1b5914..0a8268b20561 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2178,6 +2178,8 @@ static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
 		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
 		if (add_modes)
 			ret = drm_add_edid_modes(connector, edid);
+		else
+			drm_edid_to_eld(connector, edid);
 		kfree(edid);
 	} else {
 		dev_dbg(hdmi->dev, "failed to get edid\n");
-- 
2.17.1


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

* Re: [PATCH 1/5] drm: dw-hdmi: extract dw_hdmi_connector_update_edid()
  2019-09-01 16:14 ` [PATCH 1/5] drm: dw-hdmi: extract dw_hdmi_connector_update_edid() Jonas Karlman
@ 2019-09-02  8:05   ` Neil Armstrong
  0 siblings, 0 replies; 12+ messages in thread
From: Neil Armstrong @ 2019-09-02  8:05 UTC (permalink / raw)
  To: Jonas Karlman, Andrzej Hajda
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel

Hi Jonas,

On 01/09/2019 18:14, Jonas Karlman wrote:
> Extract code that updates EDID into a dw_hdmi_connector_update_edid()
> helper, it will be called from dw_hdmi_connector_detect().

Small nit, you should precise you add a bool to optionally add the modes.

Anyway:
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 521d689413c8..8ab214dc5ae7 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2171,7 +2171,8 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
>  }
>  
> -static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> +static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
> +					  bool add_modes)
>  {
>  	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
>  					     connector);
> @@ -2190,7 +2191,8 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>  		drm_connector_update_edid_property(connector, edid);
>  		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
> -		ret = drm_add_edid_modes(connector, edid);
> +		if (add_modes)
> +			ret = drm_add_edid_modes(connector, edid);
>  		kfree(edid);
>  	} else {
>  		dev_dbg(hdmi->dev, "failed to get edid\n");
> @@ -2199,6 +2201,11 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>  	return ret;
>  }
>  
> +static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> +{
> +	return dw_hdmi_connector_update_edid(connector, true);
> +}
> +
>  static void dw_hdmi_connector_force(struct drm_connector *connector)
>  {
>  	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> 


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

* Re: [PATCH 2/5] drm: dw-hdmi: move dw_hdmi_connector_detect()
  2019-09-01 16:14   ` [PATCH 2/5] drm: dw-hdmi: move dw_hdmi_connector_detect() Jonas Karlman
@ 2019-09-02  8:05     ` Neil Armstrong
  0 siblings, 0 replies; 12+ messages in thread
From: Neil Armstrong @ 2019-09-02  8:05 UTC (permalink / raw)
  To: Jonas Karlman, Andrzej Hajda
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel

On 01/09/2019 18:14, Jonas Karlman wrote:
> Move dw_hdmi_connector_detect() it will call dw_hdmi_connector_update_edid().
> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 30 +++++++++++------------
>  1 file changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 8ab214dc5ae7..91d86ddd6624 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2156,21 +2156,6 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
>  					  hdmi->rxsense);
>  }
>  
> -static enum drm_connector_status
> -dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
> -{
> -	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> -					     connector);
> -
> -	mutex_lock(&hdmi->mutex);
> -	hdmi->force = DRM_FORCE_UNSPECIFIED;
> -	dw_hdmi_update_power(hdmi);
> -	dw_hdmi_update_phy_mask(hdmi);
> -	mutex_unlock(&hdmi->mutex);
> -
> -	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
> -}
> -
>  static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
>  					  bool add_modes)
>  {
> @@ -2201,6 +2186,21 @@ static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
>  	return ret;
>  }
>  
> +static enum drm_connector_status
> +dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
> +{
> +	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> +					     connector);
> +
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->force = DRM_FORCE_UNSPECIFIED;
> +	dw_hdmi_update_power(hdmi);
> +	dw_hdmi_update_phy_mask(hdmi);
> +	mutex_unlock(&hdmi->mutex);
> +
> +	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
> +}
> +
>  static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>  {
>  	return dw_hdmi_connector_update_edid(connector, true);
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 4/5] Revert "drm/edid: make drm_edid_to_eld() static"
  2019-09-01 16:14   ` [PATCH 4/5] Revert "drm/edid: make drm_edid_to_eld() static" Jonas Karlman
@ 2019-09-02  8:07     ` Neil Armstrong
  0 siblings, 0 replies; 12+ messages in thread
From: Neil Armstrong @ 2019-09-02  8:07 UTC (permalink / raw)
  To: Jonas Karlman, Andrzej Hajda
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel

On 01/09/2019 18:14, Jonas Karlman wrote:
> drm_edid_to_eld() is needed to update stale connector ELD on HPD event.
> 
> This reverts part of commit 79436a1c9bcc ("drm/edid: make drm_edid_to_eld() static").

Why not a full revert ?

The documentation revert seems also relevant now

Neil

> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
>  drivers/gpu/drm/drm_edid.c | 5 +++--
>  include/drm/drm_edid.h     | 1 +
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 82a4ceed3fcf..47c409af0903 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4069,7 +4069,7 @@ static void clear_eld(struct drm_connector *connector)
>  	connector->audio_latency[1] = 0;
>  }
>  
> -/*
> +/**
>   * drm_edid_to_eld - build ELD from EDID
>   * @connector: connector corresponding to the HDMI/DP sink
>   * @edid: EDID to parse
> @@ -4077,7 +4077,7 @@ static void clear_eld(struct drm_connector *connector)
>   * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The
>   * HDCP and Port_ID ELD fields are left for the graphics driver to fill in.
>   */
> -static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
> +void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
>  {
>  	uint8_t *eld = connector->eld;
>  	u8 *cea;
> @@ -4162,6 +4162,7 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
>  	DRM_DEBUG_KMS("ELD size %d, SAD count %d\n",
>  		      drm_eld_size(eld), total_sad_count);
>  }
> +EXPORT_SYMBOL(drm_edid_to_eld);
>  
>  /**
>   * drm_edid_to_sad - extracts SADs from EDID
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index b9719418c3d2..49987818fe23 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -337,6 +337,7 @@ struct drm_connector;
>  struct drm_connector_state;
>  struct drm_display_mode;
>  
> +void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid);
>  int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
>  int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
>  int drm_av_sync_delay(struct drm_connector *connector,
> 


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

* Re: [PATCH 5/5] drm: dw-hdmi: update ELD on HPD event
  2019-09-01 16:14   ` [PATCH 5/5] drm: dw-hdmi: update ELD on HPD event Jonas Karlman
@ 2019-09-02  8:08     ` Neil Armstrong
  0 siblings, 0 replies; 12+ messages in thread
From: Neil Armstrong @ 2019-09-02  8:08 UTC (permalink / raw)
  To: Jonas Karlman, Andrzej Hajda
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel

On 01/09/2019 18:14, Jonas Karlman wrote:
> Update connector ELD on HPD event, fixes stale ELD when
> HDMI cable is unplugged/replugged or AVR is powered on/off.
> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 0f07be1b5914..0a8268b20561 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2178,6 +2178,8 @@ static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
>  		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>  		if (add_modes)
>  			ret = drm_add_edid_modes(connector, edid);
> +		else
> +			drm_edid_to_eld(connector, edid);
>  		kfree(edid);
>  	} else {
>  		dev_dbg(hdmi->dev, "failed to get edid\n");
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 3/5] drm: dw-hdmi: update CEC phys addr and EDID on HPD event
  2019-09-01 16:14   ` [PATCH 3/5] drm: dw-hdmi: update CEC phys addr and EDID on HPD event Jonas Karlman
@ 2019-09-02  8:10     ` Neil Armstrong
  2019-09-02 10:49       ` Jonas Karlman
  0 siblings, 1 reply; 12+ messages in thread
From: Neil Armstrong @ 2019-09-02  8:10 UTC (permalink / raw)
  To: Jonas Karlman, Andrzej Hajda
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel

On 01/09/2019 18:14, Jonas Karlman wrote:
> Update CEC phys addr and EDID on HPD event, fixes lost CEC phys addr and
> stale EDID when HDMI cable is unplugged/replugged or AVR is powered on/off.
> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 91d86ddd6624..0f07be1b5914 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2189,6 +2189,7 @@ static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
>  static enum drm_connector_status
>  dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> +	enum drm_connector_status status;
>  	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
>  					     connector);
>  
> @@ -2198,7 +2199,14 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  	dw_hdmi_update_phy_mask(hdmi);
>  	mutex_unlock(&hdmi->mutex);
>  
> -	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
> +	status = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
> +
> +	if (status == connector_status_connected)
> +		dw_hdmi_connector_update_edid(connector, false);
> +	else
> +		cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
> +
> +	return status;
>  }
>  
>  static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> @@ -2438,12 +2446,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  		dw_hdmi_setup_rx_sense(hdmi,
>  				       phy_stat & HDMI_PHY_HPD,
>  				       phy_stat & HDMI_PHY_RX_SENSE);
> -
> -		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
> -			mutex_lock(&hdmi->cec_notifier_mutex);
> -			cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
> -			mutex_unlock(&hdmi->cec_notifier_mutex);
> -		}
>  	}
>  
>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
> 

Won't it possibly trigger twice edid readouts on each HPD event,
one for CEC and one for modes ? It seems sane but not very efficient to me...

Anyway:
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 3/5] drm: dw-hdmi: update CEC phys addr and EDID on HPD event
  2019-09-02  8:10     ` Neil Armstrong
@ 2019-09-02 10:49       ` Jonas Karlman
  0 siblings, 0 replies; 12+ messages in thread
From: Jonas Karlman @ 2019-09-02 10:49 UTC (permalink / raw)
  To: Neil Armstrong, Andrzej Hajda
  Cc: David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, Laurent Pinchart, Jernej Skrabec, Hans Verkuil,
	Jerome Brunet, dri-devel, linux-kernel

On 2019-09-02 10:10, Neil Armstrong wrote:
> On 01/09/2019 18:14, Jonas Karlman wrote:
>> Update CEC phys addr and EDID on HPD event, fixes lost CEC phys addr and
>> stale EDID when HDMI cable is unplugged/replugged or AVR is powered on/off.
>>
>> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
>> ---
>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 16 +++++++++-------
>>  1 file changed, 9 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> index 91d86ddd6624..0f07be1b5914 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> @@ -2189,6 +2189,7 @@ static int dw_hdmi_connector_update_edid(struct drm_connector *connector,
>>  static enum drm_connector_status
>>  dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>>  {
>> +	enum drm_connector_status status;
>>  	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
>>  					     connector);
>>  
>> @@ -2198,7 +2199,14 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>>  	dw_hdmi_update_phy_mask(hdmi);
>>  	mutex_unlock(&hdmi->mutex);
>>  
>> -	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
>> +	status = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
>> +
>> +	if (status == connector_status_connected)
>> +		dw_hdmi_connector_update_edid(connector, false);
>> +	else
>> +		cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
>> +
>> +	return status;
>>  }
>>  
>>  static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>> @@ -2438,12 +2446,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>>  		dw_hdmi_setup_rx_sense(hdmi,
>>  				       phy_stat & HDMI_PHY_HPD,
>>  				       phy_stat & HDMI_PHY_RX_SENSE);
>> -
>> -		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
>> -			mutex_lock(&hdmi->cec_notifier_mutex);
>> -			cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
>> -			mutex_unlock(&hdmi->cec_notifier_mutex);
>> -		}
>>  	}
>>  
>>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>>
> Won't it possibly trigger twice edid readouts on each HPD event,
> one for CEC and one for modes ? It seems sane but not very efficient to me...

Yes there may be EDID readout twice with this change in case both detect and get_modes gets called.
Guess we could save the EDID readout in detect and reuse it in get_modes or similar?

The issue observed is that CEC phys addr never gets updated after an invalidation (HPD)
until get_modes is called, when TV/AVR triggers an EDID refresh using a 100ms HPD pulse
or an AVR is powered on/off the CEC phys addr, EDID and ELD never gets refreshed as
only detect is called and not get_modes.

Regards,
Jonas

>
> Anyway:
> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>


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

end of thread, other threads:[~2019-09-02 10:49 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-01 16:13 [PATCH 0/5] drm: dw-hdmi: update CEC phys addr, EDID and ELD on HPD event Jonas Karlman
2019-09-01 16:14 ` [PATCH 1/5] drm: dw-hdmi: extract dw_hdmi_connector_update_edid() Jonas Karlman
2019-09-02  8:05   ` Neil Armstrong
     [not found] ` <20190901161426.1606-1-jonas@kwiboo.se>
2019-09-01 16:14   ` [PATCH 2/5] drm: dw-hdmi: move dw_hdmi_connector_detect() Jonas Karlman
2019-09-02  8:05     ` Neil Armstrong
2019-09-01 16:14   ` [PATCH 3/5] drm: dw-hdmi: update CEC phys addr and EDID on HPD event Jonas Karlman
2019-09-02  8:10     ` Neil Armstrong
2019-09-02 10:49       ` Jonas Karlman
2019-09-01 16:14   ` [PATCH 4/5] Revert "drm/edid: make drm_edid_to_eld() static" Jonas Karlman
2019-09-02  8:07     ` Neil Armstrong
2019-09-01 16:14   ` [PATCH 5/5] drm: dw-hdmi: update ELD on HPD event Jonas Karlman
2019-09-02  8:08     ` Neil Armstrong

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