OSDN Git Service

drm/amd/display: Fixed hardware power down bypass during headless boot
authorJake Wang <haonan.wang2@amd.com>
Wed, 30 Jun 2021 17:55:50 +0000 (13:55 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 23 Jul 2021 14:07:58 +0000 (10:07 -0400)
[Why]
During headless boot, DIG may be on which causes HW/SW discrepancies.
To avoid this we power down hardware on boot if DIG is turned on. With
introduction of multiple eDP, hardware power down is being bypassed
under certain conditions.

[How]
Fixed hardware power down bypass, and ensured hardware will power down
if DIG is on and seamless boot is not enabled.

Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Jake Wang <haonan.wang2@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c

index f0f234e..89e6837 100644 (file)
@@ -1502,25 +1502,22 @@ void dcn10_init_hw(struct dc *dc)
 void dcn10_power_down_on_boot(struct dc *dc)
 {
        struct dc_link *edp_links[MAX_NUM_EDP];
-       struct dc_link *edp_link;
+       struct dc_link *edp_link = NULL;
        int edp_num;
        int i = 0;
 
        get_edp_links(dc, edp_links, &edp_num);
-
-       if (edp_num) {
-               for (i = 0; i < edp_num; i++) {
-                       edp_link = edp_links[i];
-                       if (edp_link->link_enc->funcs->is_dig_enabled &&
-                                       edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
-                                       dc->hwseq->funcs.edp_backlight_control &&
-                                       dc->hwss.power_down &&
-                                       dc->hwss.edp_power_control) {
-                               dc->hwseq->funcs.edp_backlight_control(edp_link, false);
-                               dc->hwss.power_down(dc);
-                               dc->hwss.edp_power_control(edp_link, false);
-                       }
-               }
+       if (edp_num)
+               edp_link = edp_links[0];
+
+       if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
+                       edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
+                       dc->hwseq->funcs.edp_backlight_control &&
+                       dc->hwss.power_down &&
+                       dc->hwss.edp_power_control) {
+               dc->hwseq->funcs.edp_backlight_control(edp_link, false);
+               dc->hwss.power_down(dc);
+               dc->hwss.edp_power_control(edp_link, false);
        } else {
                for (i = 0; i < dc->link_count; i++) {
                        struct dc_link *link = dc->links[i];
index c68e3a7..2e8ab97 100644 (file)
@@ -580,22 +580,19 @@ void dcn30_init_hw(struct dc *dc)
         */
        if (dc->config.power_down_display_on_boot) {
                struct dc_link *edp_links[MAX_NUM_EDP];
-               struct dc_link *edp_link;
+               struct dc_link *edp_link = NULL;
 
                get_edp_links(dc, edp_links, &edp_num);
-               if (edp_num) {
-                       for (i = 0; i < edp_num; i++) {
-                               edp_link = edp_links[i];
-                               if (edp_link->link_enc->funcs->is_dig_enabled &&
-                                               edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
-                                               dc->hwss.edp_backlight_control &&
-                                               dc->hwss.power_down &&
-                                               dc->hwss.edp_power_control) {
-                                       dc->hwss.edp_backlight_control(edp_link, false);
-                                       dc->hwss.power_down(dc);
-                                       dc->hwss.edp_power_control(edp_link, false);
-                               }
-                       }
+               if (edp_num)
+                       edp_link = edp_links[0];
+               if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
+                               edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
+                               dc->hwss.edp_backlight_control &&
+                               dc->hwss.power_down &&
+                               dc->hwss.edp_power_control) {
+                       dc->hwss.edp_backlight_control(edp_link, false);
+                       dc->hwss.power_down(dc);
+                       dc->hwss.edp_power_control(edp_link, false);
                } else {
                        for (i = 0; i < dc->link_count; i++) {
                                struct dc_link *link = dc->links[i];
index 6ac6faf..83f7904 100644 (file)
@@ -226,6 +226,7 @@ void dcn31_init_hw(struct dc *dc)
        if (dc->config.power_down_display_on_boot) {
                struct dc_link *edp_links[MAX_NUM_EDP];
                struct dc_link *edp_link;
+               bool power_down = false;
 
                get_edp_links(dc, edp_links, &edp_num);
                if (edp_num) {
@@ -239,9 +240,11 @@ void dcn31_init_hw(struct dc *dc)
                                        dc->hwss.edp_backlight_control(edp_link, false);
                                        dc->hwss.power_down(dc);
                                        dc->hwss.edp_power_control(edp_link, false);
+                                       power_down = true;
                                }
                        }
-               } else {
+               }
+               if (!power_down) {
                        for (i = 0; i < dc->link_count; i++) {
                                struct dc_link *link = dc->links[i];