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

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
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -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);
	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)
		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));
}
+17 −0
Original line number Diff line number Diff line
@@ -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.
+3 −7
Original line number Diff line number Diff line
@@ -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);
+2 −1
Original line number Diff line number Diff line
@@ -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
+8 −7
Original line number Diff line number Diff line
@@ -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;
}
Loading