From: Joshua Aberback Date: Sun, 18 Oct 2020 21:36:00 +0000 (-0400) Subject: drm/amd/display: Blank HUBP during pixel data blank for DCN30 X-Git-Tag: accepted/tizen/unified/20230118.172025~8358^2~12^2~59 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=36f878501e5faf3634b02c8a150238efbd7ee01a;p=platform%2Fkernel%2Flinux-rpi.git drm/amd/display: Blank HUBP during pixel data blank for DCN30 [Why] There are some timings for which we support p-state switching in active, but not in blank. There was a previous issue where a timing that had active-only support would hang a p-state request when we were in an extended blanking period. The workaround for that issue was to block active-only p-state switching, but that resulted in a lack of p-state support for some common timings such as 1440p60. We want to fix that issue properly by un-blocking p-state requests while the display is blanked, so that we can re-enable active-only p-state switching. [How] - new version of blank_pixel_data for DCN30 - call hubp->set_blank from dcn30_blank_pixel_data - blank every hubp in the mpcc tree, and odm tree - on blank enable, wait until the next frame before blanking HUBP Signed-off-by: Joshua Aberback Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index cc2eca8..7195257 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -809,3 +809,86 @@ void dcn30_hardware_release(struct dc *dc) dc->res_pool->hubbub->funcs->force_pstate_change_control( dc->res_pool->hubbub, true, true); } + +void dcn30_blank_pixel_data(struct dc *dc, struct pipe_ctx *pipe_ctx, bool blank) +{ + struct tg_color black_color = {0}; + struct stream_resource *stream_res = &pipe_ctx->stream_res; + struct dc_stream_state *stream = pipe_ctx->stream; + enum dc_color_space color_space = stream->output_color_space; + enum controller_dp_test_pattern test_pattern = CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR; + enum controller_dp_color_space test_pattern_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED; + struct pipe_ctx *odm_pipe; + struct pipe_ctx *mpcc_pipe; + int odm_cnt = 1; + + int width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right; + int height = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top; + + if (stream->link->test_pattern_enabled) + return; + + /* get opp dpg blank color */ + color_space_to_black_color(dc, color_space, &black_color); + + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) + odm_cnt++; + + width = width / odm_cnt; + + if (blank) { + dc->hwss.set_abm_immediate_disable(pipe_ctx); + + if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) { + test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES; + test_pattern_color_space = CONTROLLER_DP_COLOR_SPACE_RGB; + } + } else { + test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE; + } + + stream_res->opp->funcs->opp_set_disp_pattern_generator( + stream_res->opp, + test_pattern, + test_pattern_color_space, + stream->timing.display_color_depth, + &black_color, + width, + height, + 0); + + /* wait for the next frame when enabling DPG */ + if (blank && stream_res->tg->funcs->is_tg_enabled(stream_res->tg)) + dc->hwseq->funcs.wait_for_blank_complete(pipe_ctx->stream_res.opp); + + /* Blank HUBP to allow p-state during blank on all timings */ + pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, blank); + for (mpcc_pipe = pipe_ctx->bottom_pipe; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe) + mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, blank); + + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { + odm_pipe->stream_res.opp->funcs->opp_set_disp_pattern_generator( + odm_pipe->stream_res.opp, + dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE && blank ? + CONTROLLER_DP_TEST_PATTERN_COLORRAMP : test_pattern, + test_pattern_color_space, + stream->timing.display_color_depth, + &black_color, + width, + height, + 0); + + if (blank && stream_res->tg->funcs->is_tg_enabled(stream_res->tg)) + dc->hwseq->funcs.wait_for_blank_complete(pipe_ctx->stream_res.opp); + + odm_pipe->plane_res.hubp->funcs->set_blank(odm_pipe->plane_res.hubp, blank); + for (mpcc_pipe = odm_pipe->bottom_pipe; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe) + mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, blank); + } + + if (!blank) + if (stream_res->abm) { + dc->hwss.set_pipe(pipe_ctx); + stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level); + } +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h index 0ae0472..7d9db7c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h @@ -69,4 +69,6 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable); void dcn30_hardware_release(struct dc *dc); +void dcn30_blank_pixel_data(struct dc *dc, struct pipe_ctx *pipe_ctx, bool blank); + #endif /* __DC_HWSS_DCN30_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c index b829cb1..4d1b756 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c @@ -106,7 +106,7 @@ static const struct hwseq_private_funcs dcn30_private_funcs = { .set_output_transfer_func = dcn30_set_output_transfer_func, .power_down = dce110_power_down, .enable_display_power_gating = dcn10_dummy_display_power_gating, - .blank_pixel_data = dcn20_blank_pixel_data, + .blank_pixel_data = dcn30_blank_pixel_data, .reset_hw_ctx_wrap = dcn20_reset_hw_ctx_wrap, .enable_stream_timing = dcn20_enable_stream_timing, .edp_backlight_control = dce110_edp_backlight_control, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index 0f66869..3f83bcb 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -5558,7 +5558,7 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport( } } - if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0 && PrefetchMode == 0) { + if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) { *DRAMClockChangeSupport = dm_dram_clock_change_vactive; } else if (((mode_lib->vba.SynchronizedVBlank == true || mode_lib->vba.TotalNumberOfActiveOTG == 1 || SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank > 0) && PrefetchMode == 0)) { *DRAMClockChangeSupport = dm_dram_clock_change_vblank;