Skip to content

Commit 0c0a194

Browse files
Chris Parkalexdeucher
authored andcommitted
drm/amd/display: Add hblank borrowing support
[WHY] Some DSC timing failed at bandwidth validation due to hactive can't be evenly divided on each ODM segment. [HOW] Borrow from hblank to increase hactive to support these timing. Cc: Mario Limonciello <mario.limonciello@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org Reviewed-by: Wenjing Liu <wenjing.liu@amd.com> Signed-off-by: Chris Park <chris.park@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent a29997b commit 0c0a194

File tree

9 files changed

+75
-7
lines changed

9 files changed

+75
-7
lines changed

drivers/gpu/drm/amd/display/dc/core/dc_resource.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2094,7 +2094,8 @@ int resource_get_odm_slice_dst_width(struct pipe_ctx *otg_master,
20942094
count = resource_get_odm_slice_count(otg_master);
20952095
h_active = timing->h_addressable +
20962096
timing->h_border_left +
2097-
timing->h_border_right;
2097+
timing->h_border_right +
2098+
otg_master->hblank_borrow;
20982099
width = h_active / count;
20992100

21002101
if (otg_master->stream_res.tg)
@@ -4026,6 +4027,41 @@ enum dc_status dc_validate_with_context(struct dc *dc,
40264027
return res;
40274028
}
40284029

4030+
/**
4031+
* decide_hblank_borrow - Decides the horizontal blanking borrow value for a given pipe context.
4032+
* @pipe_ctx: Pointer to the pipe context structure.
4033+
*
4034+
* This function calculates the horizontal blanking borrow value for a given pipe context based on the
4035+
* display stream compression (DSC) configuration. If the horizontal active pixels (hactive) are less
4036+
* than the total width of the DSC slices, it sets the hblank_borrow value to the difference. If the
4037+
* total horizontal timing minus the hblank_borrow value is less than 32, it resets the hblank_borrow
4038+
* value to 0.
4039+
*/
4040+
static void decide_hblank_borrow(struct pipe_ctx *pipe_ctx)
4041+
{
4042+
uint32_t hactive;
4043+
uint32_t ceil_slice_width;
4044+
struct dc_stream_state *stream = NULL;
4045+
4046+
if (!pipe_ctx)
4047+
return;
4048+
4049+
stream = pipe_ctx->stream;
4050+
4051+
if (stream->timing.flags.DSC) {
4052+
hactive = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
4053+
4054+
/* Assume if determined slices does not divide Hactive evenly, Hborrow is needed for padding*/
4055+
if (hactive % stream->timing.dsc_cfg.num_slices_h != 0) {
4056+
ceil_slice_width = (hactive / stream->timing.dsc_cfg.num_slices_h) + 1;
4057+
pipe_ctx->hblank_borrow = ceil_slice_width * stream->timing.dsc_cfg.num_slices_h - hactive;
4058+
4059+
if (stream->timing.h_total - hactive - pipe_ctx->hblank_borrow < 32)
4060+
pipe_ctx->hblank_borrow = 0;
4061+
}
4062+
}
4063+
}
4064+
40294065
/**
40304066
* dc_validate_global_state() - Determine if hardware can support a given state
40314067
*
@@ -4064,6 +4100,10 @@ enum dc_status dc_validate_global_state(
40644100
if (pipe_ctx->stream != stream)
40654101
continue;
40664102

4103+
/* Decide whether hblank borrow is needed and save it in pipe_ctx */
4104+
if (dc->debug.enable_hblank_borrow)
4105+
decide_hblank_borrow(pipe_ctx);
4106+
40674107
if (dc->res_pool->funcs->patch_unknown_plane_state &&
40684108
pipe_ctx->plane_state &&
40694109
pipe_ctx->plane_state->tiling_info.gfx9.swizzle == DC_SW_UNKNOWN) {

drivers/gpu/drm/amd/display/dc/dc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,7 @@ struct dc_debug_options {
10691069
unsigned int scale_to_sharpness_policy;
10701070
bool skip_full_updated_if_possible;
10711071
unsigned int enable_oled_edp_power_up_opt;
1072+
bool enable_hblank_borrow;
10721073
};
10731074

10741075

drivers/gpu/drm/amd/display/dc/dc_spl_translate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
120120
spl_in->odm_slice_index = resource_get_odm_slice_index(pipe_ctx);
121121
// Make spl input basic out info output_size width point to stream h active
122122
spl_in->basic_out.output_size.width =
123-
stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
123+
stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right + pipe_ctx->hblank_borrow;
124124
// Make spl input basic out info output_size height point to v active
125125
spl_in->basic_out.output_size.height =
126126
stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;

drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,21 @@ static void populate_dml21_timing_config_from_stream_state(struct dml2_timing_cf
445445
timing->vblank_nom = timing->v_total - timing->v_active;
446446
}
447447

448+
/**
449+
* adjust_dml21_hblank_timing_config_from_pipe_ctx - Adjusts the horizontal blanking timing configuration
450+
* based on the pipe context.
451+
* @timing: Pointer to the dml2_timing_cfg structure to be adjusted.
452+
* @pipe: Pointer to the pipe_ctx structure containing the horizontal blanking borrow value.
453+
*
454+
* This function modifies the horizontal active and blank end timings by adding and subtracting
455+
* the horizontal blanking borrow value from the pipe context, respectively.
456+
*/
457+
static void adjust_dml21_hblank_timing_config_from_pipe_ctx(struct dml2_timing_cfg *timing, struct pipe_ctx *pipe)
458+
{
459+
timing->h_active += pipe->hblank_borrow;
460+
timing->h_blank_end -= pipe->hblank_borrow;
461+
}
462+
448463
static void populate_dml21_output_config_from_stream_state(struct dml2_link_output_cfg *output,
449464
struct dc_stream_state *stream, const struct pipe_ctx *pipe)
450465
{
@@ -732,6 +747,7 @@ static const struct scaler_data *get_scaler_data_for_plane(
732747
temp_pipe->plane_state = pipe->plane_state;
733748
temp_pipe->plane_res.scl_data.taps = pipe->plane_res.scl_data.taps;
734749
temp_pipe->stream_res = pipe->stream_res;
750+
temp_pipe->hblank_borrow = pipe->hblank_borrow;
735751
dml_ctx->config.callbacks.build_scaling_params(temp_pipe);
736752
break;
737753
}
@@ -996,6 +1012,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s
9961012

9971013
ASSERT(disp_cfg_stream_location >= 0 && disp_cfg_stream_location <= __DML2_WRAPPER_MAX_STREAMS_PLANES__);
9981014
populate_dml21_timing_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].timing, context->streams[stream_index], dml_ctx);
1015+
adjust_dml21_hblank_timing_config_from_pipe_ctx(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].timing, &context->res_ctx.pipe_ctx[stream_index]);
9991016
populate_dml21_output_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].output, context->streams[stream_index], &context->res_ctx.pipe_ctx[stream_index]);
10001017
populate_dml21_stream_overrides_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location], context->streams[stream_index]);
10011018

