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

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
...@@ -2210,9 +2210,7 @@ static void commit_planes_do_stream_update(struct dc *dc, ...@@ -2210,9 +2210,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
if (should_program_abm) { if (should_program_abm) {
if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) { if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) {
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable( dc->hwss.set_abm_immediate_disable(pipe_ctx);
pipe_ctx->stream_res.abm,
pipe_ctx->stream->link->panel_cntl->inst);
} else { } else {
pipe_ctx->stream_res.abm->funcs->set_abm_level( pipe_ctx->stream_res.abm->funcs->set_abm_level(
pipe_ctx->stream_res.abm, stream->abm_level); pipe_ctx->stream_res.abm, stream->abm_level);
......
...@@ -2504,59 +2504,56 @@ int dc_link_get_target_backlight_pwm(const struct dc_link *link) ...@@ -2504,59 +2504,56 @@ int dc_link_get_target_backlight_pwm(const struct dc_link *link)
return (int) abm->funcs->get_target_backlight(abm); 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, bool dc_link_set_backlight_level(const struct dc_link *link,
uint32_t backlight_pwm_u16_16, uint32_t backlight_pwm_u16_16,
uint32_t frame_ramp) uint32_t frame_ramp)
{ {
struct dc *dc = link->ctx->dc; struct dc *dc = link->ctx->dc;
int i;
DC_LOGGER_INIT(link->ctx->logger); DC_LOGGER_INIT(link->ctx->logger);
DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
backlight_pwm_u16_16, backlight_pwm_u16_16); backlight_pwm_u16_16, backlight_pwm_u16_16);
if (dc_is_embedded_signal(link->connector_signal)) { if (dc_is_embedded_signal(link->connector_signal)) {
struct pipe_ctx *pipe_ctx = NULL; struct pipe_ctx *pipe_ctx = get_pipe_from_link(link);
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];
if (pipe_ctx) {
/* Disable brightness ramping when the display is blanked /* Disable brightness ramping when the display is blanked
* as it can hang the DMCU * 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; frame_ramp = 0;
} } else {
}
}
if (pipe_ctx == NULL)
ASSERT(false); ASSERT(false);
return false;
}
dc->hwss.set_backlight_level( dc->hwss.set_backlight_level(
pipe_ctx, pipe_ctx,
backlight_pwm_u16_16, backlight_pwm_u16_16,
frame_ramp); frame_ramp);
} }
return true; 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) bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait)
{ {
struct dc *dc = link->ctx->dc; struct dc *dc = link->ctx->dc;
......
...@@ -220,8 +220,6 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link); ...@@ -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); 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_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); bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);
......
...@@ -83,120 +83,6 @@ static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id, uint32_t p ...@@ -83,120 +83,6 @@ static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id, uint32_t p
return true; 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( static void dmcu_set_backlight_level(
struct dce_abm *abm_dce, struct dce_abm *abm_dce,
uint32_t backlight_pwm_u16_16, uint32_t backlight_pwm_u16_16,
...@@ -249,10 +135,9 @@ static void dmcu_set_backlight_level( ...@@ -249,10 +135,9 @@ static void dmcu_set_backlight_level(
0, 1, 80000); 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); 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, 0x103);
REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101); REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
...@@ -334,85 +219,11 @@ static bool dce_abm_set_level(struct abm *abm, uint32_t level) ...@@ -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) 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) if (abm->dmcu_is_running == false)
return true; return true;
dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY, panel_inst); 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; return true;
} }
...@@ -421,23 +232,18 @@ static bool dce_abm_set_backlight_level_pwm( ...@@ -421,23 +232,18 @@ static bool dce_abm_set_backlight_level_pwm(
unsigned int backlight_pwm_u16_16, unsigned int backlight_pwm_u16_16,
unsigned int frame_ramp, unsigned int frame_ramp,
unsigned int controller_id, unsigned int controller_id,
unsigned int panel_inst, unsigned int panel_inst)
bool fw_set_brightness)
{ {
struct dce_abm *abm_dce = TO_DCE_ABM(abm); struct dce_abm *abm_dce = TO_DCE_ABM(abm);
DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
backlight_pwm_u16_16, backlight_pwm_u16_16); 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, dmcu_set_backlight_level(abm_dce,
backlight_pwm_u16_16, backlight_pwm_u16_16,
frame_ramp, frame_ramp,
controller_id, controller_id,
panel_inst); panel_inst);
else
driver_set_backlight_level(abm_dce, backlight_pwm_u16_16);
return true; return true;
} }
...@@ -445,13 +251,12 @@ static bool dce_abm_set_backlight_level_pwm( ...@@ -445,13 +251,12 @@ static bool dce_abm_set_backlight_level_pwm(
static const struct abm_funcs dce_funcs = { static const struct abm_funcs dce_funcs = {
.abm_init = dce_abm_init, .abm_init = dce_abm_init,
.set_abm_level = dce_abm_set_level, .set_abm_level = dce_abm_set_level,
.init_backlight = dce_abm_init_backlight,
.set_pipe = dce_abm_set_pipe, .set_pipe = dce_abm_set_pipe,
.set_backlight_level_pwm = dce_abm_set_backlight_level_pwm, .set_backlight_level_pwm = dce_abm_set_backlight_level_pwm,
.get_current_backlight = dce_abm_get_current_backlight, .get_current_backlight = dce_abm_get_current_backlight,
.get_target_backlight = dce_abm_get_target_backlight, .get_target_backlight = dce_abm_get_target_backlight,
.init_abm_config = NULL, .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( static void dce_abm_construct(
...@@ -465,10 +270,6 @@ static void dce_abm_construct( ...@@ -465,10 +270,6 @@ static void dce_abm_construct(
base->ctx = ctx; base->ctx = ctx;
base->funcs = &dce_funcs; 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; base->dmcu_is_running = false;
abm_dce->regs = regs; abm_dce->regs = regs;
......
...@@ -30,11 +30,6 @@ ...@@ -30,11 +30,6 @@
#include "abm.h" #include "abm.h"
#define ABM_COMMON_REG_LIST_DCE_BASE() \ #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_CNTL_REG), \
SR(MASTER_COMM_CMD_REG), \ SR(MASTER_COMM_CMD_REG), \
SR(MASTER_COMM_DATA_REG1) SR(MASTER_COMM_DATA_REG1)
...@@ -85,15 +80,6 @@ ...@@ -85,15 +80,6 @@
.field_name = reg_name ## __ ## field_name ## post_fix .field_name = reg_name ## __ ## field_name ## post_fix
#define ABM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \ #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_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_BYTE0, mask_sh), \
ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE1, mask_sh), \ ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE1, mask_sh), \
...@@ -178,19 +164,10 @@ ...@@ -178,19 +164,10 @@
type ABM1_HG_REG_READ_MISSED_FRAME_CLEAR; \ type ABM1_HG_REG_READ_MISSED_FRAME_CLEAR; \
type ABM1_LS_REG_READ_MISSED_FRAME_CLEAR; \ type ABM1_LS_REG_READ_MISSED_FRAME_CLEAR; \
type ABM1_BL_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_INTERRUPT; \
type MASTER_COMM_CMD_REG_BYTE0; \ type MASTER_COMM_CMD_REG_BYTE0; \
type MASTER_COMM_CMD_REG_BYTE1; \ type MASTER_COMM_CMD_REG_BYTE1; \
type MASTER_COMM_CMD_REG_BYTE2; \ 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
struct dce_abm_shift { struct dce_abm_shift {
ABM_REG_FIELD_LIST(uint8_t); ABM_REG_FIELD_LIST(uint8_t);
...@@ -201,10 +178,6 @@ struct dce_abm_mask { ...@@ -201,10 +178,6 @@ struct dce_abm_mask {
}; };
struct dce_abm_registers { 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_HG_SAMPLE_RATE;
uint32_t DC_ABM1_LS_SAMPLE_RATE; uint32_t DC_ABM1_LS_SAMPLE_RATE;
uint32_t BL1_PWM_BL_UPDATE_SAMPLE_RATE; uint32_t BL1_PWM_BL_UPDATE_SAMPLE_RATE;
...@@ -219,7 +192,6 @@ struct dce_abm_registers { ...@@ -219,7 +192,6 @@ struct dce_abm_registers {
uint32_t MASTER_COMM_CMD_REG; uint32_t MASTER_COMM_CMD_REG;
uint32_t MASTER_COMM_DATA_REG1; uint32_t MASTER_COMM_DATA_REG1;
uint32_t BIOS_SCRATCH_2; uint32_t BIOS_SCRATCH_2;
uint32_t BL_PWM_GRP1_REG_LOCK;
}; };
struct dce_abm { struct dce_abm {
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "dc_dmub_srv.h" #include "dc_dmub_srv.h"
#include "panel_cntl.h" #include "panel_cntl.h"
#include "dce_panel_cntl.h" #include "dce_panel_cntl.h"
#include "atom.h"
#define TO_DCE_PANEL_CNTL(panel_cntl)\ #define TO_DCE_PANEL_CNTL(panel_cntl)\
container_of(panel_cntl, struct dce_panel_cntl, base) container_of(panel_cntl, struct dce_panel_cntl, base)
...@@ -45,9 +46,113 @@ ...@@ -45,9 +46,113 @@
#define FN(reg_name, field_name) \ #define FN(reg_name, field_name) \
dce_panel_cntl->shift->field_name, dce_panel_cntl->mask->field_name dce_panel_cntl->shift->field_name, dce_panel_cntl->mask->field_name
void dce_panel_cntl_hw_init(struct panel_cntl *panel_cntl) static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_panel_cntl *dce_panel_cntl)
{ {
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);
}
uint32_t dce_panel_cntl_hw_init(struct panel_cntl *panel_cntl)
{
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl);
uint32_t value;
uint32_t current_backlight;
/* 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 (panel_cntl->stored_backlight_registers.BL_PWM_CNTL != 0) {
REG_WRITE(BL_PWM_CNTL,
panel_cntl->stored_backlight_registers.BL_PWM_CNTL);
REG_WRITE(BL_PWM_CNTL2,
panel_cntl->stored_backlight_registers.BL_PWM_CNTL2);
REG_WRITE(BL_PWM_PERIOD_CNTL,
panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL);
REG_UPDATE(PWRSEQ_REF_DIV,
BL_PWM_REF_DIV,
panel_cntl->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 {
panel_cntl->stored_backlight_registers.BL_PWM_CNTL =
REG_READ(BL_PWM_CNTL);
panel_cntl->stored_backlight_registers.BL_PWM_CNTL2 =
REG_READ(BL_PWM_CNTL2);
panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
REG_READ(BL_PWM_PERIOD_CNTL);
REG_GET(PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
&panel_cntl->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);
// Unlock group 2 backlight registers
REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
BL_PWM_GRP1_REG_LOCK, 0);
current_backlight = calculate_16_bit_backlight_from_pwm(dce_panel_cntl);
return current_backlight;
} }
bool dce_is_panel_backlight_on(struct panel_cntl *panel_cntl) bool dce_is_panel_backlight_on(struct panel_cntl *panel_cntl)
...@@ -55,7 +160,7 @@ bool dce_is_panel_backlight_on(struct panel_cntl *panel_cntl) ...@@ -55,7 +160,7 @@ bool dce_is_panel_backlight_on(struct panel_cntl *panel_cntl)
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl); struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl);
uint32_t value; uint32_t value;
REG_GET(PWRSEQ_CNTL, BLON, &value); REG_GET(PWRSEQ_CNTL, LVTMA_BLON, &value);
return value; return value;
} }
...@@ -65,13 +170,94 @@ bool dce_is_panel_powered_on(struct panel_cntl *panel_cntl) ...@@ -65,13 +170,94 @@ bool dce_is_panel_powered_on(struct panel_cntl *panel_cntl)
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl); struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl);
uint32_t pwr_seq_state, dig_on, dig_on_ovrd; uint32_t pwr_seq_state, dig_on, dig_on_ovrd;
REG_GET(PWRSEQ_STATE, PWRSEQ_TARGET_STATE_R, &pwr_seq_state); REG_GET(PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &pwr_seq_state);
REG_GET_2(PWRSEQ_CNTL, DIGON, &dig_on, DIGON_OVRD, &dig_on_ovrd); REG_GET_2(PWRSEQ_CNTL, LVTMA_DIGON, &dig_on, LVTMA_DIGON_OVRD, &dig_on_ovrd);
return (pwr_seq_state == 1) || (dig_on == 1 && dig_on_ovrd == 1); return (pwr_seq_state == 1) || (dig_on == 1 && dig_on_ovrd == 1);
} }
void dce_store_backlight_level(struct panel_cntl *panel_cntl)
{
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl);
panel_cntl->stored_backlight_registers.BL_PWM_CNTL =
REG_READ(BL_PWM_CNTL);
panel_cntl->stored_backlight_registers.BL_PWM_CNTL2 =
REG_READ(BL_PWM_CNTL2);
panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
REG_READ(BL_PWM_PERIOD_CNTL);
REG_GET(PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
&panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
}
void dce_driver_set_backlight(struct panel_cntl *panel_cntl,
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;
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl);
/*
* 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 dce_panel_cntl_destroy(struct panel_cntl **panel_cntl) static void dce_panel_cntl_destroy(struct panel_cntl **panel_cntl)
{ {
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(*panel_cntl); struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(*panel_cntl);
...@@ -85,7 +271,8 @@ static const struct panel_cntl_funcs dce_link_panel_cntl_funcs = { ...@@ -85,7 +271,8 @@ static const struct panel_cntl_funcs dce_link_panel_cntl_funcs = {
.hw_init = dce_panel_cntl_hw_init, .hw_init = dce_panel_cntl_hw_init,
.is_panel_backlight_on = dce_is_panel_backlight_on, .is_panel_backlight_on = dce_is_panel_backlight_on,
.is_panel_powered_on = dce_is_panel_powered_on, .is_panel_powered_on = dce_is_panel_powered_on,
.store_backlight_level = dce_store_backlight_level,
.driver_set_backlight = dce_driver_set_backlight,
}; };
void dce_panel_cntl_construct( void dce_panel_cntl_construct(
...@@ -95,6 +282,13 @@ void dce_panel_cntl_construct( ...@@ -95,6 +282,13 @@ void dce_panel_cntl_construct(
const struct dce_panel_cntl_shift *shift, const struct dce_panel_cntl_shift *shift,
const struct dce_panel_cntl_mask *mask) const struct dce_panel_cntl_mask *mask)
{ {
struct panel_cntl *base = &dce_panel_cntl->base;
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;
dce_panel_cntl->regs = regs; dce_panel_cntl->regs = regs;
dce_panel_cntl->shift = shift; dce_panel_cntl->shift = shift;
dce_panel_cntl->mask = mask; dce_panel_cntl->mask = mask;
......
...@@ -35,10 +35,12 @@ ...@@ -35,10 +35,12 @@
#define DCE_PANEL_CNTL_REG_LIST()\ #define DCE_PANEL_CNTL_REG_LIST()\
DCE_PANEL_CNTL_SR(PWRSEQ_CNTL, LVTMA), \ DCE_PANEL_CNTL_SR(PWRSEQ_CNTL, LVTMA), \
DCE_PANEL_CNTL_SR(PWRSEQ_STATE, LVTMA), \ DCE_PANEL_CNTL_SR(PWRSEQ_STATE, LVTMA), \
DCE_PANEL_CNTL_SR(PWRSEQ_REF_DIV, LVTMA), \
SR(BL_PWM_CNTL), \ SR(BL_PWM_CNTL), \
SR(BL_PWM_CNTL2), \ SR(BL_PWM_CNTL2), \
SR(BL_PWM_PERIOD_CNTL), \ SR(BL_PWM_PERIOD_CNTL), \
SR(BL_PWM_GRP1_REG_LOCK) SR(BL_PWM_GRP1_REG_LOCK), \
SR(BIOS_SCRATCH_2)
#define DCN_PANEL_CNTL_SR(reg_name, block)\ #define DCN_PANEL_CNTL_SR(reg_name, block)\
.reg_name = BASE(mm ## block ## _ ## reg_name ## _BASE_IDX) + \ .reg_name = BASE(mm ## block ## _ ## reg_name ## _BASE_IDX) + \
...@@ -47,33 +49,37 @@ ...@@ -47,33 +49,37 @@
#define DCN_PANEL_CNTL_REG_LIST()\ #define DCN_PANEL_CNTL_REG_LIST()\
DCN_PANEL_CNTL_SR(PWRSEQ_CNTL, LVTMA), \ DCN_PANEL_CNTL_SR(PWRSEQ_CNTL, LVTMA), \
DCN_PANEL_CNTL_SR(PWRSEQ_STATE, LVTMA), \ DCN_PANEL_CNTL_SR(PWRSEQ_STATE, LVTMA), \
DCE_PANEL_CNTL_SR(PWRSEQ_REF_DIV, LVTMA), \
SR(BL_PWM_CNTL), \ SR(BL_PWM_CNTL), \
SR(BL_PWM_CNTL2), \ SR(BL_PWM_CNTL2), \
SR(BL_PWM_PERIOD_CNTL), \ SR(BL_PWM_PERIOD_CNTL), \
SR(BL_PWM_GRP1_REG_LOCK) SR(BL_PWM_GRP1_REG_LOCK), \
SR(BIOS_SCRATCH_2)
#define DCE_PANEL_CNTL_SF(block, reg_name, field_name, post_fix)\ #define DCE_PANEL_CNTL_SF(reg_name, field_name, post_fix)\
.field_name = block ## reg_name ## __ ## block ## field_name ## post_fix .field_name = reg_name ## __ ## field_name ## post_fix
#define DCE_PANEL_CNTL_MASK_SH_LIST(mask_sh) \ #define DCE_PANEL_CNTL_MASK_SH_LIST(mask_sh) \
DCE_PANEL_CNTL_SF(LVTMA_, PWRSEQ_CNTL, BLON, mask_sh),\ DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
DCE_PANEL_CNTL_SF(LVTMA_, PWRSEQ_CNTL, DIGON, mask_sh),\ DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_CNTL, LVTMA_DIGON, mask_sh),\
DCE_PANEL_CNTL_SF(LVTMA_, PWRSEQ_CNTL, DIGON_OVRD, mask_sh),\ DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_CNTL, LVTMA_DIGON_OVRD, mask_sh),\
DCE_PANEL_CNTL_SF(LVTMA_, PWRSEQ_STATE, PWRSEQ_TARGET_STATE_R, mask_sh), \ DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh), \
DCE_PANEL_CNTL_SF(, BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, mask_sh), \ DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV, mask_sh), \
DCE_PANEL_CNTL_SF(, BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, mask_sh), \ DCE_PANEL_CNTL_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, mask_sh), \
DCE_PANEL_CNTL_SF(, BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, mask_sh), \ DCE_PANEL_CNTL_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, mask_sh), \
DCE_PANEL_CNTL_SF(, BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, mask_sh), \ DCE_PANEL_CNTL_SF(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, mask_sh), \
DCE_PANEL_CNTL_SF(, BL_PWM_CNTL, BL_PWM_EN, mask_sh), \ DCE_PANEL_CNTL_SF(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, mask_sh), \
DCE_PANEL_CNTL_SF(, BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, mask_sh), \ DCE_PANEL_CNTL_SF(BL_PWM_CNTL, BL_PWM_EN, mask_sh), \
DCE_PANEL_CNTL_SF(, BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_LOCK, mask_sh), \ DCE_PANEL_CNTL_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, mask_sh), \
DCE_PANEL_CNTL_SF(, BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_UPDATE_PENDING, mask_sh) DCE_PANEL_CNTL_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_LOCK, mask_sh), \
DCE_PANEL_CNTL_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_UPDATE_PENDING, mask_sh)
#define DCE_PANEL_CNTL_REG_FIELD_LIST(type) \ #define DCE_PANEL_CNTL_REG_FIELD_LIST(type) \
type BLON;\ type LVTMA_BLON;\
type DIGON;\ type LVTMA_DIGON;\
type DIGON_OVRD;\ type LVTMA_DIGON_OVRD;\
type PWRSEQ_TARGET_STATE_R; \ type LVTMA_PWRSEQ_TARGET_STATE_R; \
type BL_PWM_REF_DIV; \
type BL_PWM_EN; \ type BL_PWM_EN; \
type BL_ACTIVE_INT_FRAC_CNT; \ type BL_ACTIVE_INT_FRAC_CNT; \
type BL_PWM_FRACTIONAL_EN; \ type BL_PWM_FRACTIONAL_EN; \
...@@ -98,6 +104,8 @@ struct dce_panel_cntl_registers { ...@@ -98,6 +104,8 @@ struct dce_panel_cntl_registers {
uint32_t BL_PWM_CNTL2; uint32_t BL_PWM_CNTL2;
uint32_t BL_PWM_PERIOD_CNTL; uint32_t BL_PWM_PERIOD_CNTL;
uint32_t BL_PWM_GRP1_REG_LOCK; uint32_t BL_PWM_GRP1_REG_LOCK;
uint32_t PWRSEQ_REF_DIV;
uint32_t BIOS_SCRATCH_2;
}; };
struct dce_panel_cntl { struct dce_panel_cntl {
......
...@@ -70,53 +70,6 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t panel ...@@ -70,53 +70,6 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t panel
return true; return true;
} }
static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *dce_abm)
{
uint64_t current_backlight;
uint32_t round_result;
uint32_t bl_period, bl_int_count;
uint32_t bl_pwm, fractional_duty_cycle_en;
uint32_t bl_period_mask, bl_pwm_mask;
REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period);
REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count);
REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &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 = (uint64_t)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 dmcub_set_backlight_level( static void dmcub_set_backlight_level(
struct dce_abm *dce_abm, struct dce_abm *dce_abm,
uint32_t backlight_pwm_u16_16, uint32_t backlight_pwm_u16_16,
...@@ -178,10 +131,9 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc) ...@@ -178,10 +131,9 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc)
dc_dmub_srv_wait_idle(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv);
} }
static void dmub_abm_init(struct abm *abm) static void dmub_abm_init(struct abm *abm, uint32_t backlight)
{ {
struct dce_abm *dce_abm = TO_DMUB_ABM(abm); struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
unsigned int backlight = calculate_16_bit_backlight_from_pwm(dce_abm);
REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103); REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103);
REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101); REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
...@@ -261,77 +213,8 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level) ...@@ -261,77 +213,8 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level)
static bool dmub_abm_immediate_disable(struct abm *abm, uint32_t panel_inst) static bool dmub_abm_immediate_disable(struct abm *abm, uint32_t panel_inst)
{ {
struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
dmub_abm_set_pipe(abm, DISABLE_ABM_IMMEDIATELY, panel_inst); dmub_abm_set_pipe(abm, 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 dmub_abm_init_backlight(struct abm *abm)
{
struct dce_abm *dce_abm = TO_DMUB_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);
// Unlock group 2 backlight registers
REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
BL_PWM_GRP1_REG_LOCK, 0);
return true; return true;
} }
...@@ -340,8 +223,7 @@ static bool dmub_abm_set_backlight_level_pwm( ...@@ -340,8 +223,7 @@ static bool dmub_abm_set_backlight_level_pwm(
unsigned int backlight_pwm_u16_16, unsigned int backlight_pwm_u16_16,
unsigned int frame_ramp, unsigned int frame_ramp,
unsigned int otg_inst, unsigned int otg_inst,
uint32_t panel_inst, uint32_t panel_inst)
bool fw_set_brightness)
{ {
struct dce_abm *dce_abm = TO_DMUB_ABM(abm); struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
...@@ -384,7 +266,6 @@ static bool dmub_abm_init_config(struct abm *abm, ...@@ -384,7 +266,6 @@ static bool dmub_abm_init_config(struct abm *abm,
static const struct abm_funcs abm_funcs = { static const struct abm_funcs abm_funcs = {
.abm_init = dmub_abm_init, .abm_init = dmub_abm_init,
.set_abm_level = dmub_abm_set_level, .set_abm_level = dmub_abm_set_level,
.init_backlight = dmub_abm_init_backlight,
.set_pipe = dmub_abm_set_pipe, .set_pipe = dmub_abm_set_pipe,
.set_backlight_level_pwm = dmub_abm_set_backlight_level_pwm, .set_backlight_level_pwm = dmub_abm_set_backlight_level_pwm,
.get_current_backlight = dmub_abm_get_current_backlight, .get_current_backlight = dmub_abm_get_current_backlight,
...@@ -404,10 +285,6 @@ static void dmub_abm_construct( ...@@ -404,10 +285,6 @@ static void dmub_abm_construct(
base->ctx = ctx; base->ctx = ctx;
base->funcs = &abm_funcs; base->funcs = &abm_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; base->dmcu_is_running = false;
abm_dce->regs = regs; abm_dce->regs = regs;
......
...@@ -1066,7 +1066,7 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) ...@@ -1066,7 +1066,7 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
hws->funcs.edp_backlight_control(link, false); hws->funcs.edp_backlight_control(link, false);
dc_link_set_abm_disable(link); link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
} }
if (dc_is_dp_signal(pipe_ctx->stream->signal)) if (dc_is_dp_signal(pipe_ctx->stream->signal))
...@@ -2355,6 +2355,7 @@ static void init_hw(struct dc *dc) ...@@ -2355,6 +2355,7 @@ static void init_hw(struct dc *dc)
struct abm *abm; struct abm *abm;
struct dmcu *dmcu; struct dmcu *dmcu;
struct dce_hwseq *hws = dc->hwseq; struct dce_hwseq *hws = dc->hwseq;
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
bp = dc->ctx->dc_bios; bp = dc->ctx->dc_bios;
for (i = 0; i < dc->res_pool->pipe_count; i++) { for (i = 0; i < dc->res_pool->pipe_count; i++) {
...@@ -2401,12 +2402,17 @@ static void init_hw(struct dc *dc) ...@@ -2401,12 +2402,17 @@ static void init_hw(struct dc *dc)
audio->funcs->hw_init(audio); audio->funcs->hw_init(audio);
} }
abm = dc->res_pool->abm; for (i = 0; i < dc->link_count; i++) {
if (abm != NULL) { struct dc_link *link = dc->links[i];
abm->funcs->init_backlight(abm);
abm->funcs->abm_init(abm); if (link->panel_cntl)
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
} }
abm = dc->res_pool->abm;
if (abm != NULL)
abm->funcs->abm_init(abm, backlight);
dmcu = dc->res_pool->dmcu; dmcu = dc->res_pool->dmcu;
if (dmcu != NULL && abm != NULL) if (dmcu != NULL && abm != NULL)
abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu); abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
...@@ -2721,6 +2727,7 @@ bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx, ...@@ -2721,6 +2727,7 @@ bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
struct dc_link *link = pipe_ctx->stream->link; struct dc_link *link = pipe_ctx->stream->link;
struct dc *dc = link->ctx->dc; struct dc *dc = link->ctx->dc;
struct abm *abm = pipe_ctx->stream_res.abm; struct abm *abm = pipe_ctx->stream_res.abm;
struct panel_cntl *panel_cntl = link->panel_cntl;
struct dmcu *dmcu = dc->res_pool->dmcu; struct dmcu *dmcu = dc->res_pool->dmcu;
bool fw_set_brightness = true; bool fw_set_brightness = true;
/* DMCU -1 for all controller id values, /* DMCU -1 for all controller id values,
...@@ -2728,23 +2735,38 @@ bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx, ...@@ -2728,23 +2735,38 @@ bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
*/ */
uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1; uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1;
if (abm == NULL || (abm->funcs->set_backlight_level_pwm == NULL)) if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL))
return false; return false;
if (dmcu) if (dmcu)
fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight)
panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16);
else
abm->funcs->set_backlight_level_pwm( abm->funcs->set_backlight_level_pwm(
abm, abm,
backlight_pwm_u16_16, backlight_pwm_u16_16,
frame_ramp, frame_ramp,
controller_id, controller_id,
link->panel_cntl->inst, link->panel_cntl->inst);
fw_set_brightness);
return true; return true;
} }
void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
{
struct abm *abm = pipe_ctx->stream_res.abm;
struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
if (abm)
abm->funcs->set_abm_immediate_disable(abm,
pipe_ctx->stream->link->panel_cntl->inst);
if (panel_cntl)
panel_cntl->funcs->store_backlight_level(panel_cntl);
}
static const struct hw_sequencer_funcs dce110_funcs = { static const struct hw_sequencer_funcs dce110_funcs = {
.program_gamut_remap = program_gamut_remap, .program_gamut_remap = program_gamut_remap,
.program_output_csc = program_output_csc, .program_output_csc = program_output_csc,
...@@ -2781,6 +2803,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { ...@@ -2781,6 +2803,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.set_cursor_position = dce110_set_cursor_position, .set_cursor_position = dce110_set_cursor_position,
.set_cursor_attribute = dce110_set_cursor_attribute, .set_cursor_attribute = dce110_set_cursor_attribute,
.set_backlight_level = dce110_set_backlight_level, .set_backlight_level = dce110_set_backlight_level,
.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
}; };
static const struct hwseq_private_funcs dce110_private_funcs = { static const struct hwseq_private_funcs dce110_private_funcs = {
......
...@@ -88,6 +88,7 @@ void dce110_edp_wait_for_hpd_ready( ...@@ -88,6 +88,7 @@ void dce110_edp_wait_for_hpd_ready(
bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx, bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
uint32_t backlight_pwm_u16_16, uint32_t backlight_pwm_u16_16,
uint32_t frame_ramp); uint32_t frame_ramp);
void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx);
#endif /* __DC_HWSS_DCE110_H__ */ #endif /* __DC_HWSS_DCE110_H__ */
...@@ -903,8 +903,7 @@ static void dcn10_reset_back_end_for_pipe( ...@@ -903,8 +903,7 @@ static void dcn10_reset_back_end_for_pipe(
if (pipe_ctx->top_pipe == NULL) { if (pipe_ctx->top_pipe == NULL) {
if (pipe_ctx->stream_res.abm) if (pipe_ctx->stream_res.abm)
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm, dc->hwss.set_abm_immediate_disable(pipe_ctx);
pipe_ctx->stream->link->panel_cntl->inst);
pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg); pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
...@@ -1245,6 +1244,7 @@ void dcn10_init_hw(struct dc *dc) ...@@ -1245,6 +1244,7 @@ void dcn10_init_hw(struct dc *dc)
struct dce_hwseq *hws = dc->hwseq; struct dce_hwseq *hws = dc->hwseq;
struct dc_bios *dcb = dc->ctx->dc_bios; struct dc_bios *dcb = dc->ctx->dc_bios;
struct resource_pool *res_pool = dc->res_pool; struct resource_pool *res_pool = dc->res_pool;
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr); dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
...@@ -1411,11 +1411,16 @@ void dcn10_init_hw(struct dc *dc) ...@@ -1411,11 +1411,16 @@ void dcn10_init_hw(struct dc *dc)
audio->funcs->hw_init(audio); audio->funcs->hw_init(audio);
} }
if (abm != NULL) { for (i = 0; i < dc->link_count; i++) {
abm->funcs->init_backlight(abm); struct dc_link *link = dc->links[i];
abm->funcs->abm_init(abm);
if (link->panel_cntl)
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
} }
if (abm != NULL)
abm->funcs->abm_init(abm, backlight);
if (dmcu != NULL && !dmcu->auto_load_dmcu) if (dmcu != NULL && !dmcu->auto_load_dmcu)
dmcu->funcs->dmcu_init(dmcu); dmcu->funcs->dmcu_init(dmcu);
...@@ -2490,9 +2495,7 @@ void dcn10_blank_pixel_data( ...@@ -2490,9 +2495,7 @@ void dcn10_blank_pixel_data(
stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level); stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
} }
} else if (blank) { } else if (blank) {
if (stream_res->abm) dc->hwss.set_abm_immediate_disable(pipe_ctx);
stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm,
stream->link->panel_cntl->inst);
if (stream_res->tg->funcs->set_blank) if (stream_res->tg->funcs->set_blank)
stream_res->tg->funcs->set_blank(stream_res->tg, blank); stream_res->tg->funcs->set_blank(stream_res->tg, blank);
} }
......
...@@ -73,6 +73,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { ...@@ -73,6 +73,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.get_clock = dcn10_get_clock, .get_clock = dcn10_get_clock,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.set_backlight_level = dce110_set_backlight_level, .set_backlight_level = dce110_set_backlight_level,
.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
}; };
static const struct hwseq_private_funcs dcn10_private_funcs = { static const struct hwseq_private_funcs dcn10_private_funcs = {
......
...@@ -961,9 +961,7 @@ void dcn20_blank_pixel_data( ...@@ -961,9 +961,7 @@ void dcn20_blank_pixel_data(
width = width / odm_cnt; width = width / odm_cnt;
if (blank) { if (blank) {
if (stream_res->abm) dc->hwss.set_abm_immediate_disable(pipe_ctx);
stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm,
stream->link->panel_cntl->inst);
if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) { if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) {
test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES; test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
...@@ -2042,9 +2040,7 @@ static void dcn20_reset_back_end_for_pipe( ...@@ -2042,9 +2040,7 @@ static void dcn20_reset_back_end_for_pipe(
*/ */
if (pipe_ctx->top_pipe == NULL) { if (pipe_ctx->top_pipe == NULL) {
if (pipe_ctx->stream_res.abm) dc->hwss.set_abm_immediate_disable(pipe_ctx);
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm,
pipe_ctx->stream->link->panel_cntl->inst);
pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg); pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
......
...@@ -84,6 +84,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { ...@@ -84,6 +84,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
.set_flip_control_gsl = dcn20_set_flip_control_gsl, .set_flip_control_gsl = dcn20_set_flip_control_gsl,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.set_backlight_level = dce110_set_backlight_level, .set_backlight_level = dce110_set_backlight_level,
.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
}; };
static const struct hwseq_private_funcs dcn20_private_funcs = { static const struct hwseq_private_funcs dcn20_private_funcs = {
......
...@@ -88,6 +88,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { ...@@ -88,6 +88,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.power_down = dce110_power_down, .power_down = dce110_power_down,
.set_backlight_level = dce110_set_backlight_level, .set_backlight_level = dce110_set_backlight_level,
.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
}; };
static const struct hwseq_private_funcs dcn21_private_funcs = { static const struct hwseq_private_funcs dcn21_private_funcs = {
......
...@@ -27,27 +27,17 @@ ...@@ -27,27 +27,17 @@
#include "dm_services_types.h" #include "dm_services_types.h"
struct abm_backlight_registers {
unsigned int BL_PWM_CNTL;
unsigned int BL_PWM_CNTL2;
unsigned int BL_PWM_PERIOD_CNTL;
unsigned int LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV;
};
struct abm { struct abm {
struct dc_context *ctx; struct dc_context *ctx;
const struct abm_funcs *funcs; const struct abm_funcs *funcs;
bool dmcu_is_running; bool dmcu_is_running;
/* registers setting needs to be saved and restored at InitBacklight */
struct abm_backlight_registers stored_backlight_registers;
}; };
struct abm_funcs { struct abm_funcs {
void (*abm_init)(struct abm *abm); void (*abm_init)(struct abm *abm, uint32_t back_light);
bool (*set_abm_level)(struct abm *abm, unsigned int abm_level); bool (*set_abm_level)(struct abm *abm, unsigned int abm_level);
bool (*set_abm_immediate_disable)(struct abm *abm, unsigned int panel_inst); bool (*set_abm_immediate_disable)(struct abm *abm, unsigned int panel_inst);
bool (*set_pipe)(struct abm *abm, unsigned int controller_id, unsigned int panel_inst); bool (*set_pipe)(struct abm *abm, unsigned int controller_id, unsigned int panel_inst);
bool (*init_backlight)(struct abm *abm);
/* backlight_pwm_u16_16 is unsigned 32 bit, /* backlight_pwm_u16_16 is unsigned 32 bit,
* 16 bit integer + 16 fractional, where 1.0 is max backlight value. * 16 bit integer + 16 fractional, where 1.0 is max backlight value.
...@@ -56,8 +46,7 @@ struct abm_funcs { ...@@ -56,8 +46,7 @@ struct abm_funcs {
unsigned int backlight_pwm_u16_16, unsigned int backlight_pwm_u16_16,
unsigned int frame_ramp, unsigned int frame_ramp,
unsigned int controller_id, unsigned int controller_id,
unsigned int panel_inst, unsigned int panel_inst);
bool fw_set_brightness);
unsigned int (*get_current_backlight)(struct abm *abm); unsigned int (*get_current_backlight)(struct abm *abm);
unsigned int (*get_target_backlight)(struct abm *abm); unsigned int (*get_target_backlight)(struct abm *abm);
......
...@@ -32,11 +32,23 @@ ...@@ -32,11 +32,23 @@
#include "dc_types.h" #include "dc_types.h"
#define MAX_BACKLIGHT_LEVEL 0xFFFF
struct panel_cntl_backlight_registers {
unsigned int BL_PWM_CNTL;
unsigned int BL_PWM_CNTL2;
unsigned int BL_PWM_PERIOD_CNTL;
unsigned int LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV;
};
struct panel_cntl_funcs { struct panel_cntl_funcs {
void (*destroy)(struct panel_cntl **panel_cntl); void (*destroy)(struct panel_cntl **panel_cntl);
void (*hw_init)(struct panel_cntl *panel_cntl); uint32_t (*hw_init)(struct panel_cntl *panel_cntl);
bool (*is_panel_backlight_on)(struct panel_cntl *panel_cntl); bool (*is_panel_backlight_on)(struct panel_cntl *panel_cntl);
bool (*is_panel_powered_on)(struct panel_cntl *panel_cntl); bool (*is_panel_powered_on)(struct panel_cntl *panel_cntl);
void (*store_backlight_level)(struct panel_cntl *panel_cntl);
void (*driver_set_backlight)(struct panel_cntl *panel_cntl,
uint32_t backlight_pwm_u16_16);
}; };
struct panel_cntl_init_data { struct panel_cntl_init_data {
...@@ -48,6 +60,8 @@ struct panel_cntl { ...@@ -48,6 +60,8 @@ struct panel_cntl {
const struct panel_cntl_funcs *funcs; const struct panel_cntl_funcs *funcs;
struct dc_context *ctx; struct dc_context *ctx;
uint32_t inst; uint32_t inst;
/* registers setting needs to be saved and restored at InitBacklight */
struct panel_cntl_backlight_registers stored_backlight_registers;
}; };
#endif /* DC_PANEL_CNTL_H_ */ #endif /* DC_PANEL_CNTL_H_ */
...@@ -196,6 +196,8 @@ struct hw_sequencer_funcs { ...@@ -196,6 +196,8 @@ struct hw_sequencer_funcs {
uint32_t backlight_pwm_u16_16, uint32_t backlight_pwm_u16_16,
uint32_t frame_ramp); uint32_t frame_ramp);
void (*set_abm_immediate_disable)(struct pipe_ctx *pipe_ctx);
}; };
......
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