aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMario Limonciello <mario.limonciello@amd.com>2025-03-24 12:57:25 -0500
committerAlex Deucher <alexander.deucher@amd.com>2025-04-07 18:01:07 -0400
commit03b979e1025fba1d47cae005022fcdbba140f043 (patch)
tree4f5f898051d3576eb055750e13b2ed3bfed19f99
parentdrm/amdgpu: Fix CPER error handling on VFs (diff)
downloadwireguard-linux-03b979e1025fba1d47cae005022fcdbba140f043.tar.xz
wireguard-linux-03b979e1025fba1d47cae005022fcdbba140f043.zip
drm/amd/display: Optimize custom brightness curve
[Why] When BIOS includes a lot of custom brightness data points, walking the entire list can be time consuming. This is most noticed when dragging a power slider. The "higher" values are "slower" to drag around. [How] Move custom brightness calculation loop into a static function. Before starting the loop check the "half way" data point to see how it compares to the input. If greater than the half way data point use that as the starting point instead. Reviewed-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Roman Li <roman.li@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c53
1 files changed, 33 insertions, 20 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f8847cf10dbd..f1de629c7637 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4826,41 +4826,54 @@ static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
return 1;
}
-static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps,
- uint32_t brightness)
+static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps,
+ uint32_t *brightness)
{
- unsigned int min, max;
u8 prev_signal = 0, prev_lum = 0;
+ int i = 0;
- if (!get_brightness_range(caps, &min, &max))
- return brightness;
-
- for (int i = 0; i < caps->data_points; i++) {
- u8 signal, lum;
+ if (amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)
+ return;
- if (amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)
- break;
+ if (!caps->data_points)
+ return;
- signal = caps->luminance_data[i].input_signal;
- lum = caps->luminance_data[i].luminance;
+ /* choose start to run less interpolation steps */
+ if (caps->luminance_data[caps->data_points/2].input_signal > *brightness)
+ i = caps->data_points/2;
+ do {
+ u8 signal = caps->luminance_data[i].input_signal;
+ u8 lum = caps->luminance_data[i].luminance;
/*
* brightness == signal: luminance is percent numerator
* brightness < signal: interpolate between previous and current luminance numerator
* brightness > signal: find next data point
*/
- if (brightness < signal)
- lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) *
- (brightness - prev_signal),
- signal - prev_signal);
- else if (brightness > signal) {
+ if (*brightness > signal) {
prev_signal = signal;
prev_lum = lum;
+ i++;
continue;
}
- brightness = DIV_ROUND_CLOSEST(lum * brightness, 101);
- break;
- }
+ if (*brightness < signal)
+ lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) *
+ (*brightness - prev_signal),
+ signal - prev_signal);
+ *brightness = DIV_ROUND_CLOSEST(lum * *brightness, 101);
+ return;
+ } while (i < caps->data_points);
+}
+
+static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps,
+ uint32_t brightness)
+{
+ unsigned int min, max;
+
+ if (!get_brightness_range(caps, &min, &max))
+ return brightness;
+
+ convert_custom_brightness(caps, &brightness);
// Rescale 0..255 to min..max
return min + DIV_ROUND_CLOSEST((max - min) * brightness,