@@ -1134,12 +1151,12 @@ void dml21_populate_pipe_ctx_dlg_params(struct dml2_context *dml_ctx, struct dc_
11341151
struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
11351152
union dml2_global_sync_programming *global_sync = &stream_programming->global_sync;
11361153

1137-
hactive = timing->h_addressable + timing->h_border_left + timing->h_border_right;
1154+
hactive = timing->h_addressable + timing->h_border_left + timing->h_border_right + pipe_ctx->hblank_borrow;
11381155
vactive = timing->v_addressable + timing->v_border_bottom + timing->v_border_top;
11391156
hblank_start = pipe_ctx->stream->timing.h_total - pipe_ctx->stream->timing.h_front_porch;
11401157
vblank_start = pipe_ctx->stream->timing.v_total - pipe_ctx->stream->timing.v_front_porch;
11411158

1142-
hblank_end = hblank_start - timing->h_addressable - timing->h_border_left - timing->h_border_right;
1159+
hblank_end = hblank_start - timing->h_addressable - timing->h_border_left - timing->h_border_right - pipe_ctx->hblank_borrow;
11431160
vblank_end = vblank_start - timing->v_addressable - timing->v_border_top - timing->v_border_bottom;
11441161

11451162
if (dml_ctx->config.svp_pstate.callbacks.get_pipe_subvp_type(context, pipe_ctx) == SUBVP_PHANTOM) {

drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1049,7 +1049,8 @@ void dcn32_update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
10491049
}
10501050

10511051
/* Enable DSC hw block */
1052-
dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
1052+
dsc_cfg.pic_width = (stream->timing.h_addressable + pipe_ctx->hblank_borrow +
1053+
stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
10531054
dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
10541055
dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
10551056
dsc_cfg.color_depth = stream->timing.display_color_depth;

drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,7 @@ enum dc_status dcn401_enable_stream_timing(
820820
int opp_cnt = 1;
821821
int opp_inst[MAX_PIPES] = {0};
822822
struct pipe_ctx *opp_heads[MAX_PIPES] = {0};
823+
struct dc_crtc_timing patched_crtc_timing = stream->timing;
823824
bool manual_mode;
824825
unsigned int tmds_div = PIXEL_RATE_DIV_NA;
825826
unsigned int unused_div = PIXEL_RATE_DIV_NA;
@@ -874,9 +875,13 @@ enum dc_status dcn401_enable_stream_timing(
874875
if (dc->hwseq->funcs.PLAT_58856_wa && (!dc_is_dp_signal(stream->signal)))
875876
dc->hwseq->funcs.PLAT_58856_wa(context, pipe_ctx);
876877

878+
/* if we are borrowing from hblank, h_addressable needs to be adjusted */
879+
if (dc->debug.enable_hblank_borrow)
880+
patched_crtc_timing.h_addressable = patched_crtc_timing.h_addressable + pipe_ctx->hblank_borrow;
881+
877882
pipe_ctx->stream_res.tg->funcs->program_timing(
878883
pipe_ctx->stream_res.tg,
879-
&stream->timing,
884+
&patched_crtc_timing,
880885
pipe_ctx->pipe_dlg_param.vready_offset,
881886
pipe_ctx->pipe_dlg_param.vstartup_start,
882887
pipe_ctx->pipe_dlg_param.vupdate_offset,

drivers/gpu/drm/amd/display/dc/inc/core_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,8 @@ struct pipe_ctx {
478478
/* subvp_index: only valid if the pipe is a SUBVP_MAIN*/
479479
uint8_t subvp_index;
480480
struct pixel_rate_divider pixel_rate_divider;
481+
/* pixels borrowed from hblank to hactive */
482+
uint8_t hblank_borrow;
481483
};
482484

483485
/* Data used for dynamic link encoder assignment.

drivers/gpu/drm/amd/display/dc/link/link_dpms.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,8 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
808808
enum optc_dsc_mode optc_dsc_mode;
809809

810810
/* Enable DSC hw block */
811-
dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
811+
dsc_cfg.pic_width = (stream->timing.h_addressable + pipe_ctx->hblank_borrow +
812+
stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
812813
dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
813814
dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
814815
dsc_cfg.color_depth = stream->timing.display_color_depth;

drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2804,6 +2804,7 @@ struct pipe_ctx *dcn32_acquire_free_pipe_as_secondary_opp_head(
28042804
free_pipe->plane_res.xfm = pool->transforms[free_pipe_idx];
28052805
free_pipe->plane_res.dpp = pool->dpps[free_pipe_idx];
28062806
free_pipe->plane_res.mpcc_inst = pool->dpps[free_pipe_idx]->inst;
2807+
free_pipe->hblank_borrow = otg_master->hblank_borrow;
28072808
if (free_pipe->stream->timing.flags.DSC == 1) {
28082809
dcn20_acquire_dsc(free_pipe->stream->ctx->dc,
28092810
&new_ctx->res_ctx,

0 commit comments

Comments
 (0)