aboutsummaryrefslogtreecommitdiffstats
path: root/queue-6.15/drm-amd-display-optimize-custom-brightness-curve.patch
diff options
Diffstat (limited to 'queue-6.15/drm-amd-display-optimize-custom-brightness-curve.patch')
-rw-r--r--queue-6.15/drm-amd-display-optimize-custom-brightness-curve.patch110
1 files changed, 110 insertions, 0 deletions
diff --git a/queue-6.15/drm-amd-display-optimize-custom-brightness-curve.patch b/queue-6.15/drm-amd-display-optimize-custom-brightness-curve.patch
new file mode 100644
index 0000000000..146411a9db
--- /dev/null
+++ b/queue-6.15/drm-amd-display-optimize-custom-brightness-curve.patch
@@ -0,0 +1,110 @@
+From 6e1e126b02f71ac44a77136dcc8f208dc63aadba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 12:57:25 -0500
+Subject: drm/amd/display: Optimize custom brightness curve
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[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>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 53 ++++++++++++-------
+ 1 file 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 e61166a8230b6..a9a719f051f90 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -4655,41 +4655,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,
+--
+2.39.5
+