Commit 3ba01817 authored by Yongqiang Sun's avatar Yongqiang Sun Committed by Alex Deucher
Browse files

drm/amd/display: Move panel_cntl specific register from abm to panel_cntl.



[Why]
panel_cntl specific register should be access in panel_cntl object.

[How]
Move these register access from abm to panel_cntl.

Signed-off-by: default avatarYongqiang Sun <yongqiang.sun@amd.com>
Reviewed-by: default avatarAnthony Koo <Anthony.Koo@amd.com>
Acked-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 1c2075d4
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -2210,9 +2210,7 @@ static void commit_planes_do_stream_update(struct dc *dc,

				if (should_program_abm) {
					if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) {
						pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(
								pipe_ctx->stream_res.abm,
								pipe_ctx->stream->link->panel_cntl->inst);
						dc->hwss.set_abm_immediate_disable(pipe_ctx);
					} else {
						pipe_ctx->stream_res.abm->funcs->set_abm_level(
							pipe_ctx->stream_res.abm, stream->abm_level);
+28 −31
Original line number Diff line number Diff line
@@ -2504,59 +2504,56 @@ int dc_link_get_target_backlight_pwm(const struct dc_link *link)
	return (int) abm->funcs->get_target_backlight(abm);
}

static struct pipe_ctx *get_pipe_from_link(const struct dc_link *link)
{
	int i;
	struct dc *dc = link->ctx->dc;
	struct pipe_ctx *pipe_ctx = NULL;

	for (i = 0; i < MAX_PIPES; i++) {
		if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
			if (dc->current_state->res_ctx.pipe_ctx[i].stream->link == link) {
				pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
				break;
			}
		}
	}

	return pipe_ctx;
}

bool dc_link_set_backlight_level(const struct dc_link *link,
		uint32_t backlight_pwm_u16_16,
		uint32_t frame_ramp)
{
	struct dc  *dc = link->ctx->dc;
	int i;

	DC_LOGGER_INIT(link->ctx->logger);
	DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
			backlight_pwm_u16_16, backlight_pwm_u16_16);

	if (dc_is_embedded_signal(link->connector_signal)) {
		struct pipe_ctx *pipe_ctx = NULL;

		for (i = 0; i < MAX_PIPES; i++) {
			if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
				if (dc->current_state->res_ctx.
						pipe_ctx[i].stream->link
						== link) {
					pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
		struct pipe_ctx *pipe_ctx = get_pipe_from_link(link);

		if (pipe_ctx) {
			/* Disable brightness ramping when the display is blanked
			 * as it can hang the DMCU
			 */
					if (dc->current_state->res_ctx.pipe_ctx[i].plane_state == NULL)
			if (pipe_ctx->plane_state == NULL)
				frame_ramp = 0;
				}
			}
		}

		if (pipe_ctx == NULL)
		} else {
			ASSERT(false);
			return false;
		}

		dc->hwss.set_backlight_level(
				pipe_ctx,
				backlight_pwm_u16_16,
				frame_ramp);
	}

	return true;
}

bool dc_link_set_abm_disable(const struct dc_link *link)
{
	struct abm *abm = get_abm_from_stream_res(link);
	bool success = false;

	if (abm)
		success = abm->funcs->set_abm_immediate_disable(abm, link->panel_cntl->inst);

	return success;
}

bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait)
{
	struct dc  *dc = link->ctx->dc;
+0 −2
Original line number Diff line number Diff line
@@ -220,8 +220,6 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link);

int dc_link_get_target_backlight_pwm(const struct dc_link *link);

bool dc_link_set_abm_disable(const struct dc_link *dc_link);

bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable, bool wait);

bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);
+8 −207
Original line number Diff line number Diff line
@@ -83,120 +83,6 @@ static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id, uint32_t p
	return true;
}

