]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
drm/amd/display: p-state warning occurs while changing resolution from 120hz to 60hz
authorhersen wu <hersenxs.wu@amd.com>
Mon, 6 Jul 2020 13:18:25 +0000 (09:18 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 14 Jul 2020 18:34:24 +0000 (14:34 -0400)
[Why]
new calculated dispclk, dppclk are stored in
context->bw_ctx.bw.dcn.clk.dispclk_khz, dppclk_khz. Current dispclk,
dppclk are from dc->clk_mgr->clks.dispclk_khz. dcn_validate_bandwidth
compute new dispclk, dppclk. dispclk will put in use after
optimize_bandwidth when ramp_up_dispclk_with_dpp is called. There are
two places for dppclk be put in use. One location is the same as the
location as dispclk. Another is within update_dchubp_dpp which happens
between pre_bandwidth and optimize_bandwidth. dppclk updated within
update_dchubp_dpp will cause new clock values of dispclk and dppclk not
be in use at the same time. when clocks are decreased, this may cause
dppclk is lower than current configuration and let pipe stuck. for
example, eDP + external dp, change resolution of DP from 1920x1080x144hz
to 1280x960x60hz.

before change: dispclk = 337889 dppclk = 337889
change mode, dcn_validate_bandwidth calculate
             dispclk = 143122 dppclk = 143122
update_dchubp_dpp be executed before dispclk be updated,
dispclk = 337889, but dppclk use new value dispclk /2 =
168944. this will cause pipe pstate warning issue.

[How]
between pre_bandwidth and optimize_bandwidth, while dispclk is going to
be decreased, keep dppclk = dispclk

Signed-off-by: Hersen Wu <hersenxs.wu@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c

index 9cdc3d2919f4b5ba893ef46d6ba36933bcfb6c90..da0897fe3b5434b94c5d4c58c857ed86cabec44f 100644 (file)
@@ -2459,14 +2459,46 @@ static void dcn10_update_dchubp_dpp(
        struct dc_plane_state *plane_state = pipe_ctx->plane_state;
        struct plane_size size = plane_state->plane_size;
        unsigned int compat_level = 0;
+       bool should_divided_by_2 = false;
 
        /* depends on DML calculation, DPP clock value may change dynamically */
        /* If request max dpp clk is lower than current dispclk, no need to
         * divided by 2
         */
        if (plane_state->update_flags.bits.full_update) {
-               bool should_divided_by_2 = context->bw_ctx.bw.dcn.clk.dppclk_khz <=
-                               dc->clk_mgr->clks.dispclk_khz / 2;
+
+               /* new calculated dispclk, dppclk are stored in
+                * context->bw_ctx.bw.dcn.clk.dispclk_khz / dppclk_khz. current
+                * dispclk, dppclk are from dc->clk_mgr->clks.dispclk_khz.
+                * dcn_validate_bandwidth compute new dispclk, dppclk.
+                * dispclk will put in use after optimize_bandwidth when
+                * ramp_up_dispclk_with_dpp is called.
+                * there are two places for dppclk be put in use. One location
+                * is the same as the location as dispclk. Another is within
+                * update_dchubp_dpp which happens between pre_bandwidth and
+                * optimize_bandwidth.
+                * dppclk updated within update_dchubp_dpp will cause new
+                * clock values of dispclk and dppclk not be in use at the same
+                * time. when clocks are decreased, this may cause dppclk is
+                * lower than previous configuration and let pipe stuck.
+                * for example, eDP + external dp,  change resolution of DP from
+                * 1920x1080x144hz to 1280x960x60hz.
+                * before change: dispclk = 337889 dppclk = 337889
+                * change mode, dcn_validate_bandwidth calculate
+                *                dispclk = 143122 dppclk = 143122
+                * update_dchubp_dpp be executed before dispclk be updated,
+                * dispclk = 337889, but dppclk use new value dispclk /2 =
+                * 168944. this will cause pipe pstate warning issue.
+                * solution: between pre_bandwidth and optimize_bandwidth, while
+                * dispclk is going to be decreased, keep dppclk = dispclk
+                **/
+               if (context->bw_ctx.bw.dcn.clk.dispclk_khz <
+                               dc->clk_mgr->clks.dispclk_khz)
+                       should_divided_by_2 = false;
+               else
+                       should_divided_by_2 =
+                                       context->bw_ctx.bw.dcn.clk.dppclk_khz <=
+                                       dc->clk_mgr->clks.dispclk_khz / 2;
 
                dpp->funcs->dpp_dppclk_control(
                                dpp,