[PATCH V2] drm/amdgpu/display: add support for multiple backlights

Li, Roman Roman.Li at amd.com
Tue Jul 27 17:13:22 UTC 2021


[Public]

Reviewed-by: Roman Li <Roman.Li at amd.com>

-----Original Message-----
From: amd-gfx <amd-gfx-bounces at lists.freedesktop.org> On Behalf Of Alex Deucher
Sent: Wednesday, July 14, 2021 3:00 PM
To: amd-gfx at lists.freedesktop.org
Cc: Deucher, Alexander <Alexander.Deucher at amd.com>; kernel test robot <lkp at intel.com>
Subject: [PATCH V2] drm/amdgpu/display: add support for multiple backlights

On platforms that support multiple backlights, register each one separately.  This lets us manage them independently rather than registering a single backlight and applying the same settings to both.

v2: fix typo:
Reported-by: kernel test robot <lkp at intel.com>

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c      |   4 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 147 ++++++++++--------
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   4 +-
 3 files changed, 84 insertions(+), 71 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
index 59373c697b00..9122dcf42c46 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -854,8 +854,8 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
                if (amdgpu_device_has_dc_support(adev)) {  #if defined(CONFIG_DRM_AMD_DC)
                        struct amdgpu_display_manager *dm = &adev->dm;
-                       if (dm->backlight_dev)
-                               atif->bd = dm->backlight_dev;
+                       if (dm->backlight_dev[0])
+                               atif->bd = dm->backlight_dev[0];
 #endif
                } else {
                        struct drm_encoder *tmp;
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 5cdb0e75d36b..2d48bb09645f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2412,6 +2412,7 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
        static const u8 pre_computed_values[] = {
                50, 51, 52, 53, 55, 56, 57, 58, 59, 61, 62, 63, 65, 66, 68, 69,
                71, 72, 74, 75, 77, 79, 81, 82, 84, 86, 88, 90, 92, 94, 96, 98};
+       int i;

        if (!aconnector || !aconnector->dc_link)
                return;
@@ -2423,7 +2424,13 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
        conn_base = &aconnector->base;
        adev = drm_to_adev(conn_base->dev);
        dm = &adev->dm;
-       caps = &dm->backlight_caps;
+       for (i = 0; i < dm->num_of_edps; i++) {
+               if (link == dm->backlight_link[i])
+                       break;
+       }
+       if (i >= dm->num_of_edps)
+               return;
+       caps = &dm->backlight_caps[i];
        caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps;
        caps->aux_support = false;
        max_cll = conn_base->hdr_sink_metadata.hdmi_type1.max_cll;
@@ -3423,35 +3430,36 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)  #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
        defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)

-static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm)
+static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm,
+                                           int bl_idx)
 {
 #if defined(CONFIG_ACPI)
        struct amdgpu_dm_backlight_caps caps;

        memset(&caps, 0, sizeof(caps));

-       if (dm->backlight_caps.caps_valid)
+       if (dm->backlight_caps[bl_idx].caps_valid)
                return;

        amdgpu_acpi_get_backlight_caps(&caps);
        if (caps.caps_valid) {
-               dm->backlight_caps.caps_valid = true;
+               dm->backlight_caps[bl_idx].caps_valid = true;
                if (caps.aux_support)
                        return;
-               dm->backlight_caps.min_input_signal = caps.min_input_signal;
-               dm->backlight_caps.max_input_signal = caps.max_input_signal;
+               dm->backlight_caps[bl_idx].min_input_signal = caps.min_input_signal;
+               dm->backlight_caps[bl_idx].max_input_signal = caps.max_input_signal;
        } else {
-               dm->backlight_caps.min_input_signal =
+               dm->backlight_caps[bl_idx].min_input_signal =
                                AMDGPU_DM_DEFAULT_MIN_BACKLIGHT;
-               dm->backlight_caps.max_input_signal =
+               dm->backlight_caps[bl_idx].max_input_signal =
                                AMDGPU_DM_DEFAULT_MAX_BACKLIGHT;
        }
 #else
-       if (dm->backlight_caps.aux_support)
+       if (dm->backlight_caps[bl_idx].aux_support)
                return;

-       dm->backlight_caps.min_input_signal = AMDGPU_DM_DEFAULT_MIN_BACKLIGHT;
-       dm->backlight_caps.max_input_signal = AMDGPU_DM_DEFAULT_MAX_BACKLIGHT;
+       dm->backlight_caps[bl_idx].min_input_signal = AMDGPU_DM_DEFAULT_MIN_BACKLIGHT;
+       dm->backlight_caps[bl_idx].max_input_signal =
+AMDGPU_DM_DEFAULT_MAX_BACKLIGHT;
 #endif
 }

@@ -3502,41 +3510,31 @@ static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *cap  }

 static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