static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *abm_dce)
{
	uint64_t current_backlight;
	uint32_t round_result;
	uint32_t pwm_period_cntl, bl_period, bl_int_count;
	uint32_t bl_pwm_cntl, bl_pwm, fractional_duty_cycle_en;
	uint32_t bl_period_mask, bl_pwm_mask;

	pwm_period_cntl = REG_READ(BL_PWM_PERIOD_CNTL);
	REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period);
	REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count);

	bl_pwm_cntl = REG_READ(BL_PWM_CNTL);
	REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, (uint32_t *)(&bl_pwm));
	REG_GET(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, &fractional_duty_cycle_en);

	if (bl_int_count == 0)
		bl_int_count = 16;

	bl_period_mask = (1 << bl_int_count) - 1;
	bl_period &= bl_period_mask;

	bl_pwm_mask = bl_period_mask << (16 - bl_int_count);

	if (fractional_duty_cycle_en == 0)
		bl_pwm &= bl_pwm_mask;
	else
		bl_pwm &= 0xFFFF;

	current_backlight = bl_pwm << (1 + bl_int_count);

	if (bl_period == 0)
		bl_period = 0xFFFF;

	current_backlight = div_u64(current_backlight, bl_period);
	current_backlight = (current_backlight + 1) >> 1;

	current_backlight = (uint64_t)(current_backlight) * bl_period;

	round_result = (uint32_t)(current_backlight & 0xFFFFFFFF);

	round_result = (round_result >> (bl_int_count-1)) & 1;

	current_backlight >>= bl_int_count;
	current_backlight += round_result;

	return (uint32_t)(current_backlight);
}

static void driver_set_backlight_level(struct dce_abm *abm_dce,
		uint32_t backlight_pwm_u16_16)
{
	uint32_t backlight_16bit;
	uint32_t masked_pwm_period;
	uint8_t bit_count;
	uint64_t active_duty_cycle;
	uint32_t pwm_period_bitcnt;

	/*
	 * 1. Find  16 bit backlight active duty cycle, where 0 <= backlight
	 * active duty cycle <= backlight period
	 */

	/* 1.1 Apply bitmask for backlight period value based on value of BITCNT
	 */
	REG_GET_2(BL_PWM_PERIOD_CNTL,
			BL_PWM_PERIOD_BITCNT, &pwm_period_bitcnt,
			BL_PWM_PERIOD, &masked_pwm_period);

	if (pwm_period_bitcnt == 0)
		bit_count = 16;
	else
		bit_count = pwm_period_bitcnt;

	/* e.g. maskedPwmPeriod = 0x24 when bitCount is 6 */
	masked_pwm_period = masked_pwm_period & ((1 << bit_count) - 1);

	/* 1.2 Calculate integer active duty cycle required upper 16 bits
	 * contain integer component, lower 16 bits contain fractional component
	 * of active duty cycle e.g. 0x21BDC0 = 0xEFF0 * 0x24
	 */
	active_duty_cycle = backlight_pwm_u16_16 * masked_pwm_period;

	/* 1.3 Calculate 16 bit active duty cycle from integer and fractional
	 * components shift by bitCount then mask 16 bits and add rounding bit
	 * from MSB of fraction e.g. 0x86F7 = ((0x21BDC0 >> 6) & 0xFFF) + 0
	 */
	backlight_16bit = active_duty_cycle >> bit_count;
	backlight_16bit &= 0xFFFF;
	backlight_16bit += (active_duty_cycle >> (bit_count - 1)) & 0x1;

	/*
	 * 2. Program register with updated value
	 */

	/* 2.1 Lock group 2 backlight registers */

	REG_UPDATE_2(BL_PWM_GRP1_REG_LOCK,
			BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, 1,
			BL_PWM_GRP1_REG_LOCK, 1);

	// 2.2 Write new active duty cycle
	REG_UPDATE(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, backlight_16bit);

	/* 2.3 Unlock group 2 backlight registers */
	REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
			BL_PWM_GRP1_REG_LOCK, 0);

	/* 3 Wait for pending bit to be cleared */
	REG_WAIT(BL_PWM_GRP1_REG_LOCK,
			BL_PWM_GRP1_REG_UPDATE_PENDING, 0,
			1, 10000);
}

static void dmcu_set_backlight_level(
	struct dce_abm *abm_dce,
	uint32_t backlight_pwm_u16_16,
@@ -249,10 +135,9 @@ static void dmcu_set_backlight_level(
			0, 1, 80000);
}

static void dce_abm_init(struct abm *abm)
static void dce_abm_init(struct abm *abm, uint32_t backlight)
{
	struct dce_abm *abm_dce = TO_DCE_ABM(abm);
	unsigned int backlight = calculate_16_bit_backlight_from_pwm(abm_dce);

	REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103);
	REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
