From 21fc0ff38f571debdba6aaff944addb50f49a7f7 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Mon, 3 Apr 2023 17:45:41 +0800 Subject: drm/amd/display: fix a divided-by-zero error [Why & How] timing.dsc_cfg.num_slices_v can be zero and it is necessary to check before using it. This fixes the error "divide error: 0000 [#1] PREEMPT SMP NOPTI". Reviewed-by: Aurabindo Pillai Acked-by: Qingqing Zhuo Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/modules/power/power_helpers.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/amd/display/modules') diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index 0d3a983cb9ec..51e76bce92ea 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -927,6 +927,10 @@ bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link, pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom; + + if (stream->timing.dsc_cfg.num_slices_v == 0) + return false; + slice_height = pic_height / stream->timing.dsc_cfg.num_slices_v; config->dsc_slice_height = slice_height; -- cgit v1.2.3 From 94344e62a9ce8abcf681390f9822a7b075cf98e2 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Fri, 14 Apr 2023 11:08:30 -0400 Subject: drm/amd/display: remove unused variable oldest_index cpp_check reports drivers/gpu/drm/amd/display/modules/freesync/freesync.c:1143:17: style: Variable 'oldest_index' is assigned a value that is never used. [unreadVariable] oldest_index = 0; ^ This variable is not used so remove. Signed-off-by: Tom Rix Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display/modules') diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 5c41a4751db4..5798c0eafa1f 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -1137,10 +1137,6 @@ void mod_freesync_handle_preflip(struct mod_freesync *mod_freesync, if (in_out_vrr->supported && in_out_vrr->state == VRR_STATE_ACTIVE_VARIABLE) { - unsigned int oldest_index = plane->time.index + 1; - - if (oldest_index >= DC_PLANE_UPDATE_TIMES_MAX) - oldest_index = 0; last_render_time_in_us = curr_time_stamp_in_us - plane->time.prev_update_time_in_us; -- cgit v1.2.3 From 5e9252d8415f50095c854c85cf9ebcc894e9ac0d Mon Sep 17 00:00:00 2001 From: Josip Pavic Date: Mon, 3 Apr 2023 10:42:06 -0400 Subject: drm/amd/display: add option to use custom backlight caps [Why & How] Provide option for vendors to specify a custom brightness-to-backlight conversion profile. Tested-by: Daniel Wheeler Reviewed-by: Anthony Koo Acked-by: Rodrigo Siqueira Signed-off-by: Josip Pavic Signed-off-by: Alex Deucher --- .../drm/amd/display/modules/power/power_helpers.c | 43 ++++++++++++++++++++++ .../drm/amd/display/modules/power/power_helpers.h | 3 ++ 2 files changed, 46 insertions(+) (limited to 'drivers/gpu/drm/amd/display/modules') diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index 51e76bce92ea..68d95b92df76 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -116,6 +116,27 @@ static const struct abm_parameters * const abm_settings[] = { abm_settings_config2, }; +const struct dm_bl_data_point custom_backlight_curve0[] = { + {2, 14}, {4, 16}, {6, 18}, {8, 21}, {10, 23}, {12, 26}, {14, 29}, {16, 32}, {18, 35}, + {20, 38}, {22, 41}, {24, 44}, {26, 48}, {28, 52}, {30, 55}, {32, 59}, {34, 62}, + {36, 67}, {38, 71}, {40, 75}, {42, 80}, {44, 84}, {46, 88}, {48, 93}, {50, 98}, + {52, 103}, {54, 108}, {56, 113}, {58, 118}, {60, 123}, {62, 129}, {64, 135}, {66, 140}, + {68, 146}, {70, 152}, {72, 158}, {74, 164}, {76, 171}, {78, 177}, {80, 183}, {82, 190}, + {84, 197}, {86, 204}, {88, 211}, {90, 218}, {92, 225}, {94, 232}, {96, 240}, {98, 247}}; + +struct custom_backlight_profile { + uint8_t ac_level_percentage; + uint8_t dc_level_percentage; + uint8_t min_input_signal; + uint8_t max_input_signal; + uint8_t num_data_points; + const struct dm_bl_data_point *data_points; +}; + +static const struct custom_backlight_profile custom_backlight_profiles[] = { + {100, 32, 12, 255, ARRAY_SIZE(custom_backlight_curve0), custom_backlight_curve0}, +}; + #define NUM_AMBI_LEVEL 5 #define NUM_AGGR_LEVEL 4 #define NUM_POWER_FN_SEGS 8 @@ -944,3 +965,25 @@ bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link, return true; } + +bool fill_custom_backlight_caps(unsigned int config_no, struct dm_acpi_atif_backlight_caps *caps) +{ + unsigned int data_points_size; + + if (config_no >= ARRAY_SIZE(custom_backlight_profiles)) + return false; + + data_points_size = custom_backlight_profiles[config_no].num_data_points + * sizeof(custom_backlight_profiles[config_no].data_points[0]); + + caps->size = sizeof(struct dm_acpi_atif_backlight_caps) - sizeof(caps->data_points) + data_points_size; + caps->flags = 0; + caps->error_code = 0; + caps->ac_level_percentage = custom_backlight_profiles[config_no].ac_level_percentage; + caps->dc_level_percentage = custom_backlight_profiles[config_no].dc_level_percentage; + caps->min_input_signal = custom_backlight_profiles[config_no].min_input_signal; + caps->max_input_signal = custom_backlight_profiles[config_no].max_input_signal; + caps->num_data_points = custom_backlight_profiles[config_no].num_data_points; + memcpy(caps->data_points, custom_backlight_profiles[config_no].data_points, data_points_size); + return true; +} diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h index 1d3079e56799..ffc924c9991b 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h @@ -62,4 +62,7 @@ bool mod_power_only_edp(const struct dc_state *context, bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link, struct dc_stream_state *stream, struct psr_config *config); + +bool fill_custom_backlight_caps(unsigned int config_no, + struct dm_acpi_atif_backlight_caps *caps); #endif /* MODULES_POWER_POWER_HELPERS_H_ */ -- cgit v1.2.3 From 4e004146c0bab0c05d66dc648593e8b7ec3d8df5 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Wed, 26 Apr 2023 07:18:38 -0400 Subject: drm/amd/display: set variable custom_backlight_curve0 storage-class-specifier to static smatch reports drivers/gpu/drm/amd/amdgpu/../display/modules/power/power_helpers.c:119:31: warning: symbol 'custom_backlight_curve0' was not declared. Should it be static? This variable is only used in its defining file, so it should be static Signed-off-by: Tom Rix Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/modules/power/power_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/modules') diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index 68d95b92df76..30349881a283 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -116,7 +116,7 @@ static const struct abm_parameters * const abm_settings[] = { abm_settings_config2, }; -const struct dm_bl_data_point custom_backlight_curve0[] = { +static const struct dm_bl_data_point custom_backlight_curve0[] = { {2, 14}, {4, 16}, {6, 18}, {8, 21}, {10, 23}, {12, 26}, {14, 29}, {16, 32}, {18, 35}, {20, 38}, {22, 41}, {24, 44}, {26, 48}, {28, 52}, {30, 55}, {32, 59}, {34, 62}, {36, 67}, {38, 71}, {40, 75}, {42, 80}, {44, 84}, {46, 88}, {48, 93}, {50, 98}, -- cgit v1.2.3 From da55037afde24d74a1a3f26e4d314f897f3432b4 Mon Sep 17 00:00:00 2001 From: Austin Zheng Date: Thu, 1 Jun 2023 15:16:45 -0400 Subject: drm/amd/display: Limit Minimum FreeSync Refresh Rate Why: Some EDIDs report a minimum refresh rate lower than what HW can support How: Add a check to calculate minimum supported refresh rate with current timing and use that as the minimum if a lower one is passed in Acked-by: Stylon Wang Signed-off-by: Austin Zheng Reviewed-by: Anthony Koo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 1 + drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c | 1 + drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c | 1 + drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 1 + drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c | 1 + drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 11 +++++++++-- 7 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display/modules') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 5c906b007e4d..a239dcd8e9fb 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -266,6 +266,7 @@ struct dc_caps { uint16_t subvp_pstate_allow_width_us; uint16_t subvp_vertical_int_margin_us; bool seamless_odm; + uint32_t max_v_total; uint8_t subvp_drr_vblank_start_margin_us; }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index f4ee4b3df596..1a0284a068b2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -2328,6 +2328,7 @@ static bool dcn30_resource_construct( dc->caps.color.mpc.ocsc = 1; dc->caps.dp_hdmi21_pcon_support = true; + dc->caps.max_v_total = (1 << 15) - 1; /* read VBIOS LTTPR caps */ { diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c index 93f42132c900..7dc065ea247a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c @@ -1227,6 +1227,7 @@ static bool dcn302_resource_construct( dc->caps.force_dp_tps4_for_cp2520 = true; dc->caps.extended_aux_timeout_support = true; dc->caps.dmcub_support = true; + dc->caps.max_v_total = (1 << 15) - 1; /* Color pipeline capabilities */ dc->caps.color.dpp.dcn_arch = 1; diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c index f35514188a5c..6d9761395288 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c @@ -1152,6 +1152,7 @@ static bool dcn303_resource_construct( dc->caps.force_dp_tps4_for_cp2520 = true; dc->caps.extended_aux_timeout_support = true; dc->caps.dmcub_support = true; + dc->caps.max_v_total = (1 << 15) - 1; /* Color pipeline capabilities */ dc->caps.color.dpp.dcn_arch = 1; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 8c9e15952a49..19f134caa8ad 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -2175,6 +2175,7 @@ static bool dcn32_resource_construct( dc->caps.extended_aux_timeout_support = true; dc->caps.dmcub_support = true; dc->caps.seamless_odm = true; + dc->caps.max_v_total = (1 << 15) - 1; /* Color pipeline capabilities */ dc->caps.color.dpp.dcn_arch = 1; diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c index ee07ee340171..ea204742ad35 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -1718,6 +1718,7 @@ static bool dcn321_resource_construct( dc->caps.edp_dsc_support = true; dc->caps.extended_aux_timeout_support = true; dc->caps.dmcub_support = true; + dc->caps.max_v_total = (1 << 15) - 1; /* Color pipeline capabilities */ dc->caps.color.dpp.dcn_arch = 1; diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 5798c0eafa1f..dbd60811f95d 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 Advanced Micro Devices, Inc. + * Copyright 2016-2023 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -989,6 +989,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, unsigned int refresh_range = 0; unsigned long long min_refresh_in_uhz = 0; unsigned long long max_refresh_in_uhz = 0; + unsigned long long min_hardware_refresh_in_uhz = 0; if (mod_freesync == NULL) return; @@ -999,7 +1000,13 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, nominal_field_rate_in_uhz = mod_freesync_calc_nominal_field_rate(stream); - min_refresh_in_uhz = in_config->min_refresh_in_uhz; + if (stream->ctx->dc->caps.max_v_total != 0 && stream->timing.h_total != 0) { + min_hardware_refresh_in_uhz = div64_u64((stream->timing.pix_clk_100hz * 100000000ULL), + (stream->timing.h_total * stream->ctx->dc->caps.max_v_total)); + } + /* Limit minimum refresh rate to what can be supported by hardware */ + min_refresh_in_uhz = min_hardware_refresh_in_uhz > in_config->min_refresh_in_uhz ? + min_hardware_refresh_in_uhz : in_config->min_refresh_in_uhz; max_refresh_in_uhz = in_config->max_refresh_in_uhz; /* Full range may be larger than current video timing, so cap at nominal */ -- cgit v1.2.3