+                                        int bl_idx,
                                         u32 user_brightness)
 {
        struct amdgpu_dm_backlight_caps caps;
-       struct dc_link *link[AMDGPU_DM_MAX_NUM_EDP];
-       u32 brightness[AMDGPU_DM_MAX_NUM_EDP];
+       struct dc_link *link;
+       u32 brightness;
        bool rc;
-       int i;

-       amdgpu_dm_update_backlight_caps(dm);
-       caps = dm->backlight_caps;
+       amdgpu_dm_update_backlight_caps(dm, bl_idx);
+       caps = dm->backlight_caps[bl_idx];

-       for (i = 0; i < dm->num_of_edps; i++) {
-               dm->brightness[i] = user_brightness;
-               brightness[i] = convert_brightness_from_user(&caps, dm->brightness[i]);
-               link[i] = (struct dc_link *)dm->backlight_link[i];
-       }
+       dm->brightness[bl_idx] = user_brightness;
+       brightness = convert_brightness_from_user(&caps, dm->brightness[bl_idx]);
+       link = (struct dc_link *)dm->backlight_link[bl_idx];

        /* Change brightness based on AUX property */
        if (caps.aux_support) {
-               for (i = 0; i < dm->num_of_edps; i++) {
-                       rc = dc_link_set_backlight_level_nits(link[i], true, brightness[i],
-                               AUX_BL_DEFAULT_TRANSITION_TIME_MS);
-                       if (!rc) {
-                               DRM_DEBUG("DM: Failed to update backlight via AUX on eDP[%d]\n", i);
-                               break;
-                       }
-               }
+               rc = dc_link_set_backlight_level_nits(link, true, brightness,
+                                                     AUX_BL_DEFAULT_TRANSITION_TIME_MS);
+               if (!rc)
+                       DRM_DEBUG("DM: Failed to update backlight via AUX on eDP[%d]\n",
+bl_idx);
        } else {
-               for (i = 0; i < dm->num_of_edps; i++) {
-                       rc = dc_link_set_backlight_level(dm->backlight_link[i], brightness[i], 0);
-                       if (!rc) {
-                               DRM_DEBUG("DM: Failed to update backlight on eDP[%d]\n", i);
-                               break;
-                       }
-               }
+               rc = dc_link_set_backlight_level(link, brightness, 0);
+               if (!rc)
+                       DRM_DEBUG("DM: Failed to update backlight on eDP[%d]\n", bl_idx);
        }

        return rc ? 0 : 1;
@@ -3545,33 +3543,41 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,  static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)  {
        struct amdgpu_display_manager *dm = bl_get_data(bd);
+       int i;

-       amdgpu_dm_backlight_set_level(dm, bd->props.brightness);
+       for (i = 0; i < dm->num_of_edps; i++) {
+               if (bd == dm->backlight_dev[i])
+                       break;
+       }
+       if (i >= AMDGPU_DM_MAX_NUM_EDP)
+               i = 0;
+       amdgpu_dm_backlight_set_level(dm, i, bd->props.brightness);

        return 0;
 }

-static u32 amdgpu_dm_backlight_get_level(struct amdgpu_display_manager *dm)
+static u32 amdgpu_dm_backlight_get_level(struct amdgpu_display_manager *dm,
+                                        int bl_idx)
 {
        struct amdgpu_dm_backlight_caps caps;
+       struct dc_link *link = (struct dc_link *)dm->backlight_link[bl_idx];

-       amdgpu_dm_update_backlight_caps(dm);
-       caps = dm->backlight_caps;
+       amdgpu_dm_update_backlight_caps(dm, bl_idx);
+       caps = dm->backlight_caps[bl_idx];

        if (caps.aux_support) {
-               struct dc_link *link = (struct dc_link *)dm->backlight_link[0];
                u32 avg, peak;
                bool rc;

                rc = dc_link_get_backlight_level_nits(link, &avg, &peak);
                if (!rc)
-                       return dm->brightness[0];
+                       return dm->brightness[bl_idx];
                return convert_brightness_to_user(&caps, avg);
        } else {
-               int ret = dc_link_get_backlight_level(dm->backlight_link[0]);
+               int ret = dc_link_get_backlight_level(link);

                if (ret == DC_ERROR_UNEXPECTED)
-                       return dm->brightness[0];
+                       return dm->brightness[bl_idx];
                return convert_brightness_to_user(&caps, ret);
        }
 }
