On Mon, Aug 25, 2025 at 10:16:02PM +0800, Yongxing Mou wrote: > To support 4-stream MST, the link clocks for stream 3 and stream 4 > are controlled by MST_2_LCLK and MST_3_LCLK. These clocks share the > same register definitions but use different base addresses. > > This patch adds catalog support to enable programming of these blocks. > > Signed-off-by: Yongxing Mou <yongxing....@oss.qualcomm.com> > --- > drivers/gpu/drm/msm/dp/dp_ctrl.c | 82 ++++++++++++++++++--- > drivers/gpu/drm/msm/dp/dp_ctrl.h | 4 +- > drivers/gpu/drm/msm/dp/dp_display.c | 24 ++++++- > drivers/gpu/drm/msm/dp/dp_panel.c | 138 > ++++++++++++++++++++++++++++++------ > drivers/gpu/drm/msm/dp/dp_panel.h | 4 +- > drivers/gpu/drm/msm/dp/dp_reg.h | 14 ++++ > 6 files changed, 230 insertions(+), 36 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c > b/drivers/gpu/drm/msm/dp/dp_ctrl.c > index > b8b6a09966aed96f705bdd54cb16ea63e5f0141f..608a1a077301b2ef3c77c271d873bb4364abe779 > 100644 > --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c > +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c > @@ -118,6 +118,8 @@ struct msm_dp_ctrl_private { > struct msm_dp_link *link; > void __iomem *ahb_base; > void __iomem *link_base; > + void __iomem *mst2link_base; > + void __iomem *mst3link_base; > > struct phy *phy; > > @@ -172,6 +174,40 @@ static inline void msm_dp_write_link(struct > msm_dp_ctrl_private *ctrl, > writel(data, ctrl->link_base + offset); > } > > +static inline u32 msm_dp_read_mstlink(struct msm_dp_ctrl_private *ctrl, > + enum msm_dp_stream_id stream_id, u32 > offset) > +{ > + switch (stream_id) { > + case DP_STREAM_2: > + return readl_relaxed(ctrl->mst2link_base + offset); > + case DP_STREAM_3: > + return readl_relaxed(ctrl->mst3link_base + offset); > + default: > + DRM_ERROR("error stream_id\n"); > + return 0;
I'd totally prefer having a single set of wrappers which can handle all 4 streams. Having separate call sequences is not a good idea and it makes it hard to change / extend it. > + } > +} > + > +static inline void msm_dp_write_mstlink(struct msm_dp_ctrl_private *ctrl, > + enum msm_dp_stream_id stream_id, u32 offset, u32 > data) > +{ > + /* > + * To make sure link reg writes happens before any other operation, > + * this function uses writel() instread of writel_relaxed() > + */ > + switch (stream_id) { > + case DP_STREAM_2: > + writel(data, ctrl->mst2link_base + offset); > + break; > + case DP_STREAM_3: > + writel(data, ctrl->mst3link_base + offset); > + break; > + default: > + DRM_ERROR("error stream_id\n"); > + break; > + } > +} > + > static int msm_dp_aux_link_configure(struct drm_dp_aux *aux, > struct msm_dp_link_info *link) > { > @@ -386,7 +422,11 @@ static void msm_dp_ctrl_config_ctrl_streams(struct > msm_dp_ctrl_private *ctrl, > u32 config = 0, tbd; > u32 reg_offset = 0; > > - config = msm_dp_read_link(ctrl, REG_DP_CONFIGURATION_CTRL); > + if (msm_dp_panel->stream_id < DP_STREAM_2) > + config = msm_dp_read_link(ctrl, REG_DP_CONFIGURATION_CTRL); > + > + if (msm_dp_panel->stream_id == DP_STREAM_1) > + reg_offset = REG_DP1_CONFIGURATION_CTRL - > REG_DP_CONFIGURATION_CTRL; > > if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420) > config |= DP_CONFIGURATION_CTRL_RGB_YUV; /* YUV420 */ > @@ -401,8 +441,11 @@ static void msm_dp_ctrl_config_ctrl_streams(struct > msm_dp_ctrl_private *ctrl, > > drm_dbg_dp(ctrl->drm_dev, "stream DP_CONFIGURATION_CTRL=0x%x\n", > config); > > - if (msm_dp_panel->stream_id == DP_STREAM_1) > - reg_offset = REG_DP1_CONFIGURATION_CTRL - > REG_DP_CONFIGURATION_CTRL; > + if (msm_dp_panel->stream_id > DP_STREAM_1) > + msm_dp_write_mstlink(ctrl, msm_dp_panel->stream_id, > + REG_DP_MSTLINK_CONFIGURATION_CTRL, config); > + else > + msm_dp_write_link(ctrl, REG_DP_CONFIGURATION_CTRL + reg_offset, > config); > } > > static void msm_dp_ctrl_config_ctrl_link(struct msm_dp_ctrl_private *ctrl) [...] > diff --git a/drivers/gpu/drm/msm/dp/dp_reg.h b/drivers/gpu/drm/msm/dp/dp_reg.h > index > 43a9ce0539906e1f185abf250fdf161e462d9645..a806d397ff9d9ad3830b1f539614bffcc955a786 > 100644 > --- a/drivers/gpu/drm/msm/dp/dp_reg.h > +++ b/drivers/gpu/drm/msm/dp/dp_reg.h > @@ -142,6 +142,7 @@ > > #define REG_DP_CONFIGURATION_CTRL (0x00000008) > #define REG_DP1_CONFIGURATION_CTRL (0x00000400) > +#define REG_DP_MSTLINK_CONFIGURATION_CTRL (0x00000034) Please don't mix registers from different register spaces, it's confusing. > #define DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK (0x00000001) > #define DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN (0x00000002) > #define DP_CONFIGURATION_CTRL_P_INTERLACED (0x00000004) > @@ -163,12 +164,19 @@ > #define REG_DP1_SOFTWARE_MVID (0x00000414) > #define REG_DP1_SOFTWARE_NVID (0x00000418) > #define REG_DP1_TOTAL_HOR_VER (0x0000041C) > +#define REG_MSTLINK_SOFTWARE_MVID (0x00000040) > +#define REG_MSTLINK_SOFTWARE_NVID (0x00000044) > +#define REG_DP_MSTLINK_TOTAL_HOR_VER (0x00000048) > #define REG_DP_START_HOR_VER_FROM_SYNC (0x00000020) > +#define REG_DP_MSTLINK_START_HOR_VER_FROM_SYNC (0x0000004C) > #define REG_DP_HSYNC_VSYNC_WIDTH_POLARITY (0x00000024) > +#define REG_DP_MSTLINK_HSYNC_VSYNC_WIDTH_POLARITY (0x00000050) > #define REG_DP_ACTIVE_HOR_VER (0x00000028) > +#define REG_DP_MSTLINK_ACTIVE_HOR_VER (0x00000054) > > #define REG_DP_MISC1_MISC0 (0x0000002C) > #define REG_DP1_MISC1_MISC0 (0x0000042C) > +#define REG_DP_MSTLINK_MISC1_MISC0 (0x00000058) > #define DP_MISC0_SYNCHRONOUS_CLK (0x00000001) > #define DP_MISC0_COLORIMETRY_CFG_SHIFT (0x00000001) > #define DP_MISC0_TEST_BITS_DEPTH_SHIFT (0x00000005) > @@ -236,9 +244,11 @@ > > #define MMSS_DP_SDP_CFG (0x00000228) > #define MMSS_DP1_SDP_CFG (0x000004E0) > +#define MMSS_DP_MSTLINK_SDP_CFG (0x0000010c) > #define GEN0_SDP_EN (0x00020000) > #define MMSS_DP_SDP_CFG2 (0x0000022C) > #define MMSS_DP1_SDP_CFG2 (0x000004E4) > +#define MMSS_DP_MSTLINK_SDP_CFG2 (0x0000011c) > #define MMSS_DP_AUDIO_TIMESTAMP_0 (0x00000230) > #define MMSS_DP_AUDIO_TIMESTAMP_1 (0x00000234) > #define GENERIC0_SDPSIZE_VALID (0x00010000) > @@ -248,6 +258,7 @@ > > #define MMSS_DP_SDP_CFG3 (0x0000024c) > #define MMSS_DP1_SDP_CFG3 (0x000004E8) > +#define MMSS_DP_MSTLINK_SDP_CFG3 (0x00000114) > #define UPDATE_SDP (0x00000001) > > #define MMSS_DP_EXTENSION_0 (0x00000250) > @@ -297,6 +308,9 @@ > #define MMSS_DP_GENERIC1_8 (0x00000348) > #define MMSS_DP_GENERIC1_9 (0x0000034C) > #define MMSS_DP1_GENERIC0_0 (0x00000490) > +#define MMSS_DP_MSTLINK_GENERIC0_0 (0x000000BC) > +#define MMSS_DP_MSTLINK_GENERIC0_1 (0x000000C0) > +#define MMSS_DP_MSTLINK_GENERIC0_2 (0x000000C4) > > #define MMSS_DP_VSCEXT_0 (0x000002D0) > #define MMSS_DP_VSCEXT_1 (0x000002D4) > > -- > 2.34.1 > -- With best wishes Dmitry