drm/amd/display: Optimize link power-down when link powered externally
authorTony Tascioglu <tony.tascioglu@amd.com>
Fri, 25 Nov 2022 22:31:44 +0000 (17:31 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 17 Jan 2023 20:39:39 +0000 (15:39 -0500)
[Why]
When an eDP panel is powered externally by a different GPU, we don't need
to wait for hardware sequencing delays when powering down a link, as the
display is not dependent on the GPU being powered down.

[How]
This commit adds a variable 'link_powered_externally' to indicate when a
link is being powered by another GPU.

Tested-by: Daniel Wheeler <Daniel.Wheeler@amd.com>
Reviewed-by: Felipe Clark <felipe.clark@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Tony Tascioglu <tony.tascioglu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
drivers/gpu/drm/amd/display/dc/bios/command_table2.c
drivers/gpu/drm/amd/display/dc/bios/command_table2.h
drivers/gpu/drm/amd/display/dc/dc_bios_types.h
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h

index 8ca50c0888586ea9225391f19f17fc934a751470..9f11dcf67c2813cc099e965ba25ad2dfe4ff010f 100644 (file)
@@ -1697,14 +1697,15 @@ static enum bp_result bios_parser_enable_disp_power_gating(
 static enum bp_result bios_parser_enable_lvtma_control(
        struct dc_bios *dcb,
        uint8_t uc_pwr_on,
-       uint8_t panel_instance)
+       uint8_t panel_instance,
+       uint8_t bypass_powerdown_wait)
 {
        struct bios_parser *bp = BP_FROM_DCB(dcb);
 
        if (!bp->cmd_tbl.enable_lvtma_control)
                return BP_RESULT_FAILURE;
 
-       return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on, panel_instance);
+       return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on, panel_instance, bypass_powerdown_wait);
 }
 
 static bool bios_parser_is_accelerated_mode(
index f52f7ff7ead4b60f68034c979c652120e9439192..91adebc5c5b738c9b9562b57c740b7cddd512826 100644 (file)
@@ -986,7 +986,8 @@ static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id)
 static enum bp_result enable_lvtma_control(
        struct bios_parser *bp,
        uint8_t uc_pwr_on,
-       uint8_t panel_instance);
+       uint8_t panel_instance,
+       uint8_t bypass_powerdown_wait);
 
 static void init_enable_lvtma_control(struct bios_parser *bp)
 {
@@ -998,7 +999,8 @@ static void init_enable_lvtma_control(struct bios_parser *bp)
 static void enable_lvtma_control_dmcub(
        struct dc_dmub_srv *dmcub,
        uint8_t uc_pwr_on,
-       uint8_t panel_instance)
+       uint8_t panel_instance,
+       uint8_t bypass_powerdown_wait)
 {
 
        union dmub_rb_cmd cmd;
@@ -1012,6 +1014,8 @@ static void enable_lvtma_control_dmcub(
                        uc_pwr_on;
        cmd.lvtma_control.data.panel_inst =
                        panel_instance;
+       cmd.lvtma_control.data.bypass_powerdown_wait =
+                       bypass_powerdown_wait;
        dc_dmub_srv_cmd_queue(dmcub, &cmd);
        dc_dmub_srv_cmd_execute(dmcub);
        dc_dmub_srv_wait_idle(dmcub);
@@ -1021,7 +1025,8 @@ static void enable_lvtma_control_dmcub(
 static enum bp_result enable_lvtma_control(
        struct bios_parser *bp,
        uint8_t uc_pwr_on,
-       uint8_t panel_instance)
+       uint8_t panel_instance,
+       uint8_t bypass_powerdown_wait)
 {
        enum bp_result result = BP_RESULT_FAILURE;
 
@@ -1029,7 +1034,8 @@ static enum bp_result enable_lvtma_control(
            bp->base.ctx->dc->debug.dmub_command_table) {
                enable_lvtma_control_dmcub(bp->base.ctx->dmub_srv,
                                uc_pwr_on,
-                               panel_instance);
+                               panel_instance,
+                               bypass_powerdown_wait);
                return BP_RESULT_OK;
        }
        return result;
index be060b4b87db6ab6af023fde4c42ef8cba6ebc74..acb7cc69f699b0395dc18068d0aeef374fdc0496 100644 (file)
@@ -96,7 +96,8 @@ struct cmd_tbl {
                        struct bios_parser *bp, uint8_t id);
        enum bp_result (*enable_lvtma_control)(struct bios_parser *bp,
                        uint8_t uc_pwr_on,
-                       uint8_t panel_instance);
+                       uint8_t panel_instance,
+                       uint8_t bypass_powerdown_wait);
 };
 
 void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp);