@@ -334,85 +219,11 @@ static bool dce_abm_set_level(struct abm *abm, uint32_t level)

static bool dce_abm_immediate_disable(struct abm *abm, uint32_t panel_inst)
{
	struct dce_abm *abm_dce = TO_DCE_ABM(abm);

	if (abm->dmcu_is_running == false)
		return true;

	dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY, panel_inst);

	abm->stored_backlight_registers.BL_PWM_CNTL =
		REG_READ(BL_PWM_CNTL);
	abm->stored_backlight_registers.BL_PWM_CNTL2 =
		REG_READ(BL_PWM_CNTL2);
	abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
		REG_READ(BL_PWM_PERIOD_CNTL);

	REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
		&abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
	return true;
}

static bool dce_abm_init_backlight(struct abm *abm)
{
	struct dce_abm *abm_dce = TO_DCE_ABM(abm);
	uint32_t value;

	/* It must not be 0, so we have to restore them
	 * Bios bug w/a - period resets to zero,
	 * restoring to cache values which is always correct
	 */
	REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value);
	if (value == 0 || value == 1) {
		if (abm->stored_backlight_registers.BL_PWM_CNTL != 0) {
			REG_WRITE(BL_PWM_CNTL,
				abm->stored_backlight_registers.BL_PWM_CNTL);
			REG_WRITE(BL_PWM_CNTL2,
				abm->stored_backlight_registers.BL_PWM_CNTL2);
			REG_WRITE(BL_PWM_PERIOD_CNTL,
				abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL);
			REG_UPDATE(LVTMA_PWRSEQ_REF_DIV,
				BL_PWM_REF_DIV,
				abm->stored_backlight_registers.
				LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
		} else {
			/* TODO: Note: This should not really happen since VBIOS
			 * should have initialized PWM registers on boot.
			 */
			REG_WRITE(BL_PWM_CNTL, 0xC000FA00);
			REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0);
		}
	} else {
		abm->stored_backlight_registers.BL_PWM_CNTL =
				REG_READ(BL_PWM_CNTL);
		abm->stored_backlight_registers.BL_PWM_CNTL2 =
				REG_READ(BL_PWM_CNTL2);
		abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
				REG_READ(BL_PWM_PERIOD_CNTL);

		REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
				&abm->stored_backlight_registers.
				LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
	}

	/* Have driver take backlight control
	 * TakeBacklightControl(true)
	 */
	value = REG_READ(BIOS_SCRATCH_2);
	value |= ATOM_S2_VRI_BRIGHT_ENABLE;
	REG_WRITE(BIOS_SCRATCH_2, value);

	/* Enable the backlight output */
	REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);

	/* Disable fractional pwm if configured */
	REG_UPDATE(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN,
		   abm->ctx->dc->config.disable_fractional_pwm ? 0 : 1);

	/* Unlock group 2 backlight registers */
	REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
			BL_PWM_GRP1_REG_LOCK, 0);

	return true;
}

