drm/amd/display: Move panel_cntl specific register from abm to panel_cntl.
authorYongqiang Sun <yongqiang.sun@amd.com>
Sat, 18 Apr 2020 23:22:55 +0000 (19:22 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 5 May 2020 17:10:46 +0000 (13:10 -0400)
[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: Yongqiang Sun <yongqiang.sun@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
18 files changed:
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.c
drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.h
drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
drivers/gpu/drm/amd/display/dc/inc/hw/panel_cntl.h
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

index ad817bd7458665cecfe5aabeaf589f9290278db0..f47acf30acd256bcbd876ad7404442aa55f433b3 100644 (file)
@@ -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);
index 67c5342cf89a381683fb2f53cd1f891bfc2ae1c8..f895412538c0fa2c6a0e7530abb035e23b1f1bc0 100644 (file)
@@ -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];
-
-                                       /* 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)
-                                               frame_ramp = 0;
-                               }
-                       }
-               }
+               struct pipe_ctx *pipe_ctx = get_pipe_from_link(link);
 
-               if (pipe_ctx == NULL)
+               if (pipe_ctx) {
+                       /* Disable brightness ramping when the display is blanked
+                        * as it can hang the DMCU
+                        */
+                       if (pipe_ctx->plane_state == NULL)
+                               frame_ramp = 0;
+               } 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;
index 80fb4149f36a1e881f9dba7bcbc170375ed24318..eb5d910bffb6bdfbc2e8e806ba54768d45efb97f 100644 (file)
@@ -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);
index c15e60fb5ebcdbc0e47efbe157fb6e4c353cf88d..4e87e70237e3da3cb551a1365d481d8f22564f15 100644 (file)
@@ -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);
+       dmcu_set_backlight_level(abm_dce,
+                       backlight_pwm_u16_16,
+                       frame_ramp,
+                       controller_id,
+                       panel_inst);
 
        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;
index ba0caaffa24bf37add2e3b654388dfc5df6d40c7..9718a4823372c12c47042498d577bf51b3bfbeba 100644 (file)
 #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)
        .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), \
        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 {
index d9b0ff7eb2a46b499801d4e362413b8f661a5323..ebff9b1e312e5f88a593dbbd8386c33d8f3e0fed 100644 (file)
@@ -28,6 +28,7 @@
 #include "dc_dmub_srv.h"
 #include "panel_cntl.h"
 #include "dce_panel_cntl.h"
+#include "atom.h"
 
 #define TO_DCE_PANEL_CNTL(panel_cntl)\
        container_of(panel_cntl, struct dce_panel_cntl, base)
 #define FN(reg_name, 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)
@@ -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);
        uint32_t value;
 
-       REG_GET(PWRSEQ_CNTL, BLON, &value);
+       REG_GET(PWRSEQ_CNTL, LVTMA_BLON, &value);
 
        return value;
 }
@@ -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);
        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);
 }
 
+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)
 {
        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 = {
        .hw_init = dce_panel_cntl_hw_init,
        .is_panel_backlight_on = dce_is_panel_backlight_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(
@@ -95,6 +282,13 @@ void dce_panel_cntl_construct(
        const struct dce_panel_cntl_shift *shift,
        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->shift = shift;
        dce_panel_cntl->mask = mask;
index 6dc6984f92482231253e5c30e2c851c6ac28c56e..70ec691e14d2d4e07c40b19f7fb6da23e84f7535 100644 (file)
 #define DCE_PANEL_CNTL_REG_LIST()\
        DCE_PANEL_CNTL_SR(PWRSEQ_CNTL, LVTMA), \
        DCE_PANEL_CNTL_SR(PWRSEQ_STATE, LVTMA), \
+       DCE_PANEL_CNTL_SR(PWRSEQ_REF_DIV, LVTMA), \
        SR(BL_PWM_CNTL), \
        SR(BL_PWM_CNTL2), \
        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)\
        .reg_name = BASE(mm ## block ## _ ## reg_name ## _BASE_IDX) + \
 #define DCN_PANEL_CNTL_REG_LIST()\
        DCN_PANEL_CNTL_SR(PWRSEQ_CNTL, LVTMA), \
        DCN_PANEL_CNTL_SR(PWRSEQ_STATE, LVTMA), \
+       DCE_PANEL_CNTL_SR(PWRSEQ_REF_DIV, LVTMA), \
        SR(BL_PWM_CNTL), \
        SR(BL_PWM_CNTL2), \
        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)\
-       .field_name = block ## reg_name ## __ ## block ## field_name ## post_fix
+#define DCE_PANEL_CNTL_SF(reg_name, field_name, post_fix)\
+       .field_name = reg_name ## __ ## field_name ## post_fix
 
 #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, DIGON, mask_sh),\
-       DCE_PANEL_CNTL_SF(LVTMA_, PWRSEQ_CNTL, DIGON_OVRD, mask_sh),\
-       DCE_PANEL_CNTL_SF(LVTMA_, PWRSEQ_STATE, PWRSEQ_TARGET_STATE_R, mask_sh), \
-       DCE_PANEL_CNTL_SF(, BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, mask_sh), \
-       DCE_PANEL_CNTL_SF(, BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, 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_FRACTIONAL_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_IGNORE_MASTER_LOCK_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_REG_UPDATE_PENDING, mask_sh)
+       DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
+       DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_CNTL, LVTMA_DIGON, mask_sh),\
+       DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_CNTL, LVTMA_DIGON_OVRD, mask_sh),\
+       DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, 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, mask_sh), \
+       DCE_PANEL_CNTL_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, 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_FRACTIONAL_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_IGNORE_MASTER_LOCK_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_REG_UPDATE_PENDING, mask_sh)
 
 #define DCE_PANEL_CNTL_REG_FIELD_LIST(type) \
-       type BLON;\
-       type DIGON;\
-       type DIGON_OVRD;\
-       type PWRSEQ_TARGET_STATE_R; \
+       type LVTMA_BLON;\
+       type LVTMA_DIGON;\
+       type LVTMA_DIGON_OVRD;\
+       type LVTMA_PWRSEQ_TARGET_STATE_R; \
+       type BL_PWM_REF_DIV; \
        type BL_PWM_EN; \
        type BL_ACTIVE_INT_FRAC_CNT; \
        type BL_PWM_FRACTIONAL_EN; \
@@ -98,6 +104,8 @@ struct dce_panel_cntl_registers {
        uint32_t BL_PWM_CNTL2;
        uint32_t BL_PWM_PERIOD_CNTL;
        uint32_t BL_PWM_GRP1_REG_LOCK;
+       uint32_t PWRSEQ_REF_DIV;
+       uint32_t BIOS_SCRATCH_2;
 };
 
 struct dce_panel_cntl {
index 06d39d529c0962c88cb5aba8906dfb0d2f7833ea..c15a4f5b4c62cb8e81de6d6970ded57b8d29966c 100644 (file)
@@ -70,53 +70,6 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t panel
        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(
        struct dce_abm *dce_abm,
        uint32_t backlight_pwm_u16_16,
@@ -178,10 +131,9 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc)
        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);
-       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, 0x101);
@@ -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)
 {
-       struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
-
        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;
 }
 
