Commit 6e568e43 authored by Jake Wang's avatar Jake Wang Committed by Alex Deucher

drm/amd/display: Added support for individual control for multiple back-light instances.

[Why & How]
Added support for individual control for multiple back-light instances.
Signed-off-by: default avatarJake Wang <haonan.wang2@amd.com>
Reviewed-by: default avatarAnthony Koo <Anthony.Koo@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 05adfd80
...@@ -1709,7 +1709,6 @@ static int dm_late_init(void *handle) ...@@ -1709,7 +1709,6 @@ static int dm_late_init(void *handle)
unsigned int linear_lut[16]; unsigned int linear_lut[16];
int i; int i;
struct dmcu *dmcu = NULL; struct dmcu *dmcu = NULL;
bool ret = true;
dmcu = adev->dm.dc->res_pool->dmcu; dmcu = adev->dm.dc->res_pool->dmcu;
...@@ -1726,18 +1725,23 @@ static int dm_late_init(void *handle) ...@@ -1726,18 +1725,23 @@ static int dm_late_init(void *handle)
* 0xFFFF x 0.01 = 0x28F * 0xFFFF x 0.01 = 0x28F
*/ */
params.min_abm_backlight = 0x28F; params.min_abm_backlight = 0x28F;
/* In the case where abm is implemented on dmcub, /* In the case where abm is implemented on dmcub,
* dmcu object will be null. * dmcu object will be null.
* ABM 2.4 and up are implemented on dmcub. * ABM 2.4 and up are implemented on dmcub.
*/ */
if (dmcu) if (dmcu) {
ret = dmcu_load_iram(dmcu, params); if (!dmcu_load_iram(dmcu, params))
else if (adev->dm.dc->ctx->dmub_srv) return -EINVAL;
ret = dmub_init_abm_config(adev->dm.dc->res_pool, params); } else if (adev->dm.dc->ctx->dmub_srv) {
struct dc_link *edp_links[MAX_NUM_EDP];
int edp_num;
if (!ret) 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 -EINVAL;
}
}
return detect_mst_link_for_all_connectors(adev_to_drm(adev)); return detect_mst_link_for_all_connectors(adev_to_drm(adev));
} }
......
...@@ -216,6 +216,23 @@ static inline void get_edp_links(const struct dc *dc, ...@@ -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). /* Set backlight level of an embedded panel (eDP, LVDS).
* backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer
* and 16 bit fractional, where 1.0 is max backlight value. * and 16 bit fractional, where 1.0 is max backlight value.
......
...@@ -172,16 +172,12 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level) ...@@ -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, static bool dmub_abm_init_config(struct abm *abm,
const char *src, const char *src,
unsigned int bytes) unsigned int bytes,
unsigned int inst)
{ {
union dmub_rb_cmd cmd; union dmub_rb_cmd cmd;
struct dc_context *dc = abm->ctx; struct dc_context *dc = abm->ctx;
uint32_t edp_id_count = dc->dc_edp_id_count; uint8_t panel_mask = 0x01 << inst;
int i;
uint8_t panel_mask = 0;
for (i = 0; i < edp_id_count; i++)
panel_mask |= 0x01 << i;
// TODO: Optimize by only reading back final 4 bytes // TODO: Optimize by only reading back final 4 bytes
dmub_flush_buffer_mem(&dc->dmub_srv->dmub->scratch_mem_fb); dmub_flush_buffer_mem(&dc->dmub_srv->dmub->scratch_mem_fb);
......
...@@ -52,7 +52,8 @@ struct abm_funcs { ...@@ -52,7 +52,8 @@ struct abm_funcs {
unsigned int (*get_target_backlight)(struct abm *abm); unsigned int (*get_target_backlight)(struct abm *abm);
bool (*init_abm_config)(struct abm *abm, bool (*init_abm_config)(struct abm *abm,
const char *src, const char *src,
unsigned int bytes); unsigned int bytes,
unsigned int inst);
}; };
#endif #endif
...@@ -660,7 +660,8 @@ static void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram ...@@ -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, 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 iram_table_v_2_2 ram_table;
struct abm_config_table config; struct abm_config_table config;
...@@ -669,7 +670,7 @@ bool dmub_init_abm_config(struct resource_pool *res_pool, ...@@ -669,7 +670,7 @@ bool dmub_init_abm_config(struct resource_pool *res_pool,
uint32_t i, j = 0; uint32_t i, j = 0;
#if defined(CONFIG_DRM_AMD_DC_DCN) #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; return false;
#else #else
if (res_pool->abm == NULL) if (res_pool->abm == NULL)
...@@ -728,13 +729,13 @@ bool dmub_init_abm_config(struct resource_pool *res_pool, ...@@ -728,13 +729,13 @@ bool dmub_init_abm_config(struct resource_pool *res_pool,
config.min_abm_backlight = ram_table.min_abm_backlight; config.min_abm_backlight = ram_table.min_abm_backlight;
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
if (res_pool->multiple_abms[0]) if (res_pool->multiple_abms[inst]) {
result = res_pool->multiple_abms[0]->funcs->init_abm_config( result = res_pool->multiple_abms[inst]->funcs->init_abm_config(
res_pool->multiple_abms[0], (char *)(&config), sizeof(struct abm_config_table)); res_pool->multiple_abms[inst], (char *)(&config), sizeof(struct abm_config_table), inst);
else } else
#endif #endif
result = res_pool->abm->funcs->init_abm_config( 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; return result;
} }
......
...@@ -49,6 +49,7 @@ struct dmcu_iram_parameters { ...@@ -49,6 +49,7 @@ struct dmcu_iram_parameters {
bool dmcu_load_iram(struct dmcu *dmcu, bool dmcu_load_iram(struct dmcu *dmcu,
struct dmcu_iram_parameters params); struct dmcu_iram_parameters params);
bool dmub_init_abm_config(struct resource_pool *res_pool, 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_ */ #endif /* MODULES_POWER_POWER_HELPERS_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment