gma: Get DPCD 1.1+ displays out of D3

DPCD 1.1 added a field to switch the DP sink into D3 and back. Linux
(and potentially other OS') apparently makes use of it when shutting
down, also for a reboot.  This can lead to display failures in core-
boot on a reboot. So we signal any DPCD 1.1+ display unconditionally
to go into D0 before DP training.

Change-Id: Ieec3813ba99ed3a2c6f701cb34a5e2b226fc14c0
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/c/libgfxinit/+/83596
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: Nico Huber <nico.h@gmx.de>
diff --git a/common/hw-gfx-gma-connector_info.adb b/common/hw-gfx-gma-connector_info.adb
index 47292f6..7122eac 100644
--- a/common/hw-gfx-gma-connector_info.adb
+++ b/common/hw-gfx-gma-connector_info.adb
@@ -12,10 +12,13 @@
 -- GNU General Public License for more details.
 --
 
+with HW.GFX.DP_Defs;
+
 with HW.GFX.GMA.Config;
 with HW.GFX.GMA.Panel;
 with HW.GFX.GMA.DP_Dual_Mode;
 with HW.GFX.GMA.DP_Info;
+with HW.GFX.GMA.DP_Aux_Ch;
 
 with HW.Debug;
 with GNAT.Source_Info;
@@ -26,6 +29,8 @@
      (Port_Cfg    : in out Port_Config;
       Success     :    out Boolean)
    is
+      use type Word8;
+
       DP_Port : constant GMA.DP_Port :=
         (if Config.Has_Type_C_Ports
          then
@@ -76,6 +81,23 @@
                Success  => Success);
             pragma Debug (Success, DP_Info.Dump_Link_Setting (Port_Cfg.DP));
          end if;
+
+         -- Get DP sinks out of power-save mode
+         if Success and Port_Cfg.DP.Receiver_Caps.Rev >= 16#11# then
+            declare
+               DPCD_SINK_CONTROL    : constant := 16#00600#;
+               DPCD_SINK_CONTROL_D0 : constant DP_Defs.Aux_Payload :=
+                 (1 * 2 ** 0, others => 0);
+               Ignored : Boolean;
+            begin
+               DP_Aux_Ch.Aux_Write
+                 (Port     => DP_Port,
+                  Address  => DPCD_SINK_CONTROL,
+                  Length   => 1,
+                  Data     => DPCD_SINK_CONTROL_D0,
+                  Success  => Ignored);
+            end;
+         end if;
       else
          Success := True;
       end if;