Skip to content

Commit 3556dac

Browse files
Dillon Varonealexdeucher
authored andcommitted
drm/amd/display: Fix divide by zero when calculating min ODM factor
[WHY&HOW] If the debug option is set to disable_dsc the max slice width and/or dispclk can be zero. This causes a divide by zero when calculating the min ODM combine factor. Add a check to ensure they are valid first. Reviewed-by: Wenjing Liu <[email protected]> Signed-off-by: Dillon Varone <[email protected]> Signed-off-by: Wayne Lin <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Cc: [email protected]
1 parent ba0f4c4 commit 3556dac

File tree

1 file changed

+15
-14
lines changed
  • drivers/gpu/drm/amd/display/dc/dsc

1 file changed

+15
-14
lines changed

drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
152152
}
153153

154154
/* Forward Declerations */
155-
static unsigned int get_min_slice_count_for_odm(
155+
static unsigned int get_min_dsc_slice_count_for_odm(
156156
const struct display_stream_compressor *dsc,
157157
const struct dsc_enc_caps *dsc_enc_caps,
158158
const struct dc_crtc_timing *timing);
@@ -466,7 +466,7 @@ bool dc_dsc_compute_bandwidth_range(
466466
struct dc_dsc_bw_range *range)
467467
{
468468
bool is_dsc_possible = false;
469-
unsigned int min_slice_count;
469+
unsigned int min_dsc_slice_count;
470470
struct dsc_enc_caps dsc_enc_caps;
471471
struct dsc_enc_caps dsc_common_caps;
472472
struct dc_dsc_config config = {0};
@@ -478,14 +478,14 @@ bool dc_dsc_compute_bandwidth_range(
478478

479479
get_dsc_enc_caps(dsc, &dsc_enc_caps, timing->pix_clk_100hz);
480480

481-
min_slice_count = get_min_slice_count_for_odm(dsc, &dsc_enc_caps, timing);
481+
min_dsc_slice_count = get_min_dsc_slice_count_for_odm(dsc, &dsc_enc_caps, timing);
482482

483483
is_dsc_possible = intersect_dsc_caps(dsc_sink_caps, &dsc_enc_caps,
484484
timing->pixel_encoding, &dsc_common_caps);
485485

486486
if (is_dsc_possible)
487487
is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, 0, timing,
488-
&options, link_encoding, min_slice_count, &config);
488+
&options, link_encoding, min_dsc_slice_count, &config);
489489

490490
if (is_dsc_possible)
491491
is_dsc_possible = decide_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16,
@@ -593,14 +593,12 @@ static void build_dsc_enc_caps(
593593

594594
struct dc *dc;
595595

596-
memset(&single_dsc_enc_caps, 0, sizeof(struct dsc_enc_caps));
597-
598596
if (!dsc || !dsc->ctx || !dsc->ctx->dc || !dsc->funcs->dsc_get_single_enc_caps)
599597
return;
600598

601599
dc = dsc->ctx->dc;
602600

603-
if (!dc->clk_mgr || !dc->clk_mgr->funcs->get_max_clock_khz || !dc->res_pool)
601+
if (!dc->clk_mgr || !dc->clk_mgr->funcs->get_max_clock_khz || !dc->res_pool || dc->debug.disable_dsc)
604602
return;
605603

606604
/* get max DSCCLK from clk_mgr */
@@ -634,7 +632,7 @@ static inline uint32_t dsc_div_by_10_round_up(uint32_t value)
634632
return (value + 9) / 10;
635633
}
636634

637-
static unsigned int get_min_slice_count_for_odm(
635+
static unsigned int get_min_dsc_slice_count_for_odm(
638636
const struct display_stream_compressor *dsc,
639637
const struct dsc_enc_caps *dsc_enc_caps,
640638
const struct dc_crtc_timing *timing)
@@ -651,6 +649,10 @@ static unsigned int get_min_slice_count_for_odm(
651649
}
652650
}
653651

652+
/* validate parameters */
653+
if (max_dispclk_khz == 0 || dsc_enc_caps->max_slice_width == 0)
654+
return 1;
655+
654656
/* consider minimum odm slices required due to
655657
* 1) display pipe throughput (dispclk)
656658
* 2) max image width per slice
@@ -669,13 +671,12 @@ static void get_dsc_enc_caps(
669671
{
670672
memset(dsc_enc_caps, 0, sizeof(struct dsc_enc_caps));
671673

672-
if (!dsc)
674+
if (!dsc || !dsc->ctx || !dsc->ctx->dc || dsc->ctx->dc->debug.disable_dsc)
673675
return;
674676

675677
/* check if reported cap global or only for a single DCN DSC enc */
676678
if (dsc->funcs->dsc_get_enc_caps) {
677-
if (!dsc->ctx->dc->debug.disable_dsc)
678-
dsc->funcs->dsc_get_enc_caps(dsc_enc_caps, pixel_clock_100Hz);
679+
dsc->funcs->dsc_get_enc_caps(dsc_enc_caps, pixel_clock_100Hz);
679680
} else {
680681
build_dsc_enc_caps(dsc, dsc_enc_caps);
681682
}
@@ -1295,18 +1296,18 @@ bool dc_dsc_compute_config(
12951296
{
12961297
bool is_dsc_possible = false;
12971298
struct dsc_enc_caps dsc_enc_caps;
1298-
unsigned int min_slice_count;
1299+
unsigned int min_dsc_slice_count;
12991300
get_dsc_enc_caps(dsc, &dsc_enc_caps, timing->pix_clk_100hz);
13001301

1301-
min_slice_count = get_min_slice_count_for_odm(dsc, &dsc_enc_caps, timing);
1302+
min_dsc_slice_count = get_min_dsc_slice_count_for_odm(dsc, &dsc_enc_caps, timing);
13021303

13031304
is_dsc_possible = setup_dsc_config(dsc_sink_caps,
13041305
&dsc_enc_caps,
13051306
target_bandwidth_kbps,
13061307
timing,
13071308
options,
13081309
link_encoding,
1309-
min_slice_count,
1310+
min_dsc_slice_count,
13101311
dsc_cfg);
13111312
return is_dsc_possible;
13121313
}

0 commit comments

Comments
 (0)