@@ -340,8 +223,7 @@ static bool dmub_abm_set_backlight_level_pwm(
                unsigned int backlight_pwm_u16_16,
                unsigned int frame_ramp,
                unsigned int otg_inst,
-               uint32_t panel_inst,
-               bool fw_set_brightness)
+               uint32_t panel_inst)
 {
        struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
 
@@ -384,7 +266,6 @@ static bool dmub_abm_init_config(struct abm *abm,
 static const struct abm_funcs abm_funcs = {
        .abm_init = dmub_abm_init,
        .set_abm_level = dmub_abm_set_level,
-       .init_backlight = dmub_abm_init_backlight,
        .set_pipe = dmub_abm_set_pipe,
        .set_backlight_level_pwm = dmub_abm_set_backlight_level_pwm,
        .get_current_backlight = dmub_abm_get_current_backlight,
@@ -404,10 +285,6 @@ static void dmub_abm_construct(
 
        base->ctx = ctx;
        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;
 
        abm_dce->regs = regs;
index 6bd8d4e1c294f80e844f5d1a33fc4fc9e38af39b..b77e9dc1608634ca9ad7329e5ecd5081234b990e 100644 (file)
@@ -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) {
                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))
@@ -2355,6 +2355,7 @@ static void init_hw(struct dc *dc)
        struct abm *abm;
        struct dmcu *dmcu;
        struct dce_hwseq *hws = dc->hwseq;
+       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
 
        bp = dc->ctx->dc_bios;
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -2401,12 +2402,17 @@ static void init_hw(struct dc *dc)
                audio->funcs->hw_init(audio);
        }
 
-       abm = dc->res_pool->abm;
-       if (abm != NULL) {
-               abm->funcs->init_backlight(abm);
-               abm->funcs->abm_init(abm);
+       for (i = 0; i < dc->link_count; i++) {
+               struct dc_link *link = dc->links[i];
+
+               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;
        if (dmcu != NULL && abm != NULL)
                abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
@@ -2721,6 +2727,7 @@ bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
        struct dc_link *link = pipe_ctx->stream->link;
        struct dc  *dc = link->ctx->dc;
        struct abm *abm = pipe_ctx->stream_res.abm;
+       struct panel_cntl *panel_cntl = link->panel_cntl;
        struct dmcu *dmcu = dc->res_pool->dmcu;
        bool fw_set_brightness = true;
        /* DMCU -1 for all controller id values,
@@ -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;
 
-       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;
 
        if (dmcu)
                fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
 
-       abm->funcs->set_backlight_level_pwm(
-                       abm,
-                       backlight_pwm_u16_16,
-                       frame_ramp,
-                       controller_id,
-                       link->panel_cntl->inst,
-                       fw_set_brightness);
+       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,
+                               backlight_pwm_u16_16,
+                               frame_ramp,
+                               controller_id,
+                               link->panel_cntl->inst);
 
        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 = {
        .program_gamut_remap = program_gamut_remap,
        .program_output_csc = program_output_csc,
@@ -2781,6 +2803,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
        .set_cursor_position = dce110_set_cursor_position,
        .set_cursor_attribute = dce110_set_cursor_attribute,
        .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 = {
index e609a72b4634d0156e537999a5b658ad93e18dda..fe5326df00f7eb54b3d9e8981c73d5dd8213f437 100644 (file)
@@ -88,6 +88,7 @@ void dce110_edp_wait_for_hpd_ready(
 bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
                uint32_t backlight_pwm_u16_16,
                uint32_t frame_ramp);
+void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx);
 
 #endif /* __DC_HWSS_DCE110_H__ */
 
index 2eb5d0e3e4259644786ee857f8670a82bd0b8e5f..b33eafe45f76c0769182cc533cacbe68a395560f 100644 (file)
@@ -903,8 +903,7 @@ static void dcn10_reset_back_end_for_pipe(
        if (pipe_ctx->top_pipe == NULL) {
 
                if (pipe_ctx->stream_res.abm)
-                       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);
 
                pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
 
@@ -1245,6 +1244,7 @@ void dcn10_init_hw(struct dc *dc)
        struct dce_hwseq *hws = dc->hwseq;
        struct dc_bios *dcb = dc->ctx->dc_bios;
        struct resource_pool *res_pool = dc->res_pool;
+       uint32_t backlight = MAX_BACKLIGHT_LEVEL;
 
        if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
                dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
@@ -1411,11 +1411,16 @@ void dcn10_init_hw(struct dc *dc)
                audio->funcs->hw_init(audio);
        }
 
-       if (abm != NULL) {
-               abm->funcs->init_backlight(abm);
-               abm->funcs->abm_init(abm);
+       for (i = 0; i < dc->link_count; i++) {
+               struct dc_link *link = dc->links[i];
+
+               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)
                dmcu->funcs->dmcu_init(dmcu);
 
@@ -2490,9 +2495,7 @@ void dcn10_blank_pixel_data(
                        stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
                }
        } else if (blank) {
-               if (stream_res->abm)
-                       stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm,
-                                       stream->link->panel_cntl->inst);
+               dc->hwss.set_abm_immediate_disable(pipe_ctx);
                if (stream_res->tg->funcs->set_blank)
                        stream_res->tg->funcs->set_blank(stream_res->tg, blank);
        }
index 6ff7e2bd1d4a08e3d3b84e92440b2f60c6d8f923..897a3d25685a2ce985fea97b7369c9fa31981f99 100644 (file)
@@ -73,6 +73,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
        .get_clock = dcn10_get_clock,
        .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
        .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 = {
index 3a290ccaeb82ccb6b1cf9e344f6e31b6e661c04a..da5333d165ace594960bff5a8a667ea943b4256d 100644 (file)
@@ -961,9 +961,7 @@ void dcn20_blank_pixel_data(
        width = width / odm_cnt;
 
        if (blank) {
-               if (stream_res->abm)
-                       stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm,
-                                       stream->link->panel_cntl->inst);
+               dc->hwss.set_abm_immediate_disable(pipe_ctx);
 
                if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) {
                        test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
@@ -2042,9 +2040,7 @@ static void dcn20_reset_back_end_for_pipe(
         */
        if (pipe_ctx->top_pipe == NULL) {
 
-               if (pipe_ctx->stream_res.abm)
-                       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);
 
                pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
 
index c83d98e0d211042a7f5caf26c6adc586a901b27a..a8bcd747d7ba2293597278089f5d4542cff0a80d 100644 (file)
@@ -84,6 +84,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
        .set_flip_control_gsl = dcn20_set_flip_control_gsl,
        .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
        .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 = {
index 2c87e571579a615296701cfc83254c629e62658a..e97dfaa656e93bf57be23501691932125fb2efa8 100644 (file)
@@ -88,6 +88,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
        .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
        .power_down = dce110_power_down,
        .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 = {
index 91a42f0f1fc45b1994dd08222540581c3e905ab5..e8ce8c85adf1c48cf1aaf7683452f2482e8d9a87 100644 (file)
 
 #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 dc_context *ctx;
        const struct abm_funcs *funcs;
        bool dmcu_is_running;
-       /* registers setting needs to be saved and restored at InitBacklight */
-       struct abm_backlight_registers stored_backlight_registers;
 };
 
 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_immediate_disable)(struct abm *abm, 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,
         * 16 bit integer + 16 fractional, where 1.0 is max backlight value.
@@ -56,8 +46,7 @@ struct abm_funcs {
                        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);
 
        unsigned int (*get_current_backlight)(struct abm *abm);
        unsigned int (*get_target_backlight)(struct abm *abm);
index 5a75d035f1fab267b3f440514fa46485cd95d6fa..f9ab5abb64623fe07ceab8db676a539baef747dd 100644 (file)
 
 #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 {
        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_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 {
@@ -48,6 +60,8 @@ struct panel_cntl {
        const struct panel_cntl_funcs *funcs;
        struct dc_context *ctx;
        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_ */
index 1570fed20de07992ca32763fe594992b9457aaad..3b2ea9bdb62c2522457d6f3bf22085df5da40251 100644 (file)
@@ -196,6 +196,8 @@ struct hw_sequencer_funcs {
                        uint32_t backlight_pwm_u16_16,
                        uint32_t frame_ramp);
 
+       void (*set_abm_immediate_disable)(struct pipe_ctx *pipe_ctx);
+
 
 };