[PATCH v4 26/39] drm/msm/dp: abstract out the dp_display stream helpers to accept a panel

Yongxing Mou
2026-04-10T09:36:06Z

From: Abhinav Kumar <quic_abhinavk@quicinc.com>

Currently the dp_display bridge helpers, in particular the
dp_display_enable()/dp_display_disable() use the cached panel.
To be able to re-use these helpers for MST use-case abstract the
helpers to use the panel which is passed in to them.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 117 ++++++++++++++++++++++++------------
drivers/gpu/drm/msm/dp/dp_display.h | 12 ++++
2 files changed, 91 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 88a078e53dc1..33d8539afee7 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -635,12 +635,14 @@ static int msm_dp_display_set_mode(struct msm_dp *msm_dp_display,
return 0;
}

-static int msm_dp_display_prepare(struct msm_dp_display_private *dp)
+int msm_dp_display_prepare(struct msm_dp *msm_dp_display)
{
- struct msm_dp *msm_dp_display = &dp->msm_dp_display;
+ struct msm_dp_display_private *dp;
int rc = 0;
bool force_link_train = false;

+ dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
drm_dbg_dp(dp->drm_dev, "sink_count=%d\n", dp->link->sink_count);

if (msm_dp_display->is_edp)
@@ -680,7 +682,7 @@ static int msm_dp_display_enable(struct msm_dp_display_private *dp,
return 0;
}

- rc = msm_dp_ctrl_on_stream(dp->ctrl, dp->panel);
+ rc = msm_dp_ctrl_on_stream(dp->ctrl, msm_dp_panel);
if (!rc)
msm_dp_display->power_on = true;

@@ -738,18 +740,6 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp,

msm_dp_ctrl_off_pixel_clk(dp->ctrl, msm_dp_panel->stream_id);

- /* dongle is still connected but sinks are disconnected */
- if (dp->link->sink_count == 0)
- msm_dp_link_psm_config(dp->link, &msm_dp_panel->link_info, true);
-
- msm_dp_ctrl_off_link(dp->ctrl);
-
- if (dp->link->sink_count == 0)
- /* re-init the PHY so that we can listen to Dongle disconnect */
- msm_dp_ctrl_reinit_phy(dp->ctrl);
- else
- msm_dp_display_host_phy_exit(dp);
-
msm_dp_display->power_on = false;

drm_dbg_dp(dp->drm_dev, "sink count: %d\n", dp->link->sink_count);
@@ -1495,76 +1485,116 @@ int msm_dp_modeset_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
return 0;
}

-void msm_dp_display_atomic_prepare(struct msm_dp *msm_dp_display,
- struct drm_atomic_state *state)
+int msm_dp_display_set_mode_helper(struct msm_dp *msm_dp_display,
+ struct drm_atomic_state *state,
+ struct drm_encoder *drm_encoder,
+ struct msm_dp_panel *msm_dp_panel)
{
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
+
+ crtc = drm_atomic_get_new_crtc_for_encoder(state, drm_encoder);
+ if (!crtc)
+ return 0;
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+
+ return msm_dp_display_set_mode(msm_dp_display, &crtc_state->adjusted_mode, msm_dp_panel);
+}
+
+void msm_dp_display_atomic_prepare(struct msm_dp *msm_dp_display,
+ struct drm_atomic_state *state)
+{
int rc = 0;
struct msm_dp_display_private *dp;

dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);

- crtc = drm_atomic_get_new_crtc_for_encoder(state,
- msm_dp_display->bridge->encoder);
- if (!crtc)
- return;
- crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
-
- rc = msm_dp_display_set_mode(msm_dp_display, &crtc_state->adjusted_mode, dp->panel);
+ rc = msm_dp_display_set_mode_helper(msm_dp_display, state,
+ msm_dp_display->bridge->encoder, dp->panel);
if (rc) {
DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
return;
}

- rc = msm_dp_display_prepare(dp);
+ rc = msm_dp_display_prepare(msm_dp_display);
if (rc)
DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
}

-void msm_dp_display_atomic_enable(struct msm_dp *msm_dp_display)
+void msm_dp_display_enable_helper(struct msm_dp *msm_dp_display, struct msm_dp_panel *msm_dp_panel)
{
struct msm_dp_display_private *dp;
int rc = 0;

dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);

- msm_dp_display_set_stream_info(msm_dp_display, dp->panel, 0, 0, 0, 0);
-
- rc = msm_dp_display_enable(dp, dp->panel);
+ rc = msm_dp_display_enable(dp, msm_dp_panel);
if (rc)
DRM_ERROR("DP display enable failed, rc=%d\n", rc);

