On Thu, Dec 05, 2024 at 08:31:49PM -0800, Abhinav Kumar wrote: > Whenever virtual channel slot allocation changes, the DP > source must send the action control trigger sequence to notify > the sink about the same. This would be applicable during the > start and stop of the pixel stream. Add the infrastructure > to be able to send ACT packets for the DP controller when > operating in MST mode. > > Signed-off-by: Abhinav Kumar <quic_abhinavk@xxxxxxxxxxx> > --- > drivers/gpu/drm/msm/dp/dp_catalog.c | 21 +++++++++++++++++++++ > drivers/gpu/drm/msm/dp/dp_catalog.h | 4 ++++ > drivers/gpu/drm/msm/dp/dp_ctrl.c | 36 ++++++++++++++++++++++++++++++++++-- > drivers/gpu/drm/msm/dp/dp_ctrl.h | 3 ++- > drivers/gpu/drm/msm/dp/dp_display.c | 6 +++++- > drivers/gpu/drm/msm/dp/dp_display.h | 1 + > drivers/gpu/drm/msm/dp/dp_reg.h | 3 +++ > 7 files changed, 70 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c > index e6f6edf617898241c74580eb0ae6bc58f06a154f..88d6262a972ef2d30c467ef5ff5c58ef3299ae7d 100644 > --- a/drivers/gpu/drm/msm/dp/dp_catalog.c > +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c > @@ -1078,6 +1078,27 @@ void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog) > msm_dp_catalog_panel_update_sdp(msm_dp_catalog); > } > > +void msm_dp_catalog_trigger_act(struct msm_dp_catalog *msm_dp_catalog) > +{ > + struct msm_dp_catalog_private *catalog; > + > + catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog); > + > + msm_dp_write_link(catalog, REG_DP_MST_ACT, 0x1); > + > + /* make sure ACT signal is performed */ > + wmb(); > +} > + > +bool msm_dp_catalog_read_act_complete_sts(struct msm_dp_catalog *msm_dp_catalog) > +{ > + struct msm_dp_catalog_private *catalog; > + > + catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog); > + > + return msm_dp_read_link(catalog, REG_DP_MST_ACT); > +} > + Hopefully after [1] this becomes inline in the corresponding dp_ctrl functions. [1] https://patchwork.freedesktop.org/patch/626816/?series=141074&rev=2 > void msm_dp_catalog_panel_tpg_enable(struct msm_dp_catalog *msm_dp_catalog, > struct drm_display_mode *drm_mode) > { > diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h > index c020b7cfa008241e937f6a53764b136431f1dbd9..c91c52d40209b8bcb63db9c0256f6ef721dace8a 100644 > --- a/drivers/gpu/drm/msm/dp/dp_catalog.h > +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h > @@ -135,4 +135,8 @@ void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *catalog); > void msm_dp_catalog_audio_init(struct msm_dp_catalog *catalog); > void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *catalog, u32 safe_to_exit_level); > > +/* DP MST APIs */ > +void msm_dp_catalog_trigger_act(struct msm_dp_catalog *dp_catalog); > +bool msm_dp_catalog_read_act_complete_sts(struct msm_dp_catalog *dp_catalog); > + > #endif /* _DP_CATALOG_H_ */ > diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c > index ba39b009032dd6f5cb708988963cd6acb6838e4a..2bfe2aac3c02b02b12713dbd98e79ed4a75b85d0 100644 > --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c > +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c > @@ -97,6 +97,8 @@ struct msm_dp_ctrl_private { > > bool core_clks_on; > bool link_clks_on; > + > + bool mst_active; > bool stream_clks_on[DP_STREAM_MAX]; > }; > > @@ -1625,6 +1627,26 @@ static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl) > return 0; > } > > +int msm_dp_ctrl_mst_send_act(struct msm_dp_ctrl *msm_dp_ctrl) > +{ > + struct msm_dp_ctrl_private *ctrl; > + bool act_complete; > + > + ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl); > + > + msm_dp_catalog_trigger_act(ctrl->catalog); > + msleep(20); /* needs 1 frame time */ > + > + act_complete = msm_dp_catalog_read_act_complete_sts(ctrl->catalog); > + > + if (!act_complete) > + DRM_ERROR("mst ACT trigger complete SUCCESS\n"); > + else > + drm_dbg_dp(ctrl->drm_dev, "mst ACT trigger complete failed\n"); > + > + return 0; > +} > + > static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl) > { > int ret = 0; > @@ -1643,6 +1665,9 @@ static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl) > > msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO); > > + if (ctrl->mst_active) > + msm_dp_ctrl_mst_send_act(&ctrl->msm_dp_ctrl); > + > ret = msm_dp_ctrl_wait4video_ready(ctrl); > end: > return ret; > @@ -1745,7 +1770,7 @@ static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl > msm_dp_ctrl_stream_clk_off(&ctrl->msm_dp_ctrl, msm_dp_panel); > msm_dp_ctrl_off_link(&ctrl->msm_dp_ctrl); > > - ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl); > + ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl, ctrl->mst_active); > if (ret) { > DRM_ERROR("failed to enable DP link controller\n"); > return ret; > @@ -1825,7 +1850,7 @@ static bool msm_dp_ctrl_channel_eq_ok(struct msm_dp_ctrl_private *ctrl) > return drm_dp_channel_eq_ok(link_status, num_lanes); > } > > -int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) > +int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl, bool mst_active) > { > int rc = 0; > struct msm_dp_ctrl_private *ctrl; > @@ -1844,6 +1869,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) > rate = ctrl->panel->link_info.rate; > pixel_rate = ctrl->panel->msm_dp_mode.drm_mode.clock; > > + ctrl->mst_active = mst_active; > msm_dp_ctrl_core_clk_enable(&ctrl->msm_dp_ctrl); > > if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) { > @@ -2035,6 +2061,9 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel * > > msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO); > > + if (ctrl->mst_active) > + msm_dp_ctrl_mst_send_act(msm_dp_ctrl); > + > ret = msm_dp_ctrl_wait4video_ready(ctrl); > if (ret) > return ret; > @@ -2104,6 +2133,8 @@ void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl) > > msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false); > > + ctrl->mst_active = false; > + > dev_pm_opp_set_rate(ctrl->dev, 0); > msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl); > > @@ -2264,6 +2295,7 @@ struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link > ctrl->catalog = catalog; > ctrl->dev = dev; > ctrl->phy = phy; > + ctrl->mst_active = false; > > ret = msm_dp_ctrl_clk_init(&ctrl->msm_dp_ctrl); > if (ret) { > diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h > index d422fd683b65d6f5e459710d0327e472a12c30b0..81c05b1b2baac63e1f1888f3f517e62a98e230a7 100644 > --- a/drivers/gpu/drm/msm/dp/dp_ctrl.h > +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h > @@ -17,7 +17,7 @@ struct msm_dp_ctrl { > > struct phy; > > -int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl); > +int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl, bool mst_active); > int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *msm_dp_panel); > int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *dp_ctrl, bool force_link_train); > void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl); > @@ -46,5 +46,6 @@ void msm_dp_ctrl_clear_vsc_sdp_pkt(struct msm_dp_ctrl *msm_dp_ctrl, > struct msm_dp_panel *msm_dp_panel); > void msm_dp_ctrl_psm_config(struct msm_dp_ctrl *msm_dp_ctrl); > void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl); > +int msm_dp_ctrl_mst_send_act(struct msm_dp_ctrl *ctrl); > > #endif /* _DP_CTRL_H_ */ > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c > index 5fa6c003cf6c51eae77573549a555a00dc33f476..e19860ef3493fb100afbf04b09d14a136fd6b887 100644 > --- a/drivers/gpu/drm/msm/dp/dp_display.c > +++ b/drivers/gpu/drm/msm/dp/dp_display.c > @@ -370,6 +370,7 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) > struct drm_connector *connector = dp->msm_dp_display.connector; > const struct drm_display_info *info = &connector->display_info; > int rc = 0; > + struct msm_dp *dp_display = &dp->msm_dp_display; > > rc = msm_dp_panel_read_link_caps(dp->panel, connector); > if (rc) > @@ -399,7 +400,7 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) > msm_dp_link_psm_config(dp->link, &dp->panel->link_info, false); > > msm_dp_link_reset_phy_params_vx_px(dp->link); > - rc = msm_dp_ctrl_on_link(dp->ctrl); > + rc = msm_dp_ctrl_on_link(dp->ctrl, dp_display->mst_active); > if (rc) { > DRM_ERROR("failed to complete DP link training\n"); > goto end; > @@ -1628,6 +1629,9 @@ void msm_dp_display_atomic_disable(struct msm_dp *dp) > msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display); > > msm_dp_ctrl_push_idle(msm_dp_display->ctrl); > + > + if (dp->mst_active) > + msm_dp_ctrl_mst_send_act(msm_dp_display->ctrl); > } > > static void msm_dp_display_unprepare(struct msm_dp_display_private *dp) > diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h > index 8ce8ba254b1bfe5b4c000df83eceef5823772780..38ca25491b1ccfd95e027a9c8f659abb3cd576d3 100644 > --- a/drivers/gpu/drm/msm/dp/dp_display.h > +++ b/drivers/gpu/drm/msm/dp/dp_display.h > @@ -22,6 +22,7 @@ struct msm_dp { > bool audio_enabled; > bool power_on; > bool prepared; > + bool mst_active; > unsigned int connector_type; > bool is_edp; > bool internal_hpd; > diff --git a/drivers/gpu/drm/msm/dp/dp_reg.h b/drivers/gpu/drm/msm/dp/dp_reg.h > index 6c534fde6034fced2cb428e9a29de31ed5c5fcc4..46400973eb499066e9e805b16df759b1db34cf22 100644 > --- a/drivers/gpu/drm/msm/dp/dp_reg.h > +++ b/drivers/gpu/drm/msm/dp/dp_reg.h > @@ -330,6 +330,9 @@ > #define REG_DP_PHY_AUX_BIST_CFG (0x00000050) > #define REG_DP_PHY_AUX_INTERRUPT_STATUS (0x000000BC) > > +/* DP MST related registers */ > +#define REG_DP_MST_ACT (0x00000500) This looks completely out of place. > + > /* DP HDCP 1.3 registers */ > #define DP_HDCP_CTRL (0x0A0) > #define DP_HDCP_STATUS (0x0A4) > > -- > 2.34.1 > -- With best wishes Dmitry