From: Lewis Huang <lewis.hu...@amd.com>

[Why]
Need to disable EDP backlight when enter S4 with EDP only
and resume from S4 with secondary only.

[How]
Align the real hw and sw state via vBios scratch register in
function enable_accelerated_mode when resume from S4.

Signed-off-by: Lewis Huang <lewis.hu...@amd.com>
Reviewed-by: Charlene Liu <charlene....@amd.com>
Acked-by: Leo Li <sunpeng...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c |  2 +
 .../drm/amd/display/dc/bios/bios_parser_helper.c   | 93 ++++++++++++++++++++++
 .../drm/amd/display/dc/bios/bios_parser_helper.h   |  4 +
 drivers/gpu/drm/amd/display/dc/dc_bios_types.h     |  5 ++
 .../amd/display/dc/dce110/dce110_hw_sequencer.c    | 15 ++++
 .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c  |  1 +
 6 files changed, 120 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c 
b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
index ff764da..751bb61 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -1884,6 +1884,8 @@ static const struct dc_vbios_funcs vbios_funcs = {
 
        .is_accelerated_mode = bios_parser_is_accelerated_mode,
 
+       .is_active_display = bios_is_active_display,
+
        .set_scratch_critical_state = bios_parser_set_scratch_critical_state,
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c 
b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
index d458947..fdda8aa 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
@@ -88,3 +88,96 @@ uint32_t bios_get_vga_enabled_displays(
        return active_disp;
 }
 
+bool bios_is_active_display(
+               struct dc_bios *bios,
+               enum signal_type signal,
+               const struct connector_device_tag_info *device_tag)
+{
+       uint32_t active = 0;
+       uint32_t connected = 0;
+       uint32_t bios_scratch_0 = 0;
+       uint32_t bios_scratch_3 = 0;
+
+       switch (signal) {
+       case SIGNAL_TYPE_DVI_SINGLE_LINK:
+       case SIGNAL_TYPE_DVI_DUAL_LINK:
+       case SIGNAL_TYPE_HDMI_TYPE_A:
+       case SIGNAL_TYPE_DISPLAY_PORT:
+       case SIGNAL_TYPE_DISPLAY_PORT_MST:
+               {
+                       if (device_tag->dev_id.device_type == DEVICE_TYPE_DFP) {
+                               switch (device_tag->dev_id.enum_id)     {
+                               case 1:
+                                       {
+                                               active    = ATOM_S3_DFP1_ACTIVE;
+                                               connected = 0x0008;     
//ATOM_DISPLAY_DFP1_CONNECT
+                                       }
+                                       break;
+
+                               case 2:
+                                       {
+                                               active    = ATOM_S3_DFP2_ACTIVE;
+                                               connected = 0x0080; 
//ATOM_DISPLAY_DFP2_CONNECT
+                                       }
+                                       break;
+
+                               case 3:
+                                       {
+                                               active    = ATOM_S3_DFP3_ACTIVE;
+                                               connected = 0x0200; 
//ATOM_DISPLAY_DFP3_CONNECT
+                                       }
+                                       break;
+
+                               case 4:
+                                       {
+                                               active    = ATOM_S3_DFP4_ACTIVE;
+                                               connected = 0x0400;     
//ATOM_DISPLAY_DFP4_CONNECT
+                                       }
+                                       break;
+
+                               case 5:
+                                       {
+                                               active    = ATOM_S3_DFP5_ACTIVE;
+                                               connected = 0x0800; 
//ATOM_DISPLAY_DFP5_CONNECT
+                                       }
+                                       break;
+
+                               case 6:
+                                       {
+                                               active    = ATOM_S3_DFP6_ACTIVE;
+                                               connected = 0x0040; 
//ATOM_DISPLAY_DFP6_CONNECT
+                                       }
+                                       break;
+
+                               default:
+                                       break;
+                               }
+                               }
+                       }
+                       break;
+
+       case SIGNAL_TYPE_LVDS:
+       case SIGNAL_TYPE_EDP:
+               {
+                       active    = ATOM_S3_LCD1_ACTIVE;
+                       connected = 0x0002;     //ATOM_DISPLAY_LCD1_CONNECT
+               }
+               break;
+
+       default:
+               break;
+       }
+
+
+       if (bios->regs->BIOS_SCRATCH_0) /*follow up with other asic, todo*/
+               bios_scratch_0 = REG_READ(BIOS_SCRATCH_0);
+       if (bios->regs->BIOS_SCRATCH_3) /*follow up with other asic, todo*/
+               bios_scratch_3 = REG_READ(BIOS_SCRATCH_3);
+
+       bios_scratch_3 &= ATOM_S3_DEVICE_ACTIVE_MASK;
+       if ((active & bios_scratch_3) && (connected & bios_scratch_0))
+               return true;
+
+       return false;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h 
b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h
index 75a29e6..f33cac2 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h
@@ -35,6 +35,10 @@ bool bios_is_accelerated_mode(struct dc_bios *bios);
 void bios_set_scratch_acc_mode_change(struct dc_bios *bios);
 void bios_set_scratch_critical_state(struct dc_bios *bios, bool state);
 uint32_t bios_get_vga_enabled_displays(struct dc_bios *bios);
+bool bios_is_active_display(
+       struct dc_bios *bios,
+       enum signal_type signal,
+       const struct connector_device_tag_info *device_tag);
 
 #define GET_IMAGE(type, offset) ((type *) bios_get_image(&bp->base, offset, 
sizeof(type)))
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
index 8130b95..a8b3ced 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
@@ -86,6 +86,10 @@ struct dc_vbios_funcs {
 
        bool (*is_accelerated_mode)(
                struct dc_bios *bios);
+       bool (*is_active_display)(
+               struct dc_bios *bios,
+               enum signal_type signal,
+               const struct connector_device_tag_info *device_tag);
        void (*set_scratch_critical_state)(
                struct dc_bios *bios,
                bool state);
@@ -141,6 +145,7 @@ struct dc_vbios_funcs {
 };
 
 struct bios_registers {
+       uint32_t BIOS_SCRATCH_0;
        uint32_t BIOS_SCRATCH_3;
        uint32_t BIOS_SCRATCH_6;
 };
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 8873a609..4789270 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
@@ -1546,6 +1546,7 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct 
dc_state *context)
        int i;
        struct dc_link *edp_link_to_turnoff = NULL;
        struct dc_link *edp_link = get_link_for_edp(dc);
