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

Reply via email to