@@ -3579,8 +3585,15 @@ static u32 amdgpu_dm_backlight_get_level(struct amdgpu_display_manager *dm)  static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd)  {
        struct amdgpu_display_manager *dm = bl_get_data(bd);
+       int i;

-       return amdgpu_dm_backlight_get_level(dm);
+       for (i = 0; i < dm->num_of_edps; i++) {
+               if (bd == dm->backlight_dev[i])
+                       break;
+       }
+       if (i >= AMDGPU_DM_MAX_NUM_EDP)
+               i = 0;
+       return amdgpu_dm_backlight_get_level(dm, i);
 }

 static const struct backlight_ops amdgpu_dm_backlight_ops = { @@ -3594,31 +3607,28 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm)  {
        char bl_name[16];
        struct backlight_properties props = { 0 };
-       int i;

-       amdgpu_dm_update_backlight_caps(dm);
-       for (i = 0; i < dm->num_of_edps; i++)
-               dm->brightness[i] = AMDGPU_MAX_BL_LEVEL;
+       amdgpu_dm_update_backlight_caps(dm, dm->num_of_edps);
+       dm->brightness[dm->num_of_edps] = AMDGPU_MAX_BL_LEVEL;

        props.max_brightness = AMDGPU_MAX_BL_LEVEL;
        props.brightness = AMDGPU_MAX_BL_LEVEL;
        props.type = BACKLIGHT_RAW;

        snprintf(bl_name, sizeof(bl_name), "amdgpu_bl%d",
-                adev_to_drm(dm->adev)->primary->index);
+                adev_to_drm(dm->adev)->primary->index + dm->num_of_edps);

-       dm->backlight_dev = backlight_device_register(bl_name,
-                                                     adev_to_drm(dm->adev)->dev,
-                                                     dm,
-                                                     &amdgpu_dm_backlight_ops,
-                                                     &props);
+       dm->backlight_dev[dm->num_of_edps] = backlight_device_register(bl_name,
+                                                                      adev_to_drm(dm->adev)->dev,
+                                                                      dm,
+                                                                      &amdgpu_dm_backlight_ops,
+                                                                      &props);

-       if (IS_ERR(dm->backlight_dev))
+       if (IS_ERR(dm->backlight_dev[dm->num_of_edps]))
                DRM_ERROR("DM: Backlight registration failed!\n");
        else
                DRM_DEBUG_DRIVER("DM: Registered Backlight device: %s\n", bl_name);  }
-
 #endif

 static int initialize_plane(struct amdgpu_display_manager *dm, @@ -3675,10 +3685,10 @@ static void register_backlight_device(struct amdgpu_display_manager *dm,
                 * DM initialization because not having a backlight control
                 * is better then a black screen.
                 */
-               if (!dm->backlight_dev)
+               if (!dm->backlight_dev[dm->num_of_edps])
                        amdgpu_dm_register_backlight_device(dm);

-               if (dm->backlight_dev) {
+               if (dm->backlight_dev[dm->num_of_edps]) {
                        dm->backlight_link[dm->num_of_edps] = link;
                        dm->num_of_edps++;
                }
@@ -6198,6 +6208,7 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
        const struct dc_link *link = aconnector->dc_link;
        struct amdgpu_device *adev = drm_to_adev(connector->dev);
        struct amdgpu_display_manager *dm = &adev->dm;
+       int i;

        /*
         * Call only if mst_mgr was iniitalized before since it's not done @@ -6208,12 +6219,11 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)

 #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
        defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
-
-       if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) &&
-           link->type != dc_connection_none &&
-           dm->backlight_dev) {
-               backlight_device_unregister(dm->backlight_dev);
-               dm->backlight_dev = NULL;
+       for (i = 0; i < dm->num_of_edps; i++) {
+               if ((link == dm->backlight_link[i]) && dm->backlight_dev[i]) {
+                       backlight_device_unregister(dm->backlight_dev[i]);
+                       dm->backlight_dev[i] = NULL;
+               }
        }
 #endif

@@ -9191,8 +9201,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||          \
        defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
        /* restore the backlight level */
-       if (dm->backlight_dev && (amdgpu_dm_backlight_get_level(dm) != dm->brightness[0]))
-               amdgpu_dm_backlight_set_level(dm, dm->brightness[0]);
+       for (i = 0; i < dm->num_of_edps; i++) {
+               if (dm->backlight_dev[i] &&
+                   (amdgpu_dm_backlight_get_level(dm, i) != dm->brightness[i]))
+                       amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
+       }
 #endif
        /*
         * send vblank event on all events not handled in flip and diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 9522d4ca299e..ab1670b16b02 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -365,13 +365,13 @@ struct amdgpu_display_manager {

        spinlock_t irq_handler_list_table_lock;

-       struct backlight_device *backlight_dev;
+       struct backlight_device *backlight_dev[AMDGPU_DM_MAX_NUM_EDP];

        const struct dc_link *backlight_link[AMDGPU_DM_MAX_NUM_EDP];

        uint8_t num_of_edps;

-       struct amdgpu_dm_backlight_caps backlight_caps;
+       struct amdgpu_dm_backlight_caps backlight_caps[AMDGPU_DM_MAX_NUM_EDP];

        struct mod_freesync *freesync_module;
 #ifdef CONFIG_DRM_AMD_DC_HDCP
--
2.31.1

_______________________________________________
amd-gfx mailing list
amd-gfx at lists.freedesktop.org
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7Croman.li%40amd.com%7C4e1f8a3d82c94bb5a6c608d946f9a646%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637618860323313878%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=wTGk3rrbxTa2gWnTgI%2FCic0Dqr7ERPgbanwXpn47ZiA%3D&reserved=0


More information about the amd-gfx mailing list