Commit dbf5256b authored by Joshua Aberback's avatar Joshua Aberback Committed by Alex Deucher

drm/amd/display: Blank HUBP during pixel data blank for DCN30 v2

[Why]
Prior commit "Blank HUBP during pixel data blank for DCN30"
missed the call to set_disp_pattern_generator from
set_crtc_test_pattern, which re-exposed the issue for which
we initially blocked active-only p-state switching.

[How]
 - remove dcn30_blank_pixel_data, set dcn30 back to dcn20 version
 - new hwss funciton set_disp_pattern_generator
 - dcn20 version just calls opp_set_disp_pattern_generator
 - dcn30 version implements the HUBP blank
Signed-off-by: default avatarJoshua Aberback <joshua.aberback@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ec76bd6f
...@@ -3848,7 +3848,7 @@ static void set_crtc_test_pattern(struct dc_link *link, ...@@ -3848,7 +3848,7 @@ static void set_crtc_test_pattern(struct dc_link *link,
if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
controller_test_pattern, color_depth); controller_test_pattern, color_depth);
else if (opp->funcs->opp_set_disp_pattern_generator) { else if (link->dc->hwss.set_disp_pattern_generator) {
struct pipe_ctx *odm_pipe; struct pipe_ctx *odm_pipe;
enum controller_dp_color_space controller_color_space; enum controller_dp_color_space controller_color_space;
int opp_cnt = 1; int opp_cnt = 1;
...@@ -3878,26 +3878,29 @@ static void set_crtc_test_pattern(struct dc_link *link, ...@@ -3878,26 +3878,29 @@ static void set_crtc_test_pattern(struct dc_link *link,
dpg_width = width / opp_cnt; dpg_width = width / opp_cnt;
offset = dpg_width; offset = dpg_width;
opp->funcs->opp_set_disp_pattern_generator(opp, link->dc->hwss.set_disp_pattern_generator(link->dc,
controller_test_pattern, pipe_ctx,
controller_color_space,
color_depth,
NULL,
dpg_width,
height,
0);
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp,
controller_test_pattern, controller_test_pattern,
controller_color_space, controller_color_space,
color_depth, color_depth,
NULL, NULL,
dpg_width, dpg_width,
height, height,
offset); 0);
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
link->dc->hwss.set_disp_pattern_generator(link->dc,
odm_pipe,
controller_test_pattern,
controller_color_space,
color_depth,
NULL,
dpg_width,
height,
offset);
offset += offset; offset += offset;
} }
} }
...@@ -3913,7 +3916,7 @@ static void set_crtc_test_pattern(struct dc_link *link, ...@@ -3913,7 +3916,7 @@ static void set_crtc_test_pattern(struct dc_link *link,
pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
color_depth); color_depth);
else if (opp->funcs->opp_set_disp_pattern_generator) { else if (link->dc->hwss.set_disp_pattern_generator) {
struct pipe_ctx *odm_pipe; struct pipe_ctx *odm_pipe;
int opp_cnt = 1; int opp_cnt = 1;
int dpg_width = width; int dpg_width = width;
...@@ -3926,7 +3929,18 @@ static void set_crtc_test_pattern(struct dc_link *link, ...@@ -3926,7 +3929,18 @@ static void set_crtc_test_pattern(struct dc_link *link,
struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp; struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params); odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp, link->dc->hwss.set_disp_pattern_generator(link->dc,
odm_pipe,
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
CONTROLLER_DP_COLOR_SPACE_UDEFINED,
color_depth,
NULL,
dpg_width,
height,
0);
}
link->dc->hwss.set_disp_pattern_generator(link->dc,
pipe_ctx,
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
CONTROLLER_DP_COLOR_SPACE_UDEFINED, CONTROLLER_DP_COLOR_SPACE_UDEFINED,
color_depth, color_depth,
...@@ -3934,15 +3948,6 @@ static void set_crtc_test_pattern(struct dc_link *link, ...@@ -3934,15 +3948,6 @@ static void set_crtc_test_pattern(struct dc_link *link,
dpg_width, dpg_width,
height, height,
0); 0);
}
opp->funcs->opp_set_disp_pattern_generator(opp,
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
CONTROLLER_DP_COLOR_SPACE_UDEFINED,
color_depth,
NULL,
dpg_width,
height,
0);
} }
} }
break; break;
...@@ -3977,10 +3982,7 @@ bool dc_link_dp_set_test_pattern( ...@@ -3977,10 +3982,7 @@ bool dc_link_dp_set_test_pattern(
} }
} }
/* Reset CRTC Test Pattern if it is currently running and request /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */
* is VideoMode Reset DP Phy Test Pattern if it is currently running
* and request is VideoMode
*/
if (link->test_pattern_enabled && test_pattern == if (link->test_pattern_enabled && test_pattern ==
DP_TEST_PATTERN_VIDEO_MODE) { DP_TEST_PATTERN_VIDEO_MODE) {
/* Set CRTC Test Pattern */ /* Set CRTC Test Pattern */
......
...@@ -1030,8 +1030,8 @@ void dcn20_blank_pixel_data( ...@@ -1030,8 +1030,8 @@ void dcn20_blank_pixel_data(
test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE; test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
} }
stream_res->opp->funcs->opp_set_disp_pattern_generator( dc->hwss.set_disp_pattern_generator(dc,
stream_res->opp, pipe_ctx,
test_pattern, test_pattern,
test_pattern_color_space, test_pattern_color_space,
stream->timing.display_color_depth, stream->timing.display_color_depth,
...@@ -1041,8 +1041,8 @@ void dcn20_blank_pixel_data( ...@@ -1041,8 +1041,8 @@ void dcn20_blank_pixel_data(
0); 0);
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { 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( dc->hwss.set_disp_pattern_generator(dc,
odm_pipe->stream_res.opp, odm_pipe,
dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE && blank ? dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE && blank ?
CONTROLLER_DP_TEST_PATTERN_COLORRAMP : test_pattern, CONTROLLER_DP_TEST_PATTERN_COLORRAMP : test_pattern,
test_pattern_color_space, test_pattern_color_space,
...@@ -2569,3 +2569,15 @@ bool dcn20_optimize_timing_for_fsft(struct dc *dc, ...@@ -2569,3 +2569,15 @@ bool dcn20_optimize_timing_for_fsft(struct dc *dc,
return true; return true;
} }
#endif #endif
void dcn20_set_disp_pattern_generator(const struct dc *dc,
struct pipe_ctx *pipe_ctx,
enum controller_dp_test_pattern test_pattern,
enum controller_dp_color_space color_space,
enum dc_color_depth color_depth,
const struct tg_color *solid_color,
int width, int height, int offset)
{
pipe_ctx->stream_res.opp->funcs->opp_set_disp_pattern_generator(pipe_ctx->stream_res.opp, test_pattern,
color_space, color_depth, solid_color, width, height, offset);
}
\ No newline at end of file
...@@ -137,5 +137,14 @@ bool dcn20_optimize_timing_for_fsft(struct dc *dc, ...@@ -137,5 +137,14 @@ bool dcn20_optimize_timing_for_fsft(struct dc *dc,
struct dc_crtc_timing *timing, struct dc_crtc_timing *timing,
unsigned int max_input_rate_in_khz); unsigned int max_input_rate_in_khz);
#endif #endif
void dcn20_set_disp_pattern_generator(const struct dc *dc,
struct pipe_ctx *pipe_ctx,
enum controller_dp_test_pattern test_pattern,
enum controller_dp_color_space color_space,
enum dc_color_depth color_depth,
const struct tg_color *solid_color,
int width, int height, int offset);
#endif /* __DC_HWSS_DCN20_H__ */ #endif /* __DC_HWSS_DCN20_H__ */
...@@ -93,6 +93,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { ...@@ -93,6 +93,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
#ifndef TRIM_FSFT #ifndef TRIM_FSFT
.optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft, .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft,
#endif #endif
.set_disp_pattern_generator = dcn20_set_disp_pattern_generator,
}; };
static const struct hwseq_private_funcs dcn20_private_funcs = { static const struct hwseq_private_funcs dcn20_private_funcs = {
......
...@@ -98,6 +98,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { ...@@ -98,6 +98,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
.optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft, .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft,
#endif #endif
.is_abm_supported = dcn21_is_abm_supported, .is_abm_supported = dcn21_is_abm_supported,
.set_disp_pattern_generator = dcn20_set_disp_pattern_generator,
}; };
static const struct hwseq_private_funcs dcn21_private_funcs = { static const struct hwseq_private_funcs dcn21_private_funcs = {
......
...@@ -816,85 +816,37 @@ void dcn30_hardware_release(struct dc *dc) ...@@ -816,85 +816,37 @@ void dcn30_hardware_release(struct dc *dc)
dc->res_pool->hubbub, true, true); dc->res_pool->hubbub, true, true);
} }
void dcn30_blank_pixel_data(struct dc *dc, struct pipe_ctx *pipe_ctx, bool blank) void dcn30_set_disp_pattern_generator(const struct dc *dc,
struct pipe_ctx *pipe_ctx,
enum controller_dp_test_pattern test_pattern,
enum controller_dp_color_space color_space,
enum dc_color_depth color_depth,
const struct tg_color *solid_color,
int width, int height, int offset)
{ {
struct tg_color black_color = {0};
struct stream_resource *stream_res = &pipe_ctx->stream_res; 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; 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; if (test_pattern != CONTROLLER_DP_TEST_PATTERN_VIDEOMODE) {
int height = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top; /* turning on DPG */
stream_res->opp->funcs->opp_set_disp_pattern_generator(stream_res->opp, test_pattern, color_space,
color_depth, solid_color, width, height, 0);
if (stream->link->test_pattern_enabled) /* wait for the next frame when enabling DPG */
return; if (stream_res->tg->funcs->is_tg_enabled(stream_res->tg))
dc->hwseq->funcs.wait_for_blank_complete(stream_res->opp);
/* 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) { /* Blank HUBP to allow p-state during blank on all timings */
test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES; pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, true);
test_pattern_color_space = CONTROLLER_DP_COLOR_SPACE_RGB; 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, true);
} else { } else {
test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE; /* turning off DPG */
} pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, false);
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, false);
stream_res->opp->funcs->opp_set_disp_pattern_generator( stream_res->opp->funcs->opp_set_disp_pattern_generator(stream_res->opp, test_pattern, color_space,
stream_res->opp, color_depth, solid_color, width, height, 0);
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);
}
} }
...@@ -69,6 +69,12 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable); ...@@ -69,6 +69,12 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable);
void dcn30_hardware_release(struct dc *dc); void dcn30_hardware_release(struct dc *dc);
void dcn30_blank_pixel_data(struct dc *dc, struct pipe_ctx *pipe_ctx, bool blank); void dcn30_set_disp_pattern_generator(const struct dc *dc,
struct pipe_ctx *pipe_ctx,
enum controller_dp_test_pattern test_pattern,
enum controller_dp_color_space color_space,
enum dc_color_depth color_depth,
const struct tg_color *solid_color,
int width, int height, int offset);
#endif /* __DC_HWSS_DCN30_H__ */ #endif /* __DC_HWSS_DCN30_H__ */
...@@ -95,6 +95,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = { ...@@ -95,6 +95,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
.set_abm_immediate_disable = dcn21_set_abm_immediate_disable, .set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
.hardware_release = dcn30_hardware_release, .hardware_release = dcn30_hardware_release,
.set_pipe = dcn21_set_pipe, .set_pipe = dcn21_set_pipe,
.set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
}; };
static const struct hwseq_private_funcs dcn30_private_funcs = { static const struct hwseq_private_funcs dcn30_private_funcs = {
...@@ -106,7 +107,7 @@ static const struct hwseq_private_funcs dcn30_private_funcs = { ...@@ -106,7 +107,7 @@ static const struct hwseq_private_funcs dcn30_private_funcs = {
.set_output_transfer_func = dcn30_set_output_transfer_func, .set_output_transfer_func = dcn30_set_output_transfer_func,
.power_down = dce110_power_down, .power_down = dce110_power_down,
.enable_display_power_gating = dcn10_dummy_display_power_gating, .enable_display_power_gating = dcn10_dummy_display_power_gating,
.blank_pixel_data = dcn30_blank_pixel_data, .blank_pixel_data = dcn20_blank_pixel_data,
.reset_hw_ctx_wrap = dcn20_reset_hw_ctx_wrap, .reset_hw_ctx_wrap = dcn20_reset_hw_ctx_wrap,
.enable_stream_timing = dcn20_enable_stream_timing, .enable_stream_timing = dcn20_enable_stream_timing,
.edp_backlight_control = dce110_edp_backlight_control, .edp_backlight_control = dce110_edp_backlight_control,
......
...@@ -223,6 +223,14 @@ struct hw_sequencer_funcs { ...@@ -223,6 +223,14 @@ struct hw_sequencer_funcs {
bool (*is_abm_supported)(struct dc *dc, bool (*is_abm_supported)(struct dc *dc,
struct dc_state *context, struct dc_stream_state *stream); struct dc_state *context, struct dc_stream_state *stream);
void (*set_disp_pattern_generator)(const struct dc *dc,
struct pipe_ctx *pipe_ctx,
enum controller_dp_test_pattern test_pattern,
enum controller_dp_color_space color_space,
enum dc_color_depth color_depth,
const struct tg_color *solid_color,
int width, int height, int offset);
}; };
void color_space_to_black_color( void color_space_to_black_color(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment