Message ID | 20221207220012.16529-9-quic_bjorande@quicinc.com |
---|---|
State | New |
Headers | show |
Series | drm/msm: Add SC8280XP support | expand |
On 12/7/2022 2:00 PM, Bjorn Andersson wrote: > From: Bjorn Andersson <bjorn.andersson@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@linaro.org> > Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Kuogee Hsieh <quic_khsieh@quicinc.com> > --- > > Changes since v4: > - Reordered the hpd_enable/disable patch earlier > - Squashed in internal_hpd conditional changes into the same patch > > drivers/gpu/drm/msm/dp/dp_display.c | 40 +++++++++++++++++++++-------- > 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, 35 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c > index 666b45c8ab80..095adf528e43 100644 > --- a/drivers/gpu/drm/msm/dp/dp_display.c > +++ b/drivers/gpu/drm/msm/dp/dp_display.c > @@ -610,8 +610,10 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) > } > > /* enable HDP irq_hpd/replug interrupt */ > - dp_catalog_hpd_config_intr(dp->catalog, > - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, true); > + 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); > > drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", > dp->dp_display.connector_type, state); > @@ -651,8 +653,10 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) > dp->dp_display.connector_type, state); > > /* disable irq_hpd/replug interrupts */ > - dp_catalog_hpd_config_intr(dp->catalog, > - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, false); > + 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); > > /* unplugged, no more irq_hpd handle */ > dp_del_event(dp, EV_IRQ_HPD_INT); > @@ -678,7 +682,8 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) > } > > /* disable HPD plug interrupts */ > - dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false); > + if (dp->dp_display.internal_hpd) > + dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false); > > /* > * We don't need separate work for disconnect as > @@ -696,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", > @@ -1081,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, > @@ -1374,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, > @@ -1772,3 +1776,19 @@ void dp_bridge_mode_set(struct drm_bridge *drm_bridge, > dp_display->dp_mode.h_active_low = > !!(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; > +} > 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 6db82f9b03af..9d03b6ee3c41 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, > }; > > struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, > diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h > index 82035dbb0578..1f871b555006 100644 > --- a/drivers/gpu/drm/msm/dp/dp_drm.h > +++ b/drivers/gpu/drm/msm/dp/dp_drm.h > @@ -32,5 +32,7 @@ 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); > > #endif /* _DP_DRM_H_ */
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 666b45c8ab80..095adf528e43 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -610,8 +610,10 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) } /* enable HDP irq_hpd/replug interrupt */ - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, true); + 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); drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); @@ -651,8 +653,10 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) dp->dp_display.connector_type, state); /* disable irq_hpd/replug interrupts */ - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, false); + 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); /* unplugged, no more irq_hpd handle */ dp_del_event(dp, EV_IRQ_HPD_INT); @@ -678,7 +682,8 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) } /* disable HPD plug interrupts */ - dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false); + if (dp->dp_display.internal_hpd) + dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false); /* * We don't need separate work for disconnect as @@ -696,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", @@ -1081,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, @@ -1374,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, @@ -1772,3 +1776,19 @@ void dp_bridge_mode_set(struct drm_bridge *drm_bridge, dp_display->dp_mode.h_active_low = !!(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; +} 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 6db82f9b03af..9d03b6ee3c41 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, }; struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h index 82035dbb0578..1f871b555006 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.h +++ b/drivers/gpu/drm/msm/dp/dp_drm.h @@ -32,5 +32,7 @@ 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); #endif /* _DP_DRM_H_ */