Convert the AMD display driver to the DRM backlight infrastructure so brightness can be controlled through the connector LUMINANCE property. Link the registered backlight_device to the eDP connector and unlink it on teardown; the DRM core owns the embedded backlight state and its property, so no explicit allocation or failure handling is needed.
Signed-off-by: Mario Limonciello (AMD) <[email protected]> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++++++++--- .../display/amdgpu_dm/amdgpu_dm_backlight.c | 23 ++++++++++++++++--- .../display/amdgpu_dm/amdgpu_dm_connector.c | 2 ++ 3 files changed, 34 insertions(+), 6 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 2fe934036e363..f7b1eaf34b59d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5050,10 +5050,21 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_commit *state) old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); } + /* + * Apply the LUMINANCE property first: a brightness-only commit + * does not pull the CRTC into the atomic state (so new_crtc_state + * is NULL), and a modeset is skipped below - in both cases the + * backlight must still follow the requested luminance. + */ + drm_atomic_helper_connector_apply_luminance(new_con_state); + /* Skip any modesets/resets */ - if (!acrtc || drm_atomic_crtc_needs_modeset(new_crtc_state)) + if (!acrtc || !new_crtc_state || + drm_atomic_crtc_needs_modeset(new_crtc_state)) continue; + drm_connector_update_privacy_screen(new_con_state); + dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); @@ -5133,8 +5144,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_commit *state) &stream_update); mutex_unlock(&dm->dc_lock); kfree(dummy_updates); - - drm_connector_update_privacy_screen(new_con_state); } /** diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c index 406a821d03cd6..1fefe3837e4cf 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c @@ -40,6 +40,7 @@ #include <linux/backlight.h> #include <linux/power_supply.h> +#include <drm/drm_backlight.h> #include <drm/drm_edid.h> #include <drm/drm_utils.h> @@ -224,13 +225,17 @@ struct dc_stream_state *dm_find_stream_with_link( struct amdgpu_display_manager *dm, struct dc_link *link) { - struct dc_state *cur_dc_state = dm->dc->current_state; + struct dc_state *cur_dc_state; struct dc_stream_state *stream = NULL; int i; + if (!dm || !dm->dc || !dm->dc->current_state || !link) + return NULL; + + cur_dc_state = dm->dc->current_state; for (i = 0; i < cur_dc_state->stream_count; i++) { stream = cur_dc_state->streams[i]; - if (stream->link == link) + if (stream && stream->link == link) return stream; } @@ -284,7 +289,7 @@ void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm, dm->brightness[bl_idx] = user_brightness; /* update scratch register */ - if (bl_idx == 0) + if (bl_idx == 0 && dm->adev && dm->adev->rmmio && dm->adev->bios_scratch_reg_offset) amdgpu_atombios_scratch_regs_set_backlight_level(dm->adev, dm->brightness[bl_idx]); brightness = convert_brightness_from_user(caps, dm->brightness[bl_idx]); link = (struct dc_link *)dm->backlight_link[bl_idx]; @@ -496,6 +501,9 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) dm->actual_brightness[aconnector->bl_idx] = real_brightness; dm->brightness[aconnector->bl_idx] = real_brightness; } + /* Link the registered backlight device to the DRM connector. */ + drm_backlight_link(&aconnector->base, dm->backlight_dev[aconnector->bl_idx]); + drm_dbg_driver(drm, "DM: Registered Backlight device: %s\n", bl_name); } } @@ -582,6 +590,8 @@ void amdgpu_dm_setup_backlight_device(struct amdgpu_display_manager *dm, { struct dc_link *link = aconnector->dc_link; int bl_idx = dm->num_of_edps; + struct backlight_properties props = { 0 }; + struct amdgpu_dm_backlight_caps *caps; if (!(link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) || link->type == dc_connection_none) @@ -600,6 +610,13 @@ void amdgpu_dm_setup_backlight_device(struct amdgpu_display_manager *dm, amdgpu_dm_update_connector_ext_caps(aconnector); + caps = &dm->backlight_caps[bl_idx]; + amdgpu_dm_backlight_fill_props(caps, power_supply_is_system_supplied() > 0, + !(amdgpu_dc_debug_mask & + DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE), + &props); + drm_backlight_create_property(&aconnector->base, props.max_brightness, false); + /* Offer ABM property when user didn't turn off by module parameter. * OLED panels are included to support CACP (Content Adaptive * Contrast and Power) feature via set_abm_level. diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c index c8a1ab8c3b169..fe4ab55f5130f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c @@ -58,6 +58,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_uapi.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_backlight.h> #include <drm/drm_edid.h> #include <drm/drm_eld.h> #include <drm/drm_fixed.h> @@ -1911,6 +1912,7 @@ STATIC_IFN_KUNIT void amdgpu_dm_connector_destroy(struct drm_connector *connecto } if (aconnector->bl_idx != -1) { + drm_backlight_link(&aconnector->base, NULL); backlight_device_unregister(dm->backlight_dev[aconnector->bl_idx]); dm->backlight_dev[aconnector->bl_idx] = NULL; } -- 2.43.0
