Commit ee8ed250 authored by Camille Cho's avatar Camille Cho Committed by Alex Deucher

drm/amd/display: Correctly restore user_level

[Why]
BL1_PWM_USER_LEVEL is meant for the user brightness level setting from
OS. However, we update it along with other ABM levels to the real PWM
value which could be ABMed.

[How]
Driver to cache and restore the user brightness level setting so that
DMUB can retrieve the last user setting in ABM config initialization.
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: default avatarAnthony Koo <anthony.koo@amd.com>
Acked-by: default avatarRodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: default avatarCamille Cho <camille.cho@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent aa5dc053
...@@ -135,7 +135,7 @@ static void dmcu_set_backlight_level( ...@@ -135,7 +135,7 @@ static void dmcu_set_backlight_level(
0, 1, 80000); 0, 1, 80000);
} }
static void dce_abm_init(struct abm *abm, uint32_t backlight) static void dce_abm_init(struct abm *abm, uint32_t backlight, uint32_t user_level)
{ {
struct dce_abm *abm_dce = TO_DCE_ABM(abm); struct dce_abm *abm_dce = TO_DCE_ABM(abm);
...@@ -162,7 +162,7 @@ static void dce_abm_init(struct abm *abm, uint32_t backlight) ...@@ -162,7 +162,7 @@ static void dce_abm_init(struct abm *abm, uint32_t backlight)
BL1_PWM_TARGET_ABM_LEVEL, backlight); BL1_PWM_TARGET_ABM_LEVEL, backlight);
REG_UPDATE(BL1_PWM_USER_LEVEL, REG_UPDATE(BL1_PWM_USER_LEVEL,
BL1_PWM_USER_LEVEL, backlight); BL1_PWM_USER_LEVEL, user_level);
REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES,
ABM1_LS_MIN_PIXEL_VALUE_THRES, 0, ABM1_LS_MIN_PIXEL_VALUE_THRES, 0,
......
...@@ -57,9 +57,9 @@ static unsigned int abm_feature_support(struct abm *abm, unsigned int panel_inst ...@@ -57,9 +57,9 @@ static unsigned int abm_feature_support(struct abm *abm, unsigned int panel_inst
return ret; return ret;
} }
static void dmub_abm_init_ex(struct abm *abm, uint32_t backlight) static void dmub_abm_init_ex(struct abm *abm, uint32_t backlight, uint32_t user_level)
{ {
dmub_abm_init(abm, backlight); dmub_abm_init(abm, backlight, user_level);
} }
static unsigned int dmub_abm_get_current_backlight_ex(struct abm *abm) static unsigned int dmub_abm_get_current_backlight_ex(struct abm *abm)
......
...@@ -79,7 +79,7 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc) ...@@ -79,7 +79,7 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc)
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT); dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
} }
void dmub_abm_init(struct abm *abm, uint32_t backlight) void dmub_abm_init(struct abm *abm, uint32_t backlight, uint32_t user_level)
{ {
struct dce_abm *dce_abm = TO_DMUB_ABM(abm); struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
...@@ -106,7 +106,7 @@ void dmub_abm_init(struct abm *abm, uint32_t backlight) ...@@ -106,7 +106,7 @@ void dmub_abm_init(struct abm *abm, uint32_t backlight)
BL1_PWM_TARGET_ABM_LEVEL, backlight); BL1_PWM_TARGET_ABM_LEVEL, backlight);
REG_UPDATE(BL1_PWM_USER_LEVEL, REG_UPDATE(BL1_PWM_USER_LEVEL,
BL1_PWM_USER_LEVEL, backlight); BL1_PWM_USER_LEVEL, user_level);
REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES,
ABM1_LS_MIN_PIXEL_VALUE_THRES, 0, ABM1_LS_MIN_PIXEL_VALUE_THRES, 0,
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
struct abm_save_restore; struct abm_save_restore;
void dmub_abm_init(struct abm *abm, uint32_t backlight); void dmub_abm_init(struct abm *abm, uint32_t backlight, uint32_t user_level);
bool dmub_abm_set_level(struct abm *abm, uint32_t level, uint8_t panel_mask); bool dmub_abm_set_level(struct abm *abm, uint32_t level, uint8_t panel_mask);
unsigned int dmub_abm_get_current_backlight(struct abm *abm); unsigned int dmub_abm_get_current_backlight(struct abm *abm);
unsigned int dmub_abm_get_target_backlight(struct abm *abm); unsigned int dmub_abm_get_target_backlight(struct abm *abm);
......
...@@ -2593,6 +2593,7 @@ static void init_hw(struct dc *dc) ...@@ -2593,6 +2593,7 @@ static void init_hw(struct dc *dc)
struct dmcu *dmcu; struct dmcu *dmcu;
struct dce_hwseq *hws = dc->hwseq; struct dce_hwseq *hws = dc->hwseq;
uint32_t backlight = MAX_BACKLIGHT_LEVEL; uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = 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++) {
...@@ -2642,13 +2643,15 @@ static void init_hw(struct dc *dc) ...@@ -2642,13 +2643,15 @@ static void init_hw(struct dc *dc)
for (i = 0; i < dc->link_count; i++) { for (i = 0; i < dc->link_count; i++) {
struct dc_link *link = dc->links[i]; struct dc_link *link = dc->links[i];
if (link->panel_cntl) if (link->panel_cntl) {
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl); backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
user_level = link->panel_cntl->stored_backlight_registers.USER_LEVEL;
}
} }
abm = dc->res_pool->abm; abm = dc->res_pool->abm;
if (abm != NULL) if (abm != NULL)
abm->funcs->abm_init(abm, backlight); abm->funcs->abm_init(abm, backlight, user_level);
dmcu = dc->res_pool->dmcu; dmcu = dc->res_pool->dmcu;
if (dmcu != NULL && abm != NULL) if (dmcu != NULL && abm != NULL)
......
...@@ -1490,6 +1490,7 @@ void dcn10_init_hw(struct dc *dc) ...@@ -1490,6 +1490,7 @@ void dcn10_init_hw(struct dc *dc)
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; uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = MAX_BACKLIGHT_LEVEL;
bool is_optimized_init_done = false; bool is_optimized_init_done = false;
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
...@@ -1587,12 +1588,14 @@ void dcn10_init_hw(struct dc *dc) ...@@ -1587,12 +1588,14 @@ void dcn10_init_hw(struct dc *dc)
for (i = 0; i < dc->link_count; i++) { for (i = 0; i < dc->link_count; i++) {
struct dc_link *link = dc->links[i]; struct dc_link *link = dc->links[i];
if (link->panel_cntl) if (link->panel_cntl) {
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl); backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
user_level = link->panel_cntl->stored_backlight_registers.USER_LEVEL;
}
} }
if (abm != NULL) if (abm != NULL)
abm->funcs->abm_init(abm, backlight); abm->funcs->abm_init(abm, backlight, user_level);
if (dmcu != NULL && !dmcu->auto_load_dmcu) if (dmcu != NULL && !dmcu->auto_load_dmcu)
dmcu->funcs->dmcu_init(dmcu); dmcu->funcs->dmcu_init(dmcu);
......
...@@ -476,6 +476,7 @@ void dcn30_init_hw(struct dc *dc) ...@@ -476,6 +476,7 @@ void dcn30_init_hw(struct dc *dc)
int i; int i;
int edp_num; int edp_num;
uint32_t backlight = MAX_BACKLIGHT_LEVEL; uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = 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);
...@@ -612,13 +613,15 @@ void dcn30_init_hw(struct dc *dc) ...@@ -612,13 +613,15 @@ void dcn30_init_hw(struct dc *dc)
for (i = 0; i < dc->link_count; i++) { for (i = 0; i < dc->link_count; i++) {
struct dc_link *link = dc->links[i]; struct dc_link *link = dc->links[i];
if (link->panel_cntl) if (link->panel_cntl) {
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl); backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
user_level = link->panel_cntl->stored_backlight_registers.USER_LEVEL;
}
} }
for (i = 0; i < dc->res_pool->pipe_count; i++) { for (i = 0; i < dc->res_pool->pipe_count; i++) {
if (abms[i] != NULL) if (abms[i] != NULL)
abms[i]->funcs->abm_init(abms[i], backlight); abms[i]->funcs->abm_init(abms[i], backlight, user_level);
} }
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/ /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
......
...@@ -113,6 +113,7 @@ void dcn31_init_hw(struct dc *dc) ...@@ -113,6 +113,7 @@ void dcn31_init_hw(struct dc *dc)
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; uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = MAX_BACKLIGHT_LEVEL;
int i; int i;
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
...@@ -224,13 +225,15 @@ void dcn31_init_hw(struct dc *dc) ...@@ -224,13 +225,15 @@ void dcn31_init_hw(struct dc *dc)
for (i = 0; i < dc->link_count; i++) { for (i = 0; i < dc->link_count; i++) {
struct dc_link *link = dc->links[i]; struct dc_link *link = dc->links[i];
if (link->panel_cntl) if (link->panel_cntl) {
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl); backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
user_level = link->panel_cntl->stored_backlight_registers.USER_LEVEL;
}
} }
for (i = 0; i < dc->res_pool->pipe_count; i++) { for (i = 0; i < dc->res_pool->pipe_count; i++) {
if (abms[i] != NULL) if (abms[i] != NULL)
abms[i]->funcs->abm_init(abms[i], backlight); abms[i]->funcs->abm_init(abms[i], backlight, user_level);
} }
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/ /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
......
...@@ -753,6 +753,7 @@ void dcn32_init_hw(struct dc *dc) ...@@ -753,6 +753,7 @@ void dcn32_init_hw(struct dc *dc)
int i; int i;
int edp_num; int edp_num;
uint32_t backlight = MAX_BACKLIGHT_LEVEL; uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = 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);
...@@ -907,13 +908,15 @@ void dcn32_init_hw(struct dc *dc) ...@@ -907,13 +908,15 @@ void dcn32_init_hw(struct dc *dc)
for (i = 0; i < dc->link_count; i++) { for (i = 0; i < dc->link_count; i++) {
struct dc_link *link = dc->links[i]; struct dc_link *link = dc->links[i];
if (link->panel_cntl) if (link->panel_cntl) {
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl); backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
user_level = link->panel_cntl->stored_backlight_registers.USER_LEVEL;
}
} }
for (i = 0; i < dc->res_pool->pipe_count; i++) { for (i = 0; i < dc->res_pool->pipe_count; i++) {
if (abms[i] != NULL && abms[i]->funcs != NULL) if (abms[i] != NULL && abms[i]->funcs != NULL)
abms[i]->funcs->abm_init(abms[i], backlight); abms[i]->funcs->abm_init(abms[i], backlight, user_level);
} }
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/ /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
......
...@@ -134,6 +134,7 @@ void dcn35_init_hw(struct dc *dc) ...@@ -134,6 +134,7 @@ void dcn35_init_hw(struct dc *dc)
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; uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = MAX_BACKLIGHT_LEVEL;
int i; int i;
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
...@@ -280,13 +281,15 @@ void dcn35_init_hw(struct dc *dc) ...@@ -280,13 +281,15 @@ void dcn35_init_hw(struct dc *dc)
for (i = 0; i < dc->link_count; i++) { for (i = 0; i < dc->link_count; i++) {
struct dc_link *link = dc->links[i]; struct dc_link *link = dc->links[i];
if (link->panel_cntl) if (link->panel_cntl) {
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl); backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
user_level = link->panel_cntl->stored_backlight_registers.USER_LEVEL;
}
} }
if (dc->ctx->dmub_srv) { if (dc->ctx->dmub_srv) {
for (i = 0; i < dc->res_pool->pipe_count; i++) { for (i = 0; i < dc->res_pool->pipe_count; i++) {
if (abms[i] != NULL && abms[i]->funcs != NULL) if (abms[i] != NULL && abms[i]->funcs != NULL)
abms[i]->funcs->abm_init(abms[i], backlight); abms[i]->funcs->abm_init(abms[i], backlight, user_level);
} }
} }
......
...@@ -36,7 +36,7 @@ struct abm { ...@@ -36,7 +36,7 @@ struct abm {
}; };
struct abm_funcs { struct abm_funcs {
void (*abm_init)(struct abm *abm, uint32_t back_light); void (*abm_init)(struct abm *abm, uint32_t back_light, uint32_t user_level);
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);
......
...@@ -40,6 +40,7 @@ struct panel_cntl_backlight_registers { ...@@ -40,6 +40,7 @@ struct panel_cntl_backlight_registers {
unsigned int BL_PWM_PERIOD_CNTL; unsigned int BL_PWM_PERIOD_CNTL;
unsigned int LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV; unsigned int LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV;
unsigned int PANEL_PWRSEQ_REF_DIV2; unsigned int PANEL_PWRSEQ_REF_DIV2;
unsigned int USER_LEVEL;
}; };
struct panel_cntl_funcs { struct panel_cntl_funcs {
......
...@@ -529,6 +529,9 @@ bool edp_set_backlight_level(const struct dc_link *link, ...@@ -529,6 +529,9 @@ bool edp_set_backlight_level(const struct dc_link *link,
if (dc_is_embedded_signal(link->connector_signal)) { if (dc_is_embedded_signal(link->connector_signal)) {
struct pipe_ctx *pipe_ctx = get_pipe_from_link(link); struct pipe_ctx *pipe_ctx = get_pipe_from_link(link);
if (link->panel_cntl)
link->panel_cntl->stored_backlight_registers.USER_LEVEL = backlight_pwm_u16_16;
if (pipe_ctx) { 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
......
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