@@ -421,23 +232,18 @@ static bool dce_abm_set_backlight_level_pwm(
		unsigned int backlight_pwm_u16_16,
		unsigned int frame_ramp,
		unsigned int controller_id,
		unsigned int panel_inst,
		bool fw_set_brightness)
		unsigned int panel_inst)
{
	struct dce_abm *abm_dce = TO_DCE_ABM(abm);

	DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
			backlight_pwm_u16_16, backlight_pwm_u16_16);

	/* If DMCU is in reset state, DMCU is uninitialized */
	if (fw_set_brightness)
	dmcu_set_backlight_level(abm_dce,
			backlight_pwm_u16_16,
			frame_ramp,
			controller_id,
			panel_inst);
	else
		driver_set_backlight_level(abm_dce, backlight_pwm_u16_16);

	return true;
}
@@ -445,13 +251,12 @@ static bool dce_abm_set_backlight_level_pwm(
static const struct abm_funcs dce_funcs = {
	.abm_init = dce_abm_init,
	.set_abm_level = dce_abm_set_level,
	.init_backlight = dce_abm_init_backlight,
	.set_pipe = dce_abm_set_pipe,
	.set_backlight_level_pwm = dce_abm_set_backlight_level_pwm,
	.get_current_backlight = dce_abm_get_current_backlight,
	.get_target_backlight = dce_abm_get_target_backlight,
	.init_abm_config = NULL,
	.set_abm_immediate_disable = dce_abm_immediate_disable
	.set_abm_immediate_disable = dce_abm_immediate_disable,
};

static void dce_abm_construct(
@@ -465,10 +270,6 @@ static void dce_abm_construct(

	base->ctx = ctx;
	base->funcs = &dce_funcs;
	base->stored_backlight_registers.BL_PWM_CNTL = 0;
	base->stored_backlight_registers.BL_PWM_CNTL2 = 0;
	base->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 0;
	base->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV = 0;
	base->dmcu_is_running = false;

	abm_dce->regs = regs;
+1 −29
Original line number Diff line number Diff line
@@ -30,11 +30,6 @@
#include "abm.h"

#define ABM_COMMON_REG_LIST_DCE_BASE() \
	SR(BL_PWM_PERIOD_CNTL), \
	SR(BL_PWM_CNTL), \
	SR(BL_PWM_CNTL2), \
	SR(BL_PWM_GRP1_REG_LOCK), \
	SR(LVTMA_PWRSEQ_REF_DIV), \
	SR(MASTER_COMM_CNTL_REG), \
	SR(MASTER_COMM_CMD_REG), \
	SR(MASTER_COMM_DATA_REG1)
@@ -85,15 +80,6 @@
	.field_name = reg_name ## __ ## field_name ## post_fix

#define ABM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \
	ABM_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, mask_sh), \
	ABM_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, mask_sh), \
	ABM_SF(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, mask_sh), \
	ABM_SF(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, mask_sh), \
	ABM_SF(BL_PWM_CNTL, BL_PWM_EN, mask_sh), \
	ABM_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, mask_sh), \
	ABM_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_LOCK, mask_sh), \
	ABM_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_UPDATE_PENDING, mask_sh), \
	ABM_SF(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV, mask_sh), \
	ABM_SF(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, mask_sh), \
	ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, mask_sh), \
	ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE1, mask_sh), \
@@ -178,19 +164,10 @@
	type ABM1_HG_REG_READ_MISSED_FRAME_CLEAR; \
	type ABM1_LS_REG_READ_MISSED_FRAME_CLEAR; \
	type ABM1_BL_REG_READ_MISSED_FRAME_CLEAR; \
	type BL_PWM_PERIOD; \
	type BL_PWM_PERIOD_BITCNT; \
	type BL_ACTIVE_INT_FRAC_CNT; \
	type BL_PWM_FRACTIONAL_EN; \
	type MASTER_COMM_INTERRUPT; \
	type MASTER_COMM_CMD_REG_BYTE0; \
	type MASTER_COMM_CMD_REG_BYTE1; \
	type MASTER_COMM_CMD_REG_BYTE2; \
	type BL_PWM_REF_DIV; \
	type BL_PWM_EN; \
	type BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN; \
	type BL_PWM_GRP1_REG_LOCK; \
	type BL_PWM_GRP1_REG_UPDATE_PENDING
	type MASTER_COMM_CMD_REG_BYTE2

struct dce_abm_shift {
	ABM_REG_FIELD_LIST(uint8_t);
@@ -201,10 +178,6 @@ struct dce_abm_mask {
};

struct dce_abm_registers {
	uint32_t BL_PWM_PERIOD_CNTL;
	uint32_t BL_PWM_CNTL;
	uint32_t BL_PWM_CNTL2;
	uint32_t LVTMA_PWRSEQ_REF_DIV;
	uint32_t DC_ABM1_HG_SAMPLE_RATE;
	uint32_t DC_ABM1_LS_SAMPLE_RATE;
	uint32_t BL1_PWM_BL_UPDATE_SAMPLE_RATE;
@@ -219,7 +192,6 @@ struct dce_abm_registers {
	uint32_t MASTER_COMM_CMD_REG;
	uint32_t MASTER_COMM_DATA_REG1;
	uint32_t BIOS_SCRATCH_2;
	uint32_t BL_PWM_GRP1_REG_LOCK;
};

struct dce_abm {
Loading