From 474ac4a875ca6fea3fc5183d3ad22ef7523dca53 Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Mon, 27 Apr 2020 12:49:39 -0400 Subject: [PATCH] drm/amd/display: Implement some asic specific abm call backs. [Why & How] Implement abm set_pipe call stacks Have some asics speicifc call stacks for abm. Signed-off-by: Yongqiang Sun Reviewed-by: Anthony Koo Acked-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c | 92 ------------------- .../display/dc/dce110/dce110_hw_sequencer.c | 11 +++ .../display/dc/dce110/dce110_hw_sequencer.h | 1 + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_init.c | 1 + .../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 3 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_init.c | 1 + .../drm/amd/display/dc/dcn21/dcn21_hwseq.c | 89 ++++++++++++++++++ .../drm/amd/display/dc/dcn21/dcn21_hwseq.h | 6 ++ .../gpu/drm/amd/display/dc/dcn21/dcn21_init.c | 5 +- .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 2 + .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 4 + 12 files changed, 120 insertions(+), 98 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c index da0b29abfbda..0cf130dc4e52 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c @@ -50,71 +50,7 @@ #define DISABLE_ABM_IMMEDIATELY 255 -static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t panel_inst) -{ - union dmub_rb_cmd cmd; - struct dc_context *dc = abm->ctx; - uint32_t ramping_boundary = 0xFFFF; - - cmd.abm_set_pipe.header.type = DMUB_CMD__ABM; - cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE; - cmd.abm_set_pipe.abm_set_pipe_data.otg_inst = otg_inst; - cmd.abm_set_pipe.abm_set_pipe_data.panel_inst = panel_inst; - cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary; - cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data); - - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); - dc_dmub_srv_cmd_execute(dc->dmub_srv); - dc_dmub_srv_wait_idle(dc->dmub_srv); - - return true; -} - -static void dmcub_set_backlight_level( - struct dce_abm *dce_abm, - uint32_t backlight_pwm_u16_16, - uint32_t frame_ramp, - uint32_t otg_inst, - uint32_t panel_inst) -{ - union dmub_rb_cmd cmd; - struct dc_context *dc = dce_abm->base.ctx; - unsigned int backlight_8_bit = 0; - uint32_t s2; - - if (backlight_pwm_u16_16 & 0x10000) - // Check for max backlight condition - backlight_8_bit = 0xFF; - else - // Take MSB of fractional part since backlight is not max - backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF; - - dmub_abm_set_pipe(&dce_abm->base, otg_inst, panel_inst); - - REG_UPDATE(BL1_PWM_USER_LEVEL, BL1_PWM_USER_LEVEL, backlight_pwm_u16_16); - - if (otg_inst == 0) - frame_ramp = 0; - - cmd.abm_set_backlight.header.type = DMUB_CMD__ABM; - cmd.abm_set_backlight.header.sub_type = DMUB_CMD__ABM_SET_BACKLIGHT; - cmd.abm_set_backlight.abm_set_backlight_data.frame_ramp = frame_ramp; - cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data); - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); - dc_dmub_srv_cmd_execute(dc->dmub_srv); - dc_dmub_srv_wait_idle(dc->dmub_srv); - - // Update requested backlight level - s2 = REG_READ(BIOS_SCRATCH_2); - - s2 &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK; - backlight_8_bit &= (ATOM_S2_CURRENT_BL_LEVEL_MASK >> - ATOM_S2_CURRENT_BL_LEVEL_SHIFT); - s2 |= (backlight_8_bit << ATOM_S2_CURRENT_BL_LEVEL_SHIFT); - - REG_WRITE(BIOS_SCRATCH_2, s2); -} static void dmub_abm_enable_fractional_pwm(struct dc_context *dc) { @@ -211,31 +147,6 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level) return true; } -static bool dmub_abm_immediate_disable(struct abm *abm, uint32_t panel_inst) -{ - dmub_abm_set_pipe(abm, DISABLE_ABM_IMMEDIATELY, panel_inst); - - return true; -} - -static bool dmub_abm_set_backlight_level_pwm( - struct abm *abm, - unsigned int backlight_pwm_u16_16, - unsigned int frame_ramp, - unsigned int otg_inst, - uint32_t panel_inst) -{ - struct dce_abm *dce_abm = TO_DMUB_ABM(abm); - - dmcub_set_backlight_level(dce_abm, - backlight_pwm_u16_16, - frame_ramp, - otg_inst, - panel_inst); - - return true; -} - static bool dmub_abm_init_config(struct abm *abm, const char *src, unsigned int bytes) @@ -266,11 +177,8 @@ 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, - .set_pipe = dmub_abm_set_pipe, - .set_backlight_level_pwm = dmub_abm_set_backlight_level_pwm, .get_current_backlight = dmub_abm_get_current_backlight, .get_target_backlight = dmub_abm_get_target_backlight, - .set_abm_immediate_disable = dmub_abm_immediate_disable, .init_abm_config = dmub_abm_init_config, }; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index b77e9dc16086..a475e529ae1c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2767,6 +2767,16 @@ void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx) panel_cntl->funcs->store_backlight_level(panel_cntl); } +void dce110_set_pipe(struct pipe_ctx *pipe_ctx) +{ + struct abm *abm = pipe_ctx->stream_res.abm; + struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; + uint32_t otg_inst = pipe_ctx->stream_res.tg->inst + 1; + + if (abm && panel_cntl) + abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst); +} + static const struct hw_sequencer_funcs dce110_funcs = { .program_gamut_remap = program_gamut_remap, .program_output_csc = program_output_csc, @@ -2804,6 +2814,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { .set_cursor_attribute = dce110_set_cursor_attribute, .set_backlight_level = dce110_set_backlight_level, .set_abm_immediate_disable = dce110_set_abm_immediate_disable, + .set_pipe = dce110_set_pipe, }; static const struct hwseq_private_funcs dce110_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h index fe5326df00f7..b6f3843d3d05 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h @@ -89,6 +89,7 @@ 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); +void dce110_set_pipe(struct pipe_ctx *pipe_ctx); #endif /* __DC_HWSS_DCE110_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 77f16921e7f0..0313ca83cdb9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2576,8 +2576,7 @@ void dcn10_blank_pixel_data( if (stream_res->tg->funcs->set_blank) stream_res->tg->funcs->set_blank(stream_res->tg, blank); if (stream_res->abm) { - stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1, - stream->link->panel_cntl->inst); + dc->hwss.set_pipe(pipe_ctx); stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level); } } else if (blank) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c index 7cb8c3fb2665..f6a790c49321 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c @@ -75,6 +75,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .calc_vupdate_position = dcn10_calc_vupdate_position, .set_backlight_level = dce110_set_backlight_level, .set_abm_immediate_disable = dce110_set_abm_immediate_disable, + .set_pipe = dce110_set_pipe, }; static const struct hwseq_private_funcs dcn10_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index da5333d165ac..258dcd33787e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -996,8 +996,7 @@ void dcn20_blank_pixel_data( if (!blank) if (stream_res->abm) { - stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1, - stream->link->panel_cntl->inst); + dc->hwss.set_pipe(pipe_ctx); stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level); } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c index 2fbde4241559..bb9e9bec2f28 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c @@ -86,6 +86,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { .calc_vupdate_position = dcn10_calc_vupdate_position, .set_backlight_level = dce110_set_backlight_level, .set_abm_immediate_disable = dce110_set_abm_immediate_disable, + .set_pipe = dce110_set_pipe, }; static const struct hwseq_private_funcs dcn20_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c index ada65b1a7eb1..01f1d3d9a639 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c @@ -28,10 +28,13 @@ #include "core_types.h" #include "resource.h" #include "dce/dce_hwseq.h" +#include "dce110/dce110_hw_sequencer.h" #include "dcn21_hwseq.h" #include "vmid.h" #include "reg_helper.h" #include "hw/clk_mgr.h" +#include "dc_dmub_srv.h" +#include "abm.h" #define DC_LOGGER_INIT(logger) @@ -134,3 +137,89 @@ void dcn21_PLAT_58856_wa(struct dc_state *context, struct pipe_ctx *pipe_ctx) pipe_ctx->stream->dpms_off = true; } +static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t option, uint32_t panel_inst) +{ + union dmub_rb_cmd cmd; + struct dc_context *dc = abm->ctx; + uint32_t ramping_boundary = 0xFFFF; + + cmd.abm_set_pipe.header.type = DMUB_CMD__ABM; + cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE; + cmd.abm_set_pipe.abm_set_pipe_data.otg_inst = otg_inst; + cmd.abm_set_pipe.abm_set_pipe_data.set_pipe_option = option; + cmd.abm_set_pipe.abm_set_pipe_data.panel_inst = panel_inst; + cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary; + cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data); + + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); + dc_dmub_srv_cmd_execute(dc->dmub_srv); + dc_dmub_srv_wait_idle(dc->dmub_srv); + + return true; +} + +void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx) +{ + struct abm *abm = pipe_ctx->stream_res.abm; + uint32_t otg_inst = pipe_ctx->stream_res.tg->inst; + struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; + + struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu; + + if (dmcu) { + dce110_set_abm_immediate_disable(pipe_ctx); + return; + } + + if (abm && panel_cntl) + dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_IMMEDIATELY_DISABLE, + panel_cntl->inst); +} + +void dcn21_set_pipe(struct pipe_ctx *pipe_ctx) +{ + struct abm *abm = pipe_ctx->stream_res.abm; + uint32_t otg_inst = pipe_ctx->stream_res.tg->inst; + struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; + struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu; + + if (dmcu) { + dce110_set_pipe(pipe_ctx); + return; + } + + if (abm && panel_cntl) + dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst); +} + +bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, + uint32_t backlight_pwm_u16_16, + uint32_t frame_ramp) +{ + union dmub_rb_cmd cmd; + struct dc_context *dc = pipe_ctx->stream->ctx; + struct abm *abm = pipe_ctx->stream_res.abm; + uint32_t otg_inst = pipe_ctx->stream_res.tg->inst; + struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; + + if (dc->dc->res_pool->dmcu) { + dce110_set_backlight_level(pipe_ctx, backlight_pwm_u16_16, frame_ramp); + return true; + } + + if (abm && panel_cntl) + dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst); + + cmd.abm_set_backlight.header.type = DMUB_CMD__ABM; + cmd.abm_set_backlight.header.sub_type = DMUB_CMD__ABM_SET_BACKLIGHT; + cmd.abm_set_backlight.abm_set_backlight_data.frame_ramp = frame_ramp; + cmd.abm_set_backlight.abm_set_backlight_data.backlight_user_level = backlight_pwm_u16_16; + cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data); + + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); + dc_dmub_srv_cmd_execute(dc->dmub_srv); + dc_dmub_srv_wait_idle(dc->dmub_srv); + + return true; +} + diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h index 26bf24d3b59f..9e97747e57cd 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h @@ -47,4 +47,10 @@ void dcn21_optimize_pwr_state( void dcn21_PLAT_58856_wa(struct dc_state *context, struct pipe_ctx *pipe_ctx); +void dcn21_set_pipe(struct pipe_ctx *pipe_ctx); +void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx); +bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, + uint32_t backlight_pwm_u16_16, + uint32_t frame_ramp); + #endif /* __DC_HWSS_DCN21_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c index a5baef7e7a7d..8575de1a8ad2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c @@ -88,8 +88,9 @@ static const struct hw_sequencer_funcs dcn21_funcs = { .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .calc_vupdate_position = dcn10_calc_vupdate_position, .power_down = dce110_power_down, - .set_backlight_level = dce110_set_backlight_level, - .set_abm_immediate_disable = dce110_set_abm_immediate_disable, + .set_backlight_level = dcn21_set_backlight_level, + .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, + .set_pipe = dcn21_set_pipe, }; static const struct hwseq_private_funcs dcn21_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 8e72f077e552..4f9216c96e59 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -203,6 +203,8 @@ struct hw_sequencer_funcs { void (*set_abm_immediate_disable)(struct pipe_ctx *pipe_ctx); + void (*set_pipe)(struct pipe_ctx *pipe_ctx); + }; diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 599bf2055bcb..cbfde2706c18 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -36,6 +36,9 @@ #define DMUB_RB_SIZE (DMUB_RB_CMD_SIZE * DMUB_RB_MAX_ENTRY) #define REG_SET_MASK 0xFFFF +#define SET_ABM_PIPE_GRADUALLY_DISABLE 0 +#define SET_ABM_PIPE_IMMEDIATELY_DISABLE 255 +#define SET_ABM_PIPE_NORMAL 1 /* * Command IDs should be treated as stable ABI. @@ -272,6 +275,7 @@ struct dmub_rb_cmd_abm_set_pipe { struct dmub_cmd_abm_set_backlight_data { uint32_t frame_ramp; + uint32_t backlight_user_level; }; struct dmub_rb_cmd_abm_set_backlight { -- 2.25.1