--
-- Copyright (C) 2015-2016 secunet Security Networks AG
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--

with HW.Time;
with HW.GFX.DP_Training;
with HW.GFX.GMA.Config;
with HW.GFX.GMA.PCH.FDI;
with HW.GFX.GMA.PCH.Transcoder;
with HW.GFX.GMA.PCH.VGA;
with HW.GFX.GMA.DP_Info;
with HW.GFX.GMA.DP_Aux_Ch;
with HW.GFX.GMA.SPLL;
with HW.GFX.GMA.DDI_Phy;

with HW.Debug;
with GNAT.Source_Info;

package body HW.GFX.GMA.Connectors.DDI is

   DDI_BUF_CTL_BUFFER_ENABLE        : constant :=  1 * 2 ** 31;
   DDI_BUF_CTL_TRANS_SELECT_MASK    : constant := 15 * 2 ** 24;
   DDI_BUF_CTL_PORT_REVERSAL        : constant :=  1 * 2 ** 16;
   DDI_BUF_CTL_IDLE_STATUS          : constant :=  1 * 2 **  7;
   DDI_BUF_CTL_DDI_A_LANE_CAP       : constant :=  1 * 2 **  4;
   DDI_BUF_CTL_PORT_WIDTH_MASK      : constant :=  7 * 2 **  1;
   DDI_BUF_CTL_PORT_WIDTH_1_LANE    : constant :=  0 * 2 **  1;
   DDI_BUF_CTL_PORT_WIDTH_2_LANES   : constant :=  1 * 2 **  1;
   DDI_BUF_CTL_PORT_WIDTH_4_LANES   : constant :=  3 * 2 **  1;
   DDI_BUF_CTL_INIT_DISPLAY_DETECT  : constant :=  1 * 2 **  0;

   subtype DDI_BUF_CTL_TRANS_SELECT_T is Natural range 0 .. 9;
   function DDI_BUF_CTL_TRANS_SELECT
     (Sel : DDI_BUF_CTL_TRANS_SELECT_T)
      return Word32;

   type DDI_BUF_CTL_PORT_WIDTH_T is array (HW.GFX.DP_Lane_Count) of Word32;
   DDI_BUF_CTL_PORT_WIDTH : constant DDI_BUF_CTL_PORT_WIDTH_T :=
      DDI_BUF_CTL_PORT_WIDTH_T'
     (HW.GFX.DP_Lane_Count_1 => DDI_BUF_CTL_PORT_WIDTH_1_LANE,
      HW.GFX.DP_Lane_Count_2 => DDI_BUF_CTL_PORT_WIDTH_2_LANES,
      HW.GFX.DP_Lane_Count_4 => DDI_BUF_CTL_PORT_WIDTH_4_LANES);

   DP_TP_CTL_TRANSPORT_ENABLE       : constant := 1 * 2 ** 31;
   DP_TP_CTL_MODE_SST               : constant := 0 * 2 ** 27;
   DP_TP_CTL_MODE_MST               : constant := 1 * 2 ** 27;
   DP_TP_CTL_FORCE_ACT              : constant := 1 * 2 ** 25;
   DP_TP_CTL_ENHANCED_FRAME_ENABLE  : constant := 1 * 2 ** 18;
   DP_TP_CTL_FDI_AUTOTRAIN          : constant := 1 * 2 ** 15;
   DP_TP_CTL_LINK_TRAIN_MASK        : constant := 7 * 2 **  8;
   DP_TP_CTL_LINK_TRAIN_PAT1        : constant := 0 * 2 **  8;
   DP_TP_CTL_LINK_TRAIN_PAT2        : constant := 1 * 2 **  8;
   DP_TP_CTL_LINK_TRAIN_PAT3        : constant := 4 * 2 **  8;
   DP_TP_CTL_LINK_TRAIN_IDLE        : constant := 2 * 2 **  8;
   DP_TP_CTL_LINK_TRAIN_NORMAL      : constant := 3 * 2 **  8;
   DP_TP_CTL_SCRAMBLE_DISABLE       : constant := 1 * 2 **  7;
   DP_TP_CTL_ALT_SCRAMBLER_RESET    : constant := 1 * 2 **  6;

   type DP_TP_CTL_LINK_TRAIN_Array is
      array (DP_Info.Training_Pattern) of Word32;
   DP_TP_CTL_LINK_TRAIN : constant DP_TP_CTL_LINK_TRAIN_Array :=
      DP_TP_CTL_LINK_TRAIN_Array'
     (DP_Info.TP_1      => DP_TP_CTL_LINK_TRAIN_PAT1 or DP_TP_CTL_SCRAMBLE_DISABLE,
      DP_Info.TP_2      => DP_TP_CTL_LINK_TRAIN_PAT2 or DP_TP_CTL_SCRAMBLE_DISABLE,
      DP_Info.TP_3      => DP_TP_CTL_LINK_TRAIN_PAT3 or DP_TP_CTL_SCRAMBLE_DISABLE,
      DP_Info.TP_Idle   => DP_TP_CTL_LINK_TRAIN_IDLE,
      DP_Info.TP_None   => DP_TP_CTL_LINK_TRAIN_NORMAL);

   DP_TP_STATUS_MIN_IDLES_SENT      : constant := 1 * 2 ** 25;
   DP_TP_STATUS_FDI_AUTO_TRAIN_DONE : constant := 1 * 2 ** 12;

   PORT_CLK_SEL_LCPLL2700  : constant := 0 * 2 ** 29; -- not on ULX
   PORT_CLK_SEL_LCPLL1350  : constant := 1 * 2 ** 29;
   PORT_CLK_SEL_LCPLL810   : constant := 2 * 2 ** 29;
   PORT_CLK_SEL_SPLL       : constant := 3 * 2 ** 29;
   PORT_CLK_SEL_WRPLL1     : constant := 4 * 2 ** 29;
   PORT_CLK_SEL_WRPLL2     : constant := 5 * 2 ** 29;
   PORT_CLK_SEL_NONE       : constant := 7 * 2 ** 29;

   type PORT_CLK_SEL_LCPLL_T is array (HW.GFX.DP_Bandwidth) of Word32;
   PORT_CLK_SEL_LCPLL : constant PORT_CLK_SEL_LCPLL_T :=
      PORT_CLK_SEL_LCPLL_T'
     (HW.GFX.DP_Bandwidth_1_62 => PORT_CLK_SEL_LCPLL810,
      HW.GFX.DP_Bandwidth_2_7  => PORT_CLK_SEL_LCPLL1350,
      HW.GFX.DP_Bandwidth_5_4  => PORT_CLK_SEL_LCPLL2700);

   type DDI_Registers is record
      BUF_CTL        : Registers.Registers_Index;
      DP_TP_CTL      : Registers.Registers_Index;
      DP_TP_STATUS   : Registers.Registers_Invalid_Index;
      PORT_CLK_SEL   : Registers.Registers_Index;
   end record;

   type DDI_Registers_Array is array (Digital_Port) of DDI_Registers;

   DDI_Regs : constant DDI_Registers_Array := DDI_Registers_Array'
     (DIGI_A => DDI_Registers'
        (BUF_CTL        => Registers.DDI_BUF_CTL_A,
         DP_TP_CTL      => Registers.DP_TP_CTL_A,
         DP_TP_STATUS   => Registers.Invalid_Register,
         PORT_CLK_SEL   => Registers.PORT_CLK_SEL_DDIA),
      DIGI_B => DDI_Registers'
        (BUF_CTL        => Registers.DDI_BUF_CTL_B,
         DP_TP_CTL      => Registers.DP_TP_CTL_B,
         DP_TP_STATUS   => Registers.DP_TP_STATUS_B,
         PORT_CLK_SEL   => Registers.PORT_CLK_SEL_DDIB),
      DIGI_C => DDI_Registers'
        (BUF_CTL        => Registers.DDI_BUF_CTL_C,
         DP_TP_CTL      => Registers.DP_TP_CTL_C,
         DP_TP_STATUS   => Registers.DP_TP_STATUS_C,
         PORT_CLK_SEL   => Registers.PORT_CLK_SEL_DDIC),
      DIGI_D => DDI_Registers'
        (BUF_CTL        => Registers.DDI_BUF_CTL_D,
         DP_TP_CTL      => Registers.DP_TP_CTL_D,
         DP_TP_STATUS   => Registers.DP_TP_STATUS_D,
         PORT_CLK_SEL   => Registers.PORT_CLK_SEL_DDID),
      DIGI_E => DDI_Registers'
        (BUF_CTL        => Registers.DDI_BUF_CTL_E,
         DP_TP_CTL      => Registers.DP_TP_CTL_E,
         DP_TP_STATUS   => Registers.DP_TP_STATUS_E,
         PORT_CLK_SEL   => Registers.PORT_CLK_SEL_DDIE));

   ----------------------------------------------------------------------------

   type Values is array (Digital_Port) of Word32;
   type Shifts is array (Digital_Port) of Natural;

   DPLL_CTRL2_DDIx_CLOCK_OFF : constant Values := Values'
     (DIGI_A   => 1 * 2 ** 15,
      DIGI_B   => 1 * 2 ** 16,
      DIGI_C   => 1 * 2 ** 17,
      DIGI_D   => 1 * 2 ** 18,
      DIGI_E   => 1 * 2 ** 19);

   DPLL_CTRL2_DDIx_SELECT_MASK : constant Values := Values'
     (DIGI_A   => 3 * 2 **  1,
      DIGI_B   => 3 * 2 **  4,
      DIGI_C   => 3 * 2 **  7,
      DIGI_D   => 3 * 2 ** 10,
      DIGI_E   => 3 * 2 ** 13);
   DPLL_CTRL2_DDIx_SELECT_SHIFT : constant Shifts := Shifts'
     (DIGI_A   =>  1,
      DIGI_B   =>  4,
      DIGI_C   =>  7,
      DIGI_D   => 10,
      DIGI_E   => 13);

   DPLL_CTRL2_DDIx_SELECT_OVERRIDE : constant Values := Values'
     (DIGI_A   => 1 * 2 **  0,
      DIGI_B   => 1 * 2 **  3,
      DIGI_C   => 1 * 2 **  6,
      DIGI_D   => 1 * 2 **  9,
      DIGI_E   => 1 * 2 ** 12);

   ----------------------------------------------------------------------------

   function DDI_BUF_CTL_TRANS_SELECT
     (Sel : DDI_BUF_CTL_TRANS_SELECT_T)
      return Word32
   is
   begin
      return Word32 (Sel) * 2 ** 24;
   end DDI_BUF_CTL_TRANS_SELECT;

   ----------------------------------------------------------------------------

   function Max_V_Swing
     (Port : Digital_Port)
      return DP_Info.DP_Voltage_Swing
   is
   begin
      return
        (if Config.Has_DDI_PHYs then
            DDI_Phy.Max_V_Swing
         elsif (Config.Has_Low_Voltage_Swing and Config.EDP_Low_Voltage_Swing)
            and then Port = DIGI_A
         then
            DP_Info.VS_Level_3
         else
            DP_Info.VS_Level_2);
   end Max_V_Swing;

   pragma Warnings (GNATprove, Off, "unused variable ""Port""",
                    Reason => "Needed for a common interface");
   function Max_Pre_Emph
     (Port        : Digital_Port;
      Train_Set   : DP_Info.Train_Set)
      return DP_Info.DP_Pre_Emph
   is
   begin
      return
        (if Config.Has_DDI_PHYs then
            DDI_Phy.Max_Pre_Emph (Train_Set.Voltage_Swing)
         else
           (case Train_Set.Voltage_Swing is
               when DP_Info.VS_Level_0 => DP_Info.Emph_Level_3,
               when DP_Info.VS_Level_1 => DP_Info.Emph_Level_2,
               when DP_Info.VS_Level_2 => DP_Info.Emph_Level_1,
               when others             => DP_Info.Emph_Level_0));
   end Max_Pre_Emph;
   pragma Warnings (GNATprove, On, "unused variable ""Port""");

   ----------------------------------------------------------------------------

   procedure Set_TP_CTL
     (Port     : Digital_Port;
      Link     : DP_Link;
      Pattern  : DP_Info.Training_Pattern)
   is
      DP_TP_CTL_Enhanced_Frame : Word32 := 0;
   begin
      if Link.Enhanced_Framing then
         DP_TP_CTL_Enhanced_Frame := DP_TP_CTL_ENHANCED_FRAME_ENABLE;
      end if;

      Registers.Write
        (Register => DDI_Regs (Port).DP_TP_CTL,
         Value    => DP_TP_CTL_TRANSPORT_ENABLE or
                     DP_TP_CTL_Enhanced_Frame or
                     DP_TP_CTL_LINK_TRAIN (Pattern));
   end Set_TP_CTL;

   procedure Set_Training_Pattern
     (Port     : Digital_Port;
      Link     : DP_Link;
      Pattern  : DP_Info.Training_Pattern)
   is
      use type DP_Info.Training_Pattern;
   begin
      if Pattern < DP_Info.TP_Idle then
         Set_TP_CTL (Port, Link, Pattern);
      else
         -- send at least 5 idle patterns
         Set_TP_CTL (Port, Link, DP_Info.TP_Idle);

         -- switch to normal frame delivery
         if Config.End_EDP_Training_Late and then Port = DIGI_A then
            null; -- do it later in Post_On procedure
            -- TODO: if there are problems getting the pipe up,
            --       wait here some time
            -- Time.U_Delay (100);
         else
            if Port /= DIGI_A then
               Registers.Wait_Set_Mask
                 (Register    => DDI_Regs (Port).DP_TP_STATUS,
                  Mask        => DP_TP_STATUS_MIN_IDLES_SENT);
            end if;
            Set_TP_CTL (Port, Link, DP_Info.TP_None);
         end if;
      end if;
   end Set_Training_Pattern;

   procedure Set_Signal_Levels
     (Port        : Digital_Port;
      Link        : DP_Link;
      Train_Set   : DP_Info.Train_Set)
   is
      Was_Enabled : Boolean;
      Trans_Select : DDI_BUF_CTL_TRANS_SELECT_T;
   begin
      Registers.Is_Set_Mask
        (Register => DDI_Regs (Port).BUF_CTL,
         Mask     => DDI_BUF_CTL_BUFFER_ENABLE,
         Result   => Was_Enabled);

      if Config.Has_DDI_PHYs then
         Trans_Select := 0;
      else
         case Train_Set.Voltage_Swing is
            when DP_Info.VS_Level_0 =>
               case Train_Set.Pre_Emph is
                  when DP_Info.Emph_Level_0  => Trans_Select := 0;
                  when DP_Info.Emph_Level_1  => Trans_Select := 1;
                  when DP_Info.Emph_Level_2  => Trans_Select := 2;
                  when DP_Info.Emph_Level_3  => Trans_Select := 3;
               end case;
            when DP_Info.VS_Level_1 =>
               case Train_Set.Pre_Emph is
                  when DP_Info.Emph_Level_0  => Trans_Select := 4;
                  when DP_Info.Emph_Level_1  => Trans_Select := 5;
                  when DP_Info.Emph_Level_2  => Trans_Select := 6;
                  when others                => Trans_Select := 0;
               end case;
            when DP_Info.VS_Level_2 =>
               case Train_Set.Pre_Emph is
                  when DP_Info.Emph_Level_0  => Trans_Select := 7;
                  when DP_Info.Emph_Level_1  => Trans_Select := 8;
                  when others                => Trans_Select := 0;
               end case;
            when DP_Info.VS_Level_3 =>
               case Train_Set.Pre_Emph is
                  when DP_Info.Emph_Level_0  => Trans_Select := 9;
                  when others                => Trans_Select := 0;
               end case;
         end case;
      end if;

      -- enable DDI buffer
      Registers.Unset_And_Set_Mask
        (Register    => DDI_Regs (Port).BUF_CTL,
         Mask_Unset  => DDI_BUF_CTL_TRANS_SELECT_MASK or
                        DDI_BUF_CTL_PORT_REVERSAL or
                        DDI_BUF_CTL_PORT_WIDTH_MASK,
         Mask_Set    => DDI_BUF_CTL_BUFFER_ENABLE or
                        DDI_BUF_CTL_TRANS_SELECT (Trans_Select) or
                        DDI_BUF_CTL_PORT_WIDTH (Link.Lane_Count));
      Registers.Posting_Read (DDI_Regs (Port).BUF_CTL);

      if not Was_Enabled then
         Time.U_Delay (600);  -- wait >= 518us (intel spec)
      end if;

      if Config.Has_DDI_PHYs then
         DDI_Phy.Set_DP_Signal_Levels (Port, Train_Set);
      end if;
   end Set_Signal_Levels;

   ----------------------------------------------------------------------------

   procedure Digital_Off (Port : Digital_Port)
   is
      Enabled : Boolean;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Registers.Is_Set_Mask
        (Register => DDI_Regs (Port).BUF_CTL,
         Mask     => DDI_BUF_CTL_BUFFER_ENABLE,
         Result   => Enabled);

      if Enabled then
         Registers.Unset_Mask
           (Register => DDI_Regs (Port).BUF_CTL,
            Mask     => DDI_BUF_CTL_BUFFER_ENABLE);
      end if;

      Registers.Unset_Mask
        (Register => DDI_Regs (Port).DP_TP_CTL,
         Mask     => DP_TP_CTL_TRANSPORT_ENABLE);

      if Enabled then
         Registers.Wait_Set_Mask
           (Register => DDI_Regs (Port).BUF_CTL,
            Mask     => DDI_BUF_CTL_IDLE_STATUS);
      end if;

      if Config.Has_Per_DDI_Clock_Sel then
         Registers.Write
           (Register => DDI_Regs (Port).PORT_CLK_SEL,
            Value    => PORT_CLK_SEL_NONE);
      elsif not Config.Has_DDI_PHYs then
         Registers.Set_Mask
           (Register => Registers.DPLL_CTRL2,
            Mask     => DPLL_CTRL2_DDIx_CLOCK_OFF (Port));
      end if;
   end Digital_Off;

   ----------------------------------------------------------------------------

   procedure Train_FDI
     (Port_Cfg : in     Port_Config;
      Success  :    out Boolean)
   is
   begin
      PCH.FDI.Pre_Train (PCH.FDI_A, Port_Cfg);

      -- always use SPLL for FDI
      SPLL.On;
      Registers.Write
        (Register => DDI_Regs (DIGI_E).PORT_CLK_SEL,
         Value    => PORT_CLK_SEL_SPLL);

      -- try each preemph/voltage pair twice
      for Trans2 in Natural range 0 .. DDI_BUF_CTL_TRANS_SELECT_T'Last * 2 + 1
      loop
         Registers.Write
           (Register => DDI_Regs (DIGI_E).DP_TP_CTL,
            Value    => DP_TP_CTL_TRANSPORT_ENABLE or
                        DP_TP_CTL_ENHANCED_FRAME_ENABLE or
                        DP_TP_CTL_FDI_AUTOTRAIN or
                        DP_TP_CTL_LINK_TRAIN_PAT1);

         Registers.Unset_And_Set_Mask
           (Register    => DDI_Regs (DIGI_E).BUF_CTL,
            Mask_Unset  => DDI_BUF_CTL_TRANS_SELECT_MASK or
                           DDI_BUF_CTL_PORT_REVERSAL or
                           DDI_BUF_CTL_PORT_WIDTH_MASK,
            Mask_Set    => DDI_BUF_CTL_BUFFER_ENABLE or
                           DDI_BUF_CTL_TRANS_SELECT (Trans2 / 2) or
                           DDI_BUF_CTL_PORT_WIDTH (Port_Cfg.FDI.Lane_Count));
         Registers.Posting_Read (DDI_Regs (DIGI_E).BUF_CTL);
         Time.U_Delay (600);  -- wait >= 518us (intel spec)

         PCH.FDI.Auto_Train (PCH.FDI_A);
         Registers.Is_Set_Mask
           (Register => DDI_Regs (DIGI_E).DP_TP_STATUS,
            Mask     => DP_TP_STATUS_FDI_AUTO_TRAIN_DONE,
            Result   => Success);
         exit when Success;

         Registers.Unset_Mask
           (Register => DDI_Regs (DIGI_E).BUF_CTL,
            Mask     => DDI_BUF_CTL_BUFFER_ENABLE);
         Registers.Posting_Read (DDI_Regs (DIGI_E).BUF_CTL);

         Registers.Unset_And_Set_Mask
           (Register    => DDI_Regs (DIGI_E).DP_TP_CTL,
            Mask_Unset  => DP_TP_CTL_TRANSPORT_ENABLE or
                           DP_TP_CTL_LINK_TRAIN_MASK,
            Mask_Set    => DP_TP_CTL_LINK_TRAIN_PAT1);
         Registers.Posting_Read (DDI_Regs (DIGI_E).DP_TP_CTL);

         Registers.Wait_Set_Mask
           (Register => DDI_Regs (DIGI_E).BUF_CTL,
            Mask     => DDI_BUF_CTL_IDLE_STATUS);

         PCH.FDI.Off (PCH.FDI_A, PCH.FDI.Lanes_Off);
      end loop;

      if Success then
         -- start normal frame delivery
         Registers.Write
           (Register => DDI_Regs (DIGI_E).DP_TP_CTL,
            Value    => DP_TP_CTL_TRANSPORT_ENABLE or
                        DP_TP_CTL_ENHANCED_FRAME_ENABLE or
                        DP_TP_CTL_FDI_AUTOTRAIN or
                        DP_TP_CTL_LINK_TRAIN_NORMAL);
      else
         Registers.Write
           (Register => DDI_Regs (DIGI_E).PORT_CLK_SEL,
            Value    => PORT_CLK_SEL_NONE);
         SPLL.Off;

         PCH.FDI.Off (PCH.FDI_A, PCH.FDI.Clock_Off);
      end if;
   end Train_FDI;

   ----------------------------------------------------------------------------

   procedure Pre_On
     (Port_Cfg : in     Port_Config;
      PLL_Hint : in     Word32;
      Success  :    out Boolean)
   is
      function To_DP (Port : Digital_Port) return DP_Port
      is
      begin
         return
           (case Port is
               when DIGI_A => DP_A,
               when DIGI_B => DP_B,
               when DIGI_C => DP_C,
               when DIGI_D => DP_D,
               when others => DP_Port'First);
      end To_DP;
      package Training is new DP_Training
        (TPS3_Supported    => True,
         T                 => Digital_Port,
         Aux_T             => DP_Port,
         Aux_Ch            => DP_Aux_Ch,
         DP_Info           => DP_Info,
         To_Aux            => To_DP,
         Max_V_Swing       => Max_V_Swing,
         Max_Pre_Emph      => Max_Pre_Emph,
         Set_Pattern       => Set_Training_Pattern,
         Set_Signal_Levels => Set_Signal_Levels,
         Off               => Digital_Off);
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      if Port_Cfg.Display = VGA then
         Train_FDI (Port_Cfg, Success);
      else
         -- direct configured PLL output to this port
         if Config.Has_Per_DDI_Clock_Sel then
            Registers.Write
              (Register    => DDI_Regs (Port_Cfg.Port).PORT_CLK_SEL,
               Value       => PLL_Hint);
         elsif not Config.Has_DDI_PHYs then
            Registers.Unset_And_Set_Mask
              (Register    => Registers.DPLL_CTRL2,
               Mask_Unset  => DPLL_CTRL2_DDIx_CLOCK_OFF (Port_Cfg.Port) or
                              DPLL_CTRL2_DDIx_SELECT_MASK (Port_Cfg.Port),
               Mask_Set    => Shift_Left
                                (PLL_Hint,
                                 DPLL_CTRL2_DDIx_SELECT_SHIFT (Port_Cfg.Port))
                              or
                              DPLL_CTRL2_DDIx_SELECT_OVERRIDE (Port_Cfg.Port));
         end if;

         if Port_Cfg.Display = DP then
            Training.Train_DP
              (Port        => Port_Cfg.Port,
               Link        => Port_Cfg.DP,
               Success     => Success);
         elsif Config.Has_DDI_PHYs and then
            Port_Cfg.Display = HDMI and then
            Port_Cfg.Port in DDI_Phy.DDI_Phy_Port
         then
            DDI_Phy.Set_HDMI_Signal_Levels
              (Port  => Port_Cfg.Port,
               Level => DDI_Phy.HDMI_Buf_Trans_Range'Last);
            Success := True;
         else
            Success := True;
         end if;
      end if;
   end Pre_On;

   ----------------------------------------------------------------------------

   procedure Post_On (Port_Cfg : Port_Config)
   is
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      if Port_Cfg.Port = DIGI_A then
         if Config.End_EDP_Training_Late then
            Registers.Unset_And_Set_Mask
              (Register    => DDI_Regs (DIGI_A).DP_TP_CTL,
               Mask_Unset  => DP_TP_CTL_LINK_TRAIN_MASK,
               Mask_Set    => DP_TP_CTL_LINK_TRAIN_NORMAL);
         end if;
      end if;

      case Port_Cfg.Display is
         when HDMI =>
            Registers.Unset_And_Set_Mask
              (Register    => DDI_Regs (Port_Cfg.Port).BUF_CTL,
               Mask_Unset  => DDI_BUF_CTL_TRANS_SELECT_MASK or
                              DDI_BUF_CTL_PORT_REVERSAL,
               Mask_Set    => DDI_BUF_CTL_BUFFER_ENABLE);
            Time.U_Delay (600);  -- wait >= 518us (intel spec)
         when VGA =>
            PCH.VGA.Clock_On (Port_Cfg.Mode);
            PCH.Transcoder.On (Port_Cfg, PCH.FDI_A, 0);
            PCH.VGA.On
              (Port => PCH.FDI_A,
               Mode => Port_Cfg.Mode);
         when others =>
            null;
      end case;
   end Post_On;

   ----------------------------------------------------------------------------

   procedure Off (Port : Digital_Port)
   is
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      if Port = DIGI_E then
         PCH.VGA.Off;
         PCH.Transcoder.Off (PCH.FDI_A);
         -- PCH.VGA.Clock_Off; -- Can't tell what Linux does, if anything.
         PCH.FDI.Off (PCH.FDI_A, PCH.FDI.Rx_Off);
      end if;

      Digital_Off (Port);

      if Port = DIGI_E then
         SPLL.Off;
         PCH.FDI.Off (PCH.FDI_A, PCH.FDI.Clock_Off);
      end if;
   end Off;

end HW.GFX.GMA.Connectors.DDI;