+       struct dc_bios *bios = dc->ctx->dc_bios;
        bool can_edp_fast_boot_optimize = false;
        bool apply_edp_fast_boot_optimization = false;
 
@@ -1572,6 +1573,20 @@ void dce110_enable_accelerated_mode(struct dc *dc, 
struct dc_state *context)
                        if (context->streams[i]->signal == SIGNAL_TYPE_EDP) {
                                
context->streams[i]->apply_edp_fast_boot_optimization = true;
                                apply_edp_fast_boot_optimization = true;
+
+                               /* When after S4 and S5, vbios may post edp and 
previous dpms_off
+                                * doesn't make sense.
+                                * Update dpms_off state to align hw and sw 
state via check
+                                * vBios scratch register.
+                                */
+                               if (bios->funcs->is_active_display)     {
+                                       const struct connector_device_tag_info 
*device_tag = &(edp_link->device_tag);
+
+                                       if (bios->funcs->is_active_display(bios,
+                                                       
context->streams[i]->signal,
+                                                       device_tag))
+                                               context->streams[i]->dpms_off = 
false;
+                               }
                        }
                }
        }
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index acb917d..47dbe4b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -438,6 +438,7 @@ static const struct dcn_optc_mask tg_mask = {
 
 
 static const struct bios_registers bios_regs = {
+               NBIO_SR(BIOS_SCRATCH_0),
                NBIO_SR(BIOS_SCRATCH_3),
                NBIO_SR(BIOS_SCRATCH_6)
 };
-- 
2.7.4

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to