mirror of
https://github.com/torvalds/linux.git
synced 2025-08-16 06:31:34 +02:00
drm/amd/display: Export full brightness range to userspace
[WHY]
Userspace currently is offered a range from 0-0xFF but the PWM is
programmed from 0-0xFFFF. This can be limiting to some software
that wants to apply greater granularity.
[HOW]
Convert internally to firmware values only when mapping custom
brightness curves because these are in 0-0xFF range. Advertise full
PWM range to userspace.
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Roman Li <roman.li@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@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>
(cherry picked from commit 8dbd72cb79
)
Cc: stable@vger.kernel.org
This commit is contained in:
parent
ffcaed1d7e
commit
16dc8bc27c
1 changed files with 28 additions and 15 deletions
|
@ -4718,9 +4718,23 @@ static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps,
|
||||
uint32_t *brightness)
|
||||
/* Rescale from [min..max] to [0..AMDGPU_MAX_BL_LEVEL] */
|
||||
static inline u32 scale_input_to_fw(int min, int max, u64 input)
|
||||
{
|
||||
return DIV_ROUND_CLOSEST_ULL(input * AMDGPU_MAX_BL_LEVEL, max - min);
|
||||
}
|
||||
|
||||
/* Rescale from [0..AMDGPU_MAX_BL_LEVEL] to [min..max] */
|
||||
static inline u32 scale_fw_to_input(int min, int max, u64 input)
|
||||
{
|
||||
return min + DIV_ROUND_CLOSEST_ULL(input * (max - min), AMDGPU_MAX_BL_LEVEL);
|
||||
}
|
||||
|
||||
static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps,
|
||||
unsigned int min, unsigned int max,
|
||||
uint32_t *user_brightness)
|
||||
{
|
||||
u32 brightness = scale_input_to_fw(min, max, *user_brightness);
|
||||
u8 prev_signal = 0, prev_lum = 0;
|
||||
int i = 0;
|
||||
|
||||
|
@ -4731,7 +4745,7 @@ static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *cap
|
|||
return;
|
||||
|
||||
/* choose start to run less interpolation steps */
|
||||
if (caps->luminance_data[caps->data_points/2].input_signal > *brightness)
|
||||
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;
|
||||
|
@ -4742,17 +4756,18 @@ static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *cap
|
|||
* brightness < signal: interpolate between previous and current luminance numerator
|
||||
* brightness > signal: find next data point
|
||||
*/
|
||||
if (*brightness > signal) {
|
||||
if (brightness > signal) {
|
||||
prev_signal = signal;
|
||||
prev_lum = lum;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (*brightness < signal)
|
||||
if (brightness < signal)
|
||||
lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) *
|
||||
(*brightness - prev_signal),
|
||||
(brightness - prev_signal),
|
||||
signal - prev_signal);
|
||||
*brightness = DIV_ROUND_CLOSEST(lum * *brightness, 101);
|
||||
*user_brightness = scale_fw_to_input(min, max,
|
||||
DIV_ROUND_CLOSEST(lum * brightness, 101));
|
||||
return;
|
||||
} while (i < caps->data_points);
|
||||
}
|
||||
|
@ -4765,11 +4780,10 @@ static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *c
|
|||
if (!get_brightness_range(caps, &min, &max))
|
||||
return brightness;
|
||||
|
||||
convert_custom_brightness(caps, &brightness);
|
||||
convert_custom_brightness(caps, min, max, &brightness);
|
||||
|
||||
// Rescale 0..255 to min..max
|
||||
return min + DIV_ROUND_CLOSEST((max - min) * brightness,
|
||||
AMDGPU_MAX_BL_LEVEL);
|
||||
// Rescale 0..max to min..max
|
||||
return min + DIV_ROUND_CLOSEST_ULL((u64)(max - min) * brightness, max);
|
||||
}
|
||||
|
||||
static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *caps,
|
||||
|
@ -4782,8 +4796,8 @@ static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *cap
|
|||
|
||||
if (brightness < min)
|
||||
return 0;
|
||||
// Rescale min..max to 0..255
|
||||
return DIV_ROUND_CLOSEST(AMDGPU_MAX_BL_LEVEL * (brightness - min),
|
||||
// Rescale min..max to 0..max
|
||||
return DIV_ROUND_CLOSEST_ULL((u64)max * (brightness - min),
|
||||
max - min);
|
||||
}
|
||||
|
||||
|
@ -4933,11 +4947,10 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
|
|||
drm_dbg(drm, "Backlight caps: min: %d, max: %d, ac %d, dc %d\n", min, max,
|
||||
caps->ac_level, caps->dc_level);
|
||||
} else
|
||||
props.brightness = AMDGPU_MAX_BL_LEVEL;
|
||||
props.brightness = props.max_brightness = AMDGPU_MAX_BL_LEVEL;
|
||||
|
||||
if (caps->data_points && !(amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE))
|
||||
drm_info(drm, "Using custom brightness curve\n");
|
||||
props.max_brightness = AMDGPU_MAX_BL_LEVEL;
|
||||
props.type = BACKLIGHT_RAW;
|
||||
|
||||
snprintf(bl_name, sizeof(bl_name), "amdgpu_bl%d",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue