drm/amd/display: Added support for individual control for multiple back-light instances.
authorJake Wang <haonan.wang2@amd.com>
Fri, 23 Apr 2021 20:42:35 +0000 (16:42 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 27 May 2021 16:24:03 +0000 (12:24 -0400)
[Why & How]
Added support for individual control for multiple back-light instances.

Signed-off-by: Jake Wang <haonan.wang2@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
drivers/gpu/drm/amd/display/modules/power/power_helpers.c
drivers/gpu/drm/amd/display/modules/power/power_helpers.h

index 092a493c352595a3e606fbbca6ea0870ad9e64d7..46910eceda299499ac39ef0025b34f6bc5d80f41 100644 (file)
@@ -1709,7 +1709,6 @@ static int dm_late_init(void *handle)
        unsigned int linear_lut[16];
        int i;
        struct dmcu *dmcu = NULL;
-       bool ret = true;
 
        dmcu = adev->dm.dc->res_pool->dmcu;
 
@@ -1726,18 +1725,23 @@ static int dm_late_init(void *handle)
         * 0xFFFF x 0.01 = 0x28F
         */
        params.min_abm_backlight = 0x28F;
-
        /* In the case where abm is implemented on dmcub,
-        * dmcu object will be null.
-        * ABM 2.4 and up are implemented on dmcub.
-        */
-       if (dmcu)
-               ret = dmcu_load_iram(dmcu, params);
-       else if (adev->dm.dc->ctx->dmub_srv)
-               ret = dmub_init_abm_config(adev->dm.dc->res_pool, params);
+       * dmcu object will be null.
+       * ABM 2.4 and up are implemented on dmcub.
+       */
+       if (dmcu) {
+               if (!dmcu_load_iram(dmcu, params))
+                       return -EINVAL;
+       } else if (adev->dm.dc->ctx->dmub_srv) {
+               struct dc_link *edp_links[MAX_NUM_EDP];
+               int edp_num;
 
-       if (!ret)
-               return -EINVAL;
+               get_edp_links(adev->dm.dc, edp_links, &edp_num);
+               for (i = 0; i < edp_num; i++) {
+                       if (!dmub_init_abm_config(adev->dm.dc->res_pool, params, i))
+                               return -EINVAL;
+               }
+       }
 
        return detect_mst_link_for_all_connectors(adev_to_drm(adev));
 }
index c871923e7db04de15cd94535073a3f07b20230b8..c617e9ae68a31acfefd979722adb8b2f1aa2c960 100644 (file)
@@ -216,6 +216,23 @@ static inline void get_edp_links(const struct dc *dc,
        }
 }
 
+static inline bool dc_get_edp_link_panel_inst(const struct dc *dc,
+               const struct dc_link *link,
+               unsigned int *inst_out)
+{
+       struct dc_link *edp_links[MAX_NUM_EDP];
+       int edp_num;
+
+       if (link->connector_signal != SIGNAL_TYPE_EDP)
+               return false;
+       get_edp_links(dc, edp_links, &edp_num);
+       if ((edp_num > 1) && (link->link_index > edp_links[0]->link_index))
+               *inst_out = 1;
+       else
+               *inst_out = 0;
+       return true;
+}
+
 /* Set backlight level of an embedded panel (eDP, LVDS).
  * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer
  * and 16 bit fractional, where 1.0 is max backlight value.
index 6939ca2e82124979232d72a1d9fd0b5e5d401dd3..54a1408c8015c8bc5005b3c6131aaf06258b3e86 100644 (file)
@@ -172,16 +172,12 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level)
 
 static bool dmub_abm_init_config(struct abm *abm,
        const char *src,
-       unsigned int bytes)
+       unsigned int bytes,
+       unsigned int inst)
 {
        union dmub_rb_cmd cmd;
        struct dc_context *dc = abm->ctx;
-       uint32_t edp_id_count = dc->dc_edp_id_count;
-       int i;
-       uint8_t panel_mask = 0;
-
-       for (i = 0; i < edp_id_count; i++)
-               panel_mask |= 0x01 << i;
+       uint8_t panel_mask = 0x01 << inst;
 
        // TODO: Optimize by only reading back final 4 bytes
        dmub_flush_buffer_mem(&dc->dmub_srv->dmub->scratch_mem_fb);
index e8ce8c85adf1c48cf1aaf7683452f2482e8d9a87..142753644377a6314ed7a4f48b17592f25609dad 100644 (file)
@@ -52,7 +52,8 @@ struct abm_funcs {
        unsigned int (*get_target_backlight)(struct abm *abm);
        bool (*init_abm_config)(struct abm *abm,
                        const char *src,
-                       unsigned int bytes);
+                       unsigned int bytes,
+                       unsigned int inst);
 };
 
 #endif
index 6270ecbd24389b8f47f684aa2142e7e312cb3585..5e7331be1c0d22188896e0a5aaaede6a06b91032 100644 (file)
@@ -660,7 +660,8 @@ static void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram
 }
 
 bool dmub_init_abm_config(struct resource_pool *res_pool,
-       struct dmcu_iram_parameters params)
+       struct dmcu_iram_parameters params,
+       unsigned int inst)
 {
        struct iram_table_v_2_2 ram_table;
        struct abm_config_table config;
@@ -669,7 +670,7 @@ bool dmub_init_abm_config(struct resource_pool *res_pool,
        uint32_t i, j = 0;
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-       if (res_pool->abm == NULL && res_pool->multiple_abms[0] == NULL)
+       if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL)
                return false;
 #else
        if (res_pool->abm == NULL)
@@ -728,13 +729,13 @@ bool dmub_init_abm_config(struct resource_pool *res_pool,
        config.min_abm_backlight = ram_table.min_abm_backlight;
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-       if (res_pool->multiple_abms[0])
-               result = res_pool->multiple_abms[0]->funcs->init_abm_config(
-                       res_pool->multiple_abms[0], (char *)(&config), sizeof(struct abm_config_table));
-       else
+       if (res_pool->multiple_abms[inst]) {
+               result = res_pool->multiple_abms[inst]->funcs->init_abm_config(
+                       res_pool->multiple_abms[inst], (char *)(&config), sizeof(struct abm_config_table), inst);
+       else
 #endif
                result = res_pool->abm->funcs->init_abm_config(
-                       res_pool->abm, (char *)(&config), sizeof(struct abm_config_table));
+                       res_pool->abm, (char *)(&config), sizeof(struct abm_config_table), 0);
 
        return result;
 }
index 6f2eecce6baa757486b12aedae533440943fd4a1..2a9f8e2d8080916b34acc0a68edf8f30fe6b6979 100644 (file)
@@ -49,6 +49,7 @@ struct dmcu_iram_parameters {
 bool dmcu_load_iram(struct dmcu *dmcu,
                struct dmcu_iram_parameters params);
 bool dmub_init_abm_config(struct resource_pool *res_pool,
-               struct dmcu_iram_parameters params);
+               struct dmcu_iram_parameters params,
+               unsigned int inst);
 
 #endif /* MODULES_POWER_POWER_HELPERS_H_ */