mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-28 21:33:52 +00:00
drm/amd/display: Refactor DPG test pattern logic for ODM cases
[Why] Current DPG test pattern logic does not account for ODM configuration changes after test pattern has already been programmed. For example, if ODM2:1 is enabled after test pattern is already being output, the second pipe is not programmed to output test pattern, causing half the screen to be black. [How] Move DPG test pattern parameter calculations into separate function. Whenever ODM pipe configuration changes, re-calculate DPG test pattern parameters and program DPG if test pattern is currently enabled. Reviewed-by: Wenjing Liu <wenjing.liu@amd.com> Acked-by: Tom Chung <chiahsuan.chung@amd.com> Signed-off-by: George Shen <george.shen@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
ef013f6fcd
commit
051d90070d
6 changed files with 175 additions and 93 deletions
|
@ -3169,6 +3169,14 @@ static bool update_planes_and_stream_state(struct dc *dc,
|
|||
BREAK_TO_DEBUGGER();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
struct pipe_ctx *otg_master = resource_get_otg_master_for_stream(&context->res_ctx,
|
||||
context->streams[i]);
|
||||
|
||||
if (otg_master->stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE)
|
||||
resource_build_test_pattern_params(&context->res_ctx, otg_master);
|
||||
}
|
||||
}
|
||||
|
||||
*new_context = context;
|
||||
|
|
|
@ -1367,6 +1367,110 @@ static bool is_subvp_high_refresh_candidate(struct dc_stream_state *stream)
|
|||
return false;
|
||||
}
|
||||
|
||||
static enum controller_dp_test_pattern convert_dp_to_controller_test_pattern(
|
||||
enum dp_test_pattern test_pattern)
|
||||
{
|
||||
enum controller_dp_test_pattern controller_test_pattern;
|
||||
|
||||
switch (test_pattern) {
|
||||
case DP_TEST_PATTERN_COLOR_SQUARES:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
|
||||
break;
|
||||
case DP_TEST_PATTERN_VERTICAL_BARS:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
|
||||
break;
|
||||
case DP_TEST_PATTERN_HORIZONTAL_BARS:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_RAMP:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
|
||||
break;
|
||||
default:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
|
||||
break;
|
||||
}
|
||||
|
||||
return controller_test_pattern;
|
||||
}
|
||||
|
||||
static enum controller_dp_color_space convert_dp_to_controller_color_space(
|
||||
enum dp_test_pattern_color_space color_space)
|
||||
{
|
||||
enum controller_dp_color_space controller_color_space;
|
||||
|
||||
switch (color_space) {
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_RGB:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_RGB;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR601;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR709;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED:
|
||||
default:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
|
||||
break;
|
||||
}
|
||||
|
||||
return controller_color_space;
|
||||
}
|
||||
|
||||
void resource_build_test_pattern_params(struct resource_context *res_ctx,
|
||||
struct pipe_ctx *otg_master)
|
||||
{
|
||||
int odm_slice_width, last_odm_slice_width, offset = 0;
|
||||
struct pipe_ctx *opp_heads[MAX_PIPES];
|
||||
struct test_pattern_params *params;
|
||||
int odm_cnt = 1;
|
||||
enum controller_dp_test_pattern controller_test_pattern;
|
||||
enum controller_dp_color_space controller_color_space;
|
||||
enum dc_color_depth color_depth = otg_master->stream->timing.display_color_depth;
|
||||
int h_active = otg_master->stream->timing.h_addressable +
|
||||
otg_master->stream->timing.h_border_left +
|
||||
otg_master->stream->timing.h_border_right;
|
||||
int v_active = otg_master->stream->timing.v_addressable +
|
||||
otg_master->stream->timing.v_border_bottom +
|
||||
otg_master->stream->timing.v_border_top;
|
||||
int i;
|
||||
|
||||
controller_test_pattern = convert_dp_to_controller_test_pattern(
|
||||
otg_master->stream->test_pattern.type);
|
||||
controller_color_space = convert_dp_to_controller_color_space(
|
||||
otg_master->stream->test_pattern.color_space);
|
||||
|
||||
odm_cnt = resource_get_opp_heads_for_otg_master(otg_master, res_ctx, opp_heads);
|
||||
|
||||
odm_slice_width = h_active / odm_cnt;
|
||||
last_odm_slice_width = h_active - odm_slice_width * (odm_cnt - 1);
|
||||
|
||||
for (i = 0; i < odm_cnt; i++) {
|
||||
params = &opp_heads[i]->stream_res.test_pattern_params;
|
||||
params->test_pattern = controller_test_pattern;
|
||||
params->color_space = controller_color_space;
|
||||
params->color_depth = color_depth;
|
||||
params->height = v_active;
|
||||
params->offset = offset;
|
||||
|
||||
if (i < odm_cnt - 1)
|
||||
params->width = odm_slice_width;
|
||||
else
|
||||
params->width = last_odm_slice_width;
|
||||
|
||||
offset += odm_slice_width;
|
||||
}
|
||||
}
|
||||
|
||||
bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
||||
|
|
|
@ -1538,6 +1538,11 @@ static void dcn20_detect_pipe_changes(struct pipe_ctx *old_pipe, struct pipe_ctx
|
|||
|
||||
if (old_pipe->unbounded_req != new_pipe->unbounded_req)
|
||||
new_pipe->update_flags.bits.unbounded_req = 1;
|
||||
|
||||
if (memcmp(&old_pipe->stream_res.test_pattern_params,
|
||||
&new_pipe->stream_res.test_pattern_params, sizeof(struct test_pattern_params))) {
|
||||
new_pipe->update_flags.bits.test_pattern_changed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void dcn20_update_dchubp_dpp(
|
||||
|
@ -1846,6 +1851,23 @@ static void dcn20_program_pipe(
|
|||
pipe_ctx->stream->abm_level);
|
||||
}
|
||||
}
|
||||
|
||||
if (pipe_ctx->update_flags.bits.test_pattern_changed) {
|
||||
struct output_pixel_processor *odm_opp = pipe_ctx->stream_res.opp;
|
||||
struct bit_depth_reduction_params params;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms);
|
||||
dc->hwss.set_disp_pattern_generator(dc,
|
||||
pipe_ctx,
|
||||
pipe_ctx->stream_res.test_pattern_params.test_pattern,
|
||||
pipe_ctx->stream_res.test_pattern_params.color_space,
|
||||
pipe_ctx->stream_res.test_pattern_params.color_depth,
|
||||
NULL,
|
||||
pipe_ctx->stream_res.test_pattern_params.width,
|
||||
pipe_ctx->stream_res.test_pattern_params.height,
|
||||
pipe_ctx->stream_res.test_pattern_params.offset);
|
||||
}
|
||||
}
|
||||
|
||||
void dcn20_program_front_end_for_ctx(
|
||||
|
|
|
@ -308,6 +308,16 @@ struct dcn_fe_bandwidth {
|
|||
|
||||
};
|
||||
|
||||
/* Parameters needed to call set_disp_pattern_generator */
|
||||
struct test_pattern_params {
|
||||
enum controller_dp_test_pattern test_pattern;
|
||||
enum controller_dp_color_space color_space;
|
||||
enum dc_color_depth color_depth;
|
||||
int width;
|
||||
int height;
|
||||
int offset;
|
||||
};
|
||||
|
||||
struct stream_resource {
|
||||
struct output_pixel_processor *opp;
|
||||
struct display_stream_compressor *dsc;
|
||||
|
@ -324,6 +334,8 @@ struct stream_resource {
|
|||
* otherwise it's using group number 'gsl_group-1'
|
||||
*/
|
||||
uint8_t gsl_group;
|
||||
|
||||
struct test_pattern_params test_pattern_params;
|
||||
};
|
||||
|
||||
struct plane_resource {
|
||||
|
@ -367,6 +379,7 @@ union pipe_update_flags {
|
|||
uint32_t plane_changed : 1;
|
||||
uint32_t det_size : 1;
|
||||
uint32_t unbounded_req : 1;
|
||||
uint32_t test_pattern_changed : 1;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
};
|
||||
|
|
|
@ -103,6 +103,10 @@ enum dc_status resource_map_pool_resources(
|
|||
struct dc_state *context,
|
||||
struct dc_stream_state *stream);
|
||||
|
||||
void resource_build_test_pattern_params(
|
||||
struct resource_context *res_ctx,
|
||||
struct pipe_ctx *pipe_ctx);
|
||||
|
||||
bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx);
|
||||
|
||||
enum dc_status resource_build_scaling_params_for_context(
|
||||
|
|
|
@ -429,49 +429,13 @@ static void set_crtc_test_pattern(struct dc_link *link,
|
|||
struct bit_depth_reduction_params params;
|
||||
struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
|
||||
struct pipe_ctx *odm_pipe;
|
||||
int odm_cnt = 1;
|
||||
int h_active = pipe_ctx->stream->timing.h_addressable +
|
||||
pipe_ctx->stream->timing.h_border_left +
|
||||
pipe_ctx->stream->timing.h_border_right;
|
||||
int v_active = pipe_ctx->stream->timing.v_addressable +
|
||||
pipe_ctx->stream->timing.v_border_bottom +
|
||||
pipe_ctx->stream->timing.v_border_top;
|
||||
int odm_slice_width, last_odm_slice_width, offset = 0;
|
||||
struct test_pattern_params *tp_params;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
|
||||
odm_cnt++;
|
||||
|
||||
odm_slice_width = h_active / odm_cnt;
|
||||
last_odm_slice_width = h_active - odm_slice_width * (odm_cnt - 1);
|
||||
|
||||
switch (test_pattern) {
|
||||
case DP_TEST_PATTERN_COLOR_SQUARES:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
|
||||
break;
|
||||
case DP_TEST_PATTERN_VERTICAL_BARS:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
|
||||
break;
|
||||
case DP_TEST_PATTERN_HORIZONTAL_BARS:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_RAMP:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
|
||||
break;
|
||||
default:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
|
||||
break;
|
||||
}
|
||||
resource_build_test_pattern_params(&link->dc->current_state->res_ctx,
|
||||
pipe_ctx);
|
||||
controller_test_pattern = pipe_ctx->stream_res.test_pattern_params.test_pattern;
|
||||
|
||||
switch (test_pattern) {
|
||||
case DP_TEST_PATTERN_COLOR_SQUARES:
|
||||
|
@ -490,51 +454,29 @@ static void set_crtc_test_pattern(struct dc_link *link,
|
|||
enum controller_dp_color_space controller_color_space;
|
||||
struct output_pixel_processor *odm_opp;
|
||||
|
||||
switch (test_pattern_color_space) {
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_RGB:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_RGB;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR601;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR709;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED:
|
||||
default:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
|
||||
DC_LOG_ERROR("%s: Color space must be defined for test pattern", __func__);
|
||||
controller_color_space = pipe_ctx->stream_res.test_pattern_params.color_space;
|
||||
|
||||
if (controller_color_space == CONTROLLER_DP_COLOR_SPACE_UDEFINED) {
|
||||
DC_LOG_WARNING("%s: Color space must be defined for test pattern", __func__);
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
odm_pipe = pipe_ctx;
|
||||
while (odm_pipe->next_odm_pipe) {
|
||||
while (odm_pipe) {
|
||||
tp_params = &odm_pipe->stream_res.test_pattern_params;
|
||||
odm_opp = odm_pipe->stream_res.opp;
|
||||
odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms);
|
||||
link->dc->hwss.set_disp_pattern_generator(link->dc,
|
||||
odm_pipe,
|
||||
controller_test_pattern,
|
||||
controller_color_space,
|
||||
color_depth,
|
||||
tp_params->test_pattern,
|
||||
tp_params->color_space,
|
||||
tp_params->color_depth,
|
||||
NULL,
|
||||
odm_slice_width,
|
||||
v_active,
|
||||
offset);
|
||||
offset += odm_slice_width;
|
||||
tp_params->width,
|
||||
tp_params->height,
|
||||
tp_params->offset);
|
||||
odm_pipe = odm_pipe->next_odm_pipe;
|
||||
}
|
||||
odm_opp = odm_pipe->stream_res.opp;
|
||||
odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms);
|
||||
link->dc->hwss.set_disp_pattern_generator(link->dc,
|
||||
odm_pipe,
|
||||
controller_test_pattern,
|
||||
controller_color_space,
|
||||
color_depth,
|
||||
NULL,
|
||||
last_odm_slice_width,
|
||||
v_active,
|
||||
offset);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -552,32 +494,21 @@ static void set_crtc_test_pattern(struct dc_link *link,
|
|||
struct output_pixel_processor *odm_opp;
|
||||
|
||||
odm_pipe = pipe_ctx;
|
||||
while (odm_pipe->next_odm_pipe) {
|
||||
while (odm_pipe) {
|
||||
tp_params = &odm_pipe->stream_res.test_pattern_params;
|
||||
odm_opp = odm_pipe->stream_res.opp;
|
||||
odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms);
|
||||
link->dc->hwss.set_disp_pattern_generator(link->dc,
|
||||
odm_pipe,
|
||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
|
||||
CONTROLLER_DP_COLOR_SPACE_UDEFINED,
|
||||
color_depth,
|
||||
tp_params->test_pattern,
|
||||
tp_params->color_space,
|
||||
tp_params->color_depth,
|
||||
NULL,
|
||||
odm_slice_width,
|
||||
v_active,
|
||||
offset);
|
||||
offset += odm_slice_width;
|
||||
tp_params->width,
|
||||
tp_params->height,
|
||||
tp_params->offset);
|
||||
odm_pipe = odm_pipe->next_odm_pipe;
|
||||
}
|
||||
odm_opp = odm_pipe->stream_res.opp;
|
||||
odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms);
|
||||
link->dc->hwss.set_disp_pattern_generator(link->dc,
|
||||
odm_pipe,
|
||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
|
||||
CONTROLLER_DP_COLOR_SPACE_UDEFINED,
|
||||
color_depth,
|
||||
NULL,
|
||||
last_odm_slice_width,
|
||||
v_active,
|
||||
offset);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue