[PATCH v4 10/13] drm/msm/dp: Rely on hpd_enable/disable callbacks

Dmitry Baryshkov dmitry.baryshkov at linaro.org
Mon Dec 5 21:11:22 UTC 2022



On 5 December 2022 20:44:30 GMT+03:00, Bjorn Andersson <quic_bjorande at quicinc.com> wrote:
>From: Bjorn Andersson <bjorn.andersson at linaro.org>
>
>The DisplayPort controller's internal HPD interrupt handling is used for
>cases where the HPD signal is connected to a GPIO which is pinmuxed into
>the DisplayPort controller. In other configurations the HPD notification
>might be delivered by the DRM framework from an associated bridge.
>
>This difference is not appropriately represented by the "is_edp"
>boolean, but is properly represented by the frameworks invocation of the
>hpd_enable() and hpd_disable() callbacks. Switch the current condition
>to rely on these callbacks instead.
>
>This ensures appropriate handling of the three cases; no bridge
>connected, a bridge without DRM_BRIDGE_OP_HPD and a bridge with
>DRM_BRIDGE_OP_HPD.
>
>Signed-off-by: Bjorn Andersson <bjorn.andersson at linaro.org>
>Signed-off-by: Bjorn Andersson <quic_bjorande at quicinc.com>
>---
>
>Worth mentioning, I did look into moving the HPD enablement/disablement
>completely into these new callbacks, but that affect the entire power
>management model of the driver, so I think it's worth to tackle that in
>subsequent changes. It seems also reasonable to expect that we by such
>modifications could leave the block unclocked until the external HPD
>notification arrives...

I see... I still suppose this is the way to go in the long term.

For now:

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