rc = msm_dp_display_post_enable(msm_dp_display);
if (rc) {
DRM_ERROR("DP display post enable failed, rc=%d\n", rc);
- msm_dp_display_disable(dp, dp->panel);
+ msm_dp_display_disable(dp, msm_dp_panel);
}

drm_dbg_dp(msm_dp_display->drm_dev, "type=%d Done\n", msm_dp_display->connector_type);
}

-void msm_dp_display_atomic_disable(struct msm_dp *msm_dp_display)
+void msm_dp_display_atomic_enable(struct msm_dp *msm_dp_display)
{
struct msm_dp_display_private *dp;

dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);

- msm_dp_ctrl_push_idle(dp->ctrl, dp->panel);
+ msm_dp_display_set_stream_info(msm_dp_display, dp->panel, 0, 0, 0, 0);
+
+ msm_dp_display_enable_helper(msm_dp_display, dp->panel);
+}
+
+void msm_dp_display_disable_helper(struct msm_dp *msm_dp_display,
+ struct msm_dp_panel *msm_dp_panel)
+{
+ struct msm_dp_display_private *dp;
+
+ dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+ msm_dp_ctrl_push_idle(dp->ctrl, msm_dp_panel);
msm_dp_ctrl_mst_stream_channel_slot_setup(dp->ctrl);
msm_dp_ctrl_mst_send_act(dp->ctrl);
}

-static void msm_dp_display_unprepare(struct msm_dp_display_private *dp)
+void msm_dp_display_atomic_disable(struct msm_dp *msm_dp_display)
{
- struct msm_dp *msm_dp_display = &dp->msm_dp_display;
+ struct msm_dp_display_private *dp;

- pm_runtime_put_sync(&msm_dp_display->pdev->dev);
+ dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+ msm_dp_display_disable_helper(msm_dp_display, dp->panel);
+}
+
+void msm_dp_display_unprepare(struct msm_dp *msm_dp_display)
+{
+ struct msm_dp_display_private *dp;
+
+ dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);

- drm_dbg_dp(dp->drm_dev, "type=%d Done\n", msm_dp_display->connector_type);
+ /* dongle is still connected but sinks are disconnected */
+ if (dp->link->sink_count == 0)
+ msm_dp_link_psm_config(dp->link, &dp->panel->link_info, true);
+
+ msm_dp_ctrl_off_link(dp->ctrl);
+
+ /* re-init the PHY so that we can listen to Dongle disconnect */
+ if (dp->link->sink_count == 0)
+ msm_dp_ctrl_reinit_phy(dp->ctrl);
+ else
+ msm_dp_display_host_phy_exit(dp);
+
+ pm_runtime_put_sync(&msm_dp_display->pdev->dev);
}

-void msm_dp_display_atomic_post_disable(struct msm_dp *dp)
+void msm_dp_display_atomic_post_disable_helper(struct msm_dp *dp, struct msm_dp_panel *msm_dp_panel)
{
struct msm_dp_display_private *msm_dp_display;

@@ -1575,7 +1605,18 @@ void msm_dp_display_atomic_post_disable(struct msm_dp *dp)

msm_dp_display_audio_notify_disable(msm_dp_display);

- msm_dp_display_disable(msm_dp_display, msm_dp_display->panel);
+ msm_dp_display_disable(msm_dp_display, msm_dp_panel);
+
+ drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
+}
+
+void msm_dp_display_atomic_post_disable(struct msm_dp *msm_dp_display)
+{
+ struct msm_dp_display_private *dp;
+
+ dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+ msm_dp_display_atomic_post_disable_helper(msm_dp_display, dp->panel);

msm_dp_display_unprepare(msm_dp_display);
}
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index 0ccdddb223c8..0ede5505be58 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -46,5 +46,17 @@ enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
int msm_dp_display_set_stream_info(struct msm_dp *msm_dp_display, struct msm_dp_panel *panel,
enum msm_dp_stream_id stream_id,
u32 start_slot, u32 num_slots, u32 pbn);
+void msm_dp_display_enable_helper(struct msm_dp *msm_dp_display,
+ struct msm_dp_panel *msm_dp_panel);
+void msm_dp_display_disable_helper(struct msm_dp *msm_dp_display,
+ struct msm_dp_panel *msm_dp_panel);
+void msm_dp_display_atomic_post_disable_helper(struct msm_dp *msm_dp_display,
+ struct msm_dp_panel *msm_dp_panel);
+int msm_dp_display_set_mode_helper(struct msm_dp *msm_dp_display,
+ struct drm_atomic_state *state,
+ struct drm_encoder *drm_encoder,
+ struct msm_dp_panel *msm_dp_panel);
+int msm_dp_display_prepare(struct msm_dp *msm_dp_display);
+void msm_dp_display_unprepare(struct msm_dp *dp);

#endif /* _DP_DISPLAY_H_ */

--
2.43.0