diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 80116e19fbbf4..4181898f51cbc 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -2414,6 +2414,19 @@ void msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl *msm_dp_ctrl, enum msm_dp_stre } } +bool msm_dp_ctrl_stream_clk_on(struct msm_dp_ctrl *msm_dp_ctrl, + enum msm_dp_stream_id stream_id) +{ + struct msm_dp_ctrl_private *ctrl; + + if (stream_id >= DP_STREAM_MAX) + return false; + + ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl); + + return ctrl->stream_clks_on[stream_id]; +} + static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl, struct msm_dp_panel *panel) { diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h index 88a02d52f61c6..4279f673e2d8d 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.h +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h @@ -26,6 +26,8 @@ int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl, void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel); void msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl *msm_dp_ctrl, enum msm_dp_stream_id stream_id); +bool msm_dp_ctrl_stream_clk_on(struct msm_dp_ctrl *msm_dp_ctrl, + enum msm_dp_stream_id stream_id); void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl); void msm_dp_ctrl_push_vcpf(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel); irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl, diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 8a75990d1055a..30ddc0eaa8a94 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -936,6 +936,7 @@ int msm_dp_display_get_test_bpp(struct msm_dp *dp) void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp) { struct msm_dp_display_private *msm_dp_display; + int i; msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display); @@ -959,14 +960,22 @@ void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp) msm_dp_display->mst2link_base, "dp_mst2link"); msm_disp_snapshot_add_block(disp_state, msm_dp_display->mst3link_len, msm_dp_display->mst3link_base, "dp_mst3link"); - msm_disp_snapshot_add_block(disp_state, msm_dp_display->pixel_len, - msm_dp_display->pixel_base[0], "dp_p0"); - msm_disp_snapshot_add_block(disp_state, msm_dp_display->pixel_len, - msm_dp_display->pixel_base[1], "dp_p1"); - msm_disp_snapshot_add_block(disp_state, msm_dp_display->pixel_len, - msm_dp_display->pixel_base[2], "dp_p2"); - msm_disp_snapshot_add_block(disp_state, msm_dp_display->pixel_len, - msm_dp_display->pixel_base[3], "dp_p3"); + + /* + * Each pixel stream is fed by its own pixel clock, and active_stream_cnt + * only tells us that at least one of them is running. Dump a per-stream + * block only when it is both mapped and its pixel clock is enabled: in + * SST only stream 0 is used, so reading the others - present in the IO + * space but unclocked - would trigger an unclocked (NoC) access. + */ + for (i = 0; i < DP_STREAM_MAX; i++) { + if (!msm_dp_display->pixel_base[i] || + !msm_dp_ctrl_stream_clk_on(msm_dp_display->ctrl, i)) + continue; + + msm_disp_snapshot_add_block(disp_state, msm_dp_display->pixel_len, + msm_dp_display->pixel_base[i], "dp_p%d", i); + } } void msm_dp_display_set_psr(struct msm_dp *msm_dp_display, bool enter)