>
>Changes since v3:
>- Introduced reliance on hpd_enable/disable callbacks instead of next_bridge
>
> drivers/gpu/drm/msm/dp/dp_display.c | 35 ++++++++++++++++++++---------
> drivers/gpu/drm/msm/dp/dp_display.h |  1 +
> drivers/gpu/drm/msm/dp/dp_drm.c     |  2 ++
> drivers/gpu/drm/msm/dp/dp_drm.h     |  2 ++
> 4 files changed, 30 insertions(+), 10 deletions(-)
>
>diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
>index bb92c33beff8..3e464c33ff11 100644
>--- a/drivers/gpu/drm/msm/dp/dp_display.c
>+++ b/drivers/gpu/drm/msm/dp/dp_display.c
>@@ -610,7 +610,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
> 	}
> 
> 	/* enable HDP irq_hpd/replug interrupt */
>-	if (!dp->dp_display.is_edp)
>+	if (dp->dp_display.internal_hpd)
> 		dp_catalog_hpd_config_intr(dp->catalog,
> 					   DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK,
> 					   true);
>@@ -653,7 +653,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
> 			dp->dp_display.connector_type, state);
> 
> 	/* disable irq_hpd/replug interrupts */
>-	if (!dp->dp_display.is_edp)
>+	if (dp->dp_display.internal_hpd)
> 		dp_catalog_hpd_config_intr(dp->catalog,
> 					   DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK,
> 					   false);
>@@ -682,7 +682,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
> 	}
> 
> 	/* disable HPD plug interrupts */
>-	if (!dp->dp_display.is_edp)
>+	if (dp->dp_display.internal_hpd)
> 		dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false);
> 
> 	/*
>@@ -701,7 +701,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
> 	dp_display_handle_plugged_change(&dp->dp_display, false);
> 
> 	/* enable HDP plug interrupt to prepare for next plugin */
>-	if (!dp->dp_display.is_edp)
>+	if (dp->dp_display.internal_hpd)
> 		dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true);
> 
> 	drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
>@@ -1086,8 +1086,8 @@ static void dp_display_config_hpd(struct dp_display_private *dp)
> 	dp_display_host_init(dp);
> 	dp_catalog_ctrl_hpd_config(dp->catalog);
> 
>-	/* Enable plug and unplug interrupts only for external DisplayPort */
>-	if (!dp->dp_display.is_edp)
>+	/* Enable plug and unplug interrupts only if requested */
>+	if (dp->dp_display.internal_hpd)
> 		dp_catalog_hpd_config_intr(dp->catalog,
> 				DP_DP_HPD_PLUG_INT_MASK |
> 				DP_DP_HPD_UNPLUG_INT_MASK,
>@@ -1379,8 +1379,7 @@ static int dp_pm_resume(struct device *dev)
> 
> 	dp_catalog_ctrl_hpd_config(dp->catalog);
> 
>-
>-	if (!dp->dp_display.is_edp)
>+	if (dp->dp_display.internal_hpd)
> 		dp_catalog_hpd_config_intr(dp->catalog,
> 				DP_DP_HPD_PLUG_INT_MASK |
> 				DP_DP_HPD_UNPLUG_INT_MASK,
>@@ -1778,6 +1777,22 @@ void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
> 		!!(dp_display->dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC);
> }
> 
>+void dp_bridge_hpd_enable(struct drm_bridge *bridge)
>+{
>+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
>+	struct msm_dp *dp_display = dp_bridge->dp_display;
>+
>+	dp_display->internal_hpd = true;
>+}
>+
>+void dp_bridge_hpd_disable(struct drm_bridge *bridge)
>+{
>+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
>+	struct msm_dp *dp_display = dp_bridge->dp_display;
>+
>+	dp_display->internal_hpd = false;
>+}
>+
> void dp_bridge_hpd_notify(struct drm_bridge *bridge,
> 			  enum drm_connector_status status)
> {
>@@ -1785,8 +1800,8 @@ void dp_bridge_hpd_notify(struct drm_bridge *bridge,
> 	struct msm_dp *dp_display = dp_bridge->dp_display;
> 	struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
> 
>-	/* Without next_bridge interrupts are handled by the DP core directly */
>-	if (!dp_display->next_bridge)
>+	/* Plug events are generated by the dp_display_irq_handler() */
>+	if (dp_display->internal_hpd)
> 		return;
> 
> 	if (!dp->core_initialized) {
>diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
>index dcedf021f7fe..371337d0fae2 100644
>--- a/drivers/gpu/drm/msm/dp/dp_display.h
>+++ b/drivers/gpu/drm/msm/dp/dp_display.h
>@@ -21,6 +21,7 @@ struct msm_dp {
> 	bool power_on;
> 	unsigned int connector_type;
> 	bool is_edp;
>+	bool internal_hpd;
> 
> 	hdmi_codec_plugged_cb plugged_cb;
> 
>diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
>index 3898366ebd5e..275370f21115 100644
>--- a/drivers/gpu/drm/msm/dp/dp_drm.c
>+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>@@ -102,6 +102,8 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
> 	.get_modes    = dp_bridge_get_modes,
> 	.detect       = dp_bridge_detect,
> 	.atomic_check = dp_bridge_atomic_check,
>+	.hpd_enable   = dp_bridge_hpd_enable,
>+	.hpd_disable  = dp_bridge_hpd_disable,
> 	.hpd_notify   = dp_bridge_hpd_notify,
> };
> 
>diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
>index 79e6b2cf2d25..250f7c66201f 100644
>--- a/drivers/gpu/drm/msm/dp/dp_drm.h
>+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
>@@ -32,6 +32,8 @@ enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
> void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
> 			const struct drm_display_mode *mode,
> 			const struct drm_display_mode *adjusted_mode);
>+void dp_bridge_hpd_enable(struct drm_bridge *bridge);
>+void dp_bridge_hpd_disable(struct drm_bridge *bridge);
> void dp_bridge_hpd_notify(struct drm_bridge *bridge,
> 			  enum drm_connector_status status);
> 

-- 
With best wishes
Dmitry


More information about the dri-devel mailing list