index 260ac4458870bf59afa290c7cc685d14feaab9a1..07d996c992ed3e083c299d98420c0ff6f6955d1c 100644 (file)
@@ -140,7 +140,8 @@ struct dc_vbios_funcs {
        enum bp_result (*enable_lvtma_control)(
                struct dc_bios *bios,
                uint8_t uc_pwr_on,
-               uint8_t panel_instance);
+               uint8_t panel_instance,
+               uint8_t bypass_powerdown_wait);
 
        enum bp_result (*get_soc_bb_info)(
                struct dc_bios *dcb,
index 63fe60dd3ea33d05f1d9e74f28a70152920f6b22..48f6a5b0933611ab3fabd607fd429ee3be065644 100644 (file)
@@ -294,6 +294,8 @@ struct dc_link {
 
        struct gpio *hpd_gpio;
        enum dc_link_fec_state fec_state;
+       bool link_powered_externally;   // Used to bypass hardware sequencing delays when panel is powered down forcibly
+
        struct dc_panel_config panel_config;
        struct phy_state phy_state;
 };
index 94be3ffcdea0235e8fda84123f7bb39536d06c63..ef5afd2a5cf7030aabad9201f2366d87a3011851 100644 (file)
@@ -875,14 +875,16 @@ void dce110_edp_power_control(
 
                if (ctx->dc->ctx->dmub_srv &&
                                ctx->dc->debug.dmub_command_table) {
-                       if (cntl.action == TRANSMITTER_CONTROL_POWER_ON)
+
+                       if (cntl.action == TRANSMITTER_CONTROL_POWER_ON) {
                                bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
                                                LVTMA_CONTROL_POWER_ON,
-                                               panel_instance);
-                       else
+                                               panel_instance, link->link_powered_externally);
+                       } else {
                                bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
                                                LVTMA_CONTROL_POWER_OFF,
-                                               panel_instance);
+                                               panel_instance, link->link_powered_externally);
+                       }
                }
 
                bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
@@ -1025,11 +1027,11 @@ void dce110_edp_backlight_control(
                if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON)
                        ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
                                        LVTMA_CONTROL_LCD_BLON,
-                                       panel_instance);
+                                       panel_instance, 0);
                else
                        ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
                                        LVTMA_CONTROL_LCD_BLOFF,
-                                       panel_instance);
+                                       panel_instance, 0);
        }
 
        link_transmitter_control(ctx->dc_bios, &cntl);
index 328978ec6814bff21feaa4ecaaed6ad915d284c4..b3acdb53875c1fa874281cca902ec691d548fd9e 100644 (file)
@@ -3111,7 +3111,8 @@ struct dmub_rb_cmd_panel_cntl {
  */
 struct dmub_cmd_lvtma_control_data {
        uint8_t uc_pwr_action; /**< LVTMA_ACTION */
-       uint8_t reserved_0[3]; /**< For future use */
+       uint8_t bypass_powerdown_wait;
+       uint8_t reserved_0[2];
        uint8_t panel_inst; /**< LVTMA control instance */
        uint8_t reserved_1[3]; /**< For future use */
 };