Re: [PATCH v4 13/39] drm/msm/dp: introduce stream_id for each DP panel
From: Yongxing Mou
Date: Tue May 19 2026 - 04:37:19 EST
On 4/12/2026 1:55 AM, Dmitry Baryshkov wrote:
On Fri, Apr 10, 2026 at 05:33:48PM +0800, Yongxing Mou wrote:Got it. will update next patch.
From: Abhinav Kumar <quic_abhinavk@xxxxxxxxxxx>
With MST, each DP controller can handle multiple streams.
There shall be one dp_panel for each stream but the dp_display
object shall be shared among them. To represent this abstraction,
create a stream_id for each DP panel which shall be set by the
MST stream. For SST, default this to stream 0.
Use the stream ID to control the pixel clock of that respective
stream by extending the clock handles and state tracking of the
DP pixel clock to an array of max supported streams. The maximum
streams currently is 4.
Please mention that panels are going to be dynamically assigned to
actual stream IDs.
For MST path, we pass panel to the func. For SST case, we still need to pass the sst panel to func, in here it is ctrl->panel.. in dp_display, it is dp_display->panel.
Signed-off-by: Abhinav Kumar <quic_abhinavk@xxxxxxxxxxx>
Signed-off-by: Yongxing Mou <yongxing.mou@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/msm/dp/dp_ctrl.c | 57 +++++++++++++++++++++++--------------
drivers/gpu/drm/msm/dp/dp_ctrl.h | 2 +-
drivers/gpu/drm/msm/dp/dp_display.c | 24 ++++++++++++++--
drivers/gpu/drm/msm/dp/dp_display.h | 2 ++
drivers/gpu/drm/msm/dp/dp_panel.h | 11 +++++++
5 files changed, 71 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index 120ec00884e5..fb6396727628 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -127,7 +127,7 @@ struct msm_dp_ctrl_private {
unsigned int num_link_clks;
struct clk_bulk_data *link_clks;
- struct clk *pixel_clk;
+ struct clk *pixel_clk[DP_STREAM_MAX];
union phy_configure_opts phy_opts;
@@ -139,7 +139,7 @@ struct msm_dp_ctrl_private {
bool core_clks_on;
bool link_clks_on;
- bool stream_clks_on;
+ bool stream_clks_on[DP_STREAM_MAX];
};
static inline u32 msm_dp_read_ahb(const struct msm_dp_ctrl_private *ctrl, u32 offset)
@@ -2176,39 +2176,40 @@ static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl)
return success;
}
-static int msm_dp_ctrl_on_pixel_clk(struct msm_dp_ctrl_private *ctrl, unsigned long pixel_rate)
+static int msm_dp_ctrl_on_pixel_clk(struct msm_dp_ctrl_private *ctrl, unsigned long pixel_rate,
+ enum msm_dp_stream_id stream_id)
{
int ret;
- ret = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);
+ ret = clk_set_rate(ctrl->pixel_clk[stream_id], pixel_rate * 1000);
if (ret) {
DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
return ret;
}
- if (ctrl->stream_clks_on) {
+ if (ctrl->stream_clks_on[stream_id]) {
drm_dbg_dp(ctrl->drm_dev, "pixel clks already enabled\n");
} else {
- ret = clk_prepare_enable(ctrl->pixel_clk);
+ ret = clk_prepare_enable(ctrl->pixel_clk[stream_id]);
if (ret) {
DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
return ret;
}
- ctrl->stream_clks_on = true;
+ ctrl->stream_clks_on[stream_id] = true;
}
return ret;
}
-void msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl *msm_dp_ctrl)
+void msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl *msm_dp_ctrl, enum msm_dp_stream_id stream_id)
{
struct msm_dp_ctrl_private *ctrl;
ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
- if (ctrl->stream_clks_on) {
- clk_disable_unprepare(ctrl->pixel_clk);
- ctrl->stream_clks_on = false;
+ if (ctrl->stream_clks_on[stream_id]) {
+ clk_disable_unprepare(ctrl->pixel_clk[stream_id]);
+ ctrl->stream_clks_on[stream_id] = false;
}
}
@@ -2228,7 +2229,7 @@ static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl
* running. Add the global reset just before disabling the
* link clocks and core clocks.
*/
- msm_dp_ctrl_off_pixel_clk(&ctrl->msm_dp_ctrl);
+ msm_dp_ctrl_off_pixel_clk(&ctrl->msm_dp_ctrl, ctrl->panel->stream_id);
Why are we using ctrl->panel again here for the stream-related
functions? Didn't you got rid of its usage few patches ago?
msm_dp_ctrl_off_link(&ctrl->msm_dp_ctrl);
ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl);
@@ -2238,7 +2239,7 @@ static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl
}
pixel_rate = ctrl->panel->msm_dp_mode.drm_mode.clock;
- ret = msm_dp_ctrl_on_pixel_clk(ctrl, pixel_rate);
+ ret = msm_dp_ctrl_on_pixel_clk(ctrl, pixel_rate, ctrl->panel->stream_id);
And here...
msm_dp_ctrl_send_phy_test_pattern(ctrl);
@@ -1451,6 +1469,8 @@ void msm_dp_display_atomic_enable(struct msm_dp *msm_dp_display)
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);
DP_STREAM_0
+
rc = msm_dp_display_enable(dp);
if (rc)
DRM_ERROR("DP display enable failed, rc=%d\n", rc);