From: Leon Huang <[email protected]>

[Why]
set ABM pipe/backlight gets some issues when abm callback func pointers
are NULL. For some usecase, driver would like to control PWM level before
ABM resource is ready. However, recent flow refactor of ABM didn't
consider that use case.

[How]
Rollback flow that sending inbox command to dmub directly when ABM
function pointers aren't ready.

Reviewed-by: Rodrigo Siqueira <[email protected]>
Signed-off-by: Leon Huang <[email protected]>
---
 .../drm/amd/display/dc/dcn21/dcn21_hwseq.c    | 64 ++++++++++++++-----
 1 file changed, 47 insertions(+), 17 deletions(-)

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 2a182c2f57d6..1c6477d73c8e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
@@ -159,6 +159,25 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t 
otg_inst, uint32_t optio
        return true;
 }
 
+static void dmub_abm_set_backlight(struct dc_context *dc, uint32_t 
backlight_pwm_u16_16,
+                                                                       
uint32_t frame_ramp, uint32_t panel_inst)
+{
+       union dmub_rb_cmd cmd;
+
+       memset(&cmd, 0, sizeof(cmd));
+       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.abm_set_backlight_data.version = 
DMUB_CMD_ABM_CONTROL_VERSION_1;
+       cmd.abm_set_backlight.abm_set_backlight_data.panel_mask = (0x01 << 
panel_inst);
+       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);
+}
+
 void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
 {
        struct abm *abm = pipe_ctx->stream_res.abm;
@@ -173,8 +192,12 @@ void dcn21_set_abm_immediate_disable(struct pipe_ctx 
*pipe_ctx)
        }
 
        if (abm && panel_cntl) {
-               dmub_abm_set_pipe(abm, otg_inst, 
SET_ABM_PIPE_IMMEDIATELY_DISABLE,
-                               panel_cntl->inst);
+               if (abm->funcs && abm->funcs->set_pipe_ex) {
+                       abm->funcs->set_pipe_ex(abm, otg_inst, 
SET_ABM_PIPE_IMMEDIATELY_DISABLE,
+                       panel_cntl->inst);
+               } else {
+                       dmub_abm_set_pipe(abm, otg_inst, 
SET_ABM_PIPE_IMMEDIATELY_DISABLE, panel_cntl->inst);
+               }
                panel_cntl->funcs->store_backlight_level(panel_cntl);
        }
 }
@@ -191,8 +214,13 @@ void dcn21_set_pipe(struct pipe_ctx *pipe_ctx)
                return;
        }
 
-       if (abm && panel_cntl)
-               dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, 
panel_cntl->inst);
+       if (abm && panel_cntl) {
+               if (abm->funcs && abm->funcs->set_pipe_ex) {
+                       abm->funcs->set_pipe_ex(abm, otg_inst, 
SET_ABM_PIPE_NORMAL, panel_cntl->inst);
+               } else {
+                       dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, 
panel_cntl->inst);
+               }
+       }
 }
 
 bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
@@ -210,21 +238,23 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
                return true;
        }
 
-       if (abm && panel_cntl)
-               dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, 
panel_cntl->inst);
+       if (abm != NULL) {
+               uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
 
-       memset(&cmd, 0, sizeof(cmd));
-       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.abm_set_backlight_data.version = 
DMUB_CMD_ABM_CONTROL_VERSION_1;
-       cmd.abm_set_backlight.abm_set_backlight_data.panel_mask = (0x01 << 
panel_cntl->inst);
-       cmd.abm_set_backlight.header.payload_bytes = sizeof(struct 
dmub_cmd_abm_set_backlight_data);
+               if (abm && panel_cntl) {
+                       if (abm->funcs && abm->funcs->set_pipe_ex) {
+                               abm->funcs->set_pipe_ex(abm, otg_inst, 
SET_ABM_PIPE_NORMAL, panel_cntl->inst);
+                       } else {
+                               dmub_abm_set_pipe(abm, otg_inst, 
SET_ABM_PIPE_NORMAL, panel_cntl->inst);
+                       }
+               }
+       }
 
-       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);
+       if (abm && abm->funcs && abm->funcs->set_backlight_level_pwm)
+               abm->funcs->set_backlight_level_pwm(abm, backlight_pwm_u16_16,
+                       frame_ramp, 0, panel_cntl->inst);
+       else
+               dmub_abm_set_backlight(dc, backlight_pwm_u16_16, frame_ramp, 
panel_cntl->inst);
 
        return true;
 }
-- 
2.34.1

Reply via email to