--
-- Copyright (C) 2015-2017 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.GFX.GMA.Connectors.DDI.Buffers;

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);

   DISPIO_CR_TX_BLNC_LEG_DISBL_MASK    : constant := 16#1f# * 2 ** 23;
   DISPIO_CR_TX_BLNC_LEG_SCTL_4_SHIFT  : constant :=               20;
   DISPIO_CR_TX_BLNC_LEG_SCTL_4_MASK   : constant := 16#07# * 2 ** 20;
   DISPIO_CR_TX_BLNC_LEG_SCTL_3_SHIFT  : constant :=               17;
   DISPIO_CR_TX_BLNC_LEG_SCTL_3_MASK   : constant := 16#07# * 2 ** 17;
   DISPIO_CR_TX_BLNC_LEG_SCTL_2_SHIFT  : constant :=               14;
   DISPIO_CR_TX_BLNC_LEG_SCTL_2_MASK   : constant := 16#07# * 2 ** 14;
   DISPIO_CR_TX_BLNC_LEG_SCTL_1_SHIFT  : constant :=               11;
   DISPIO_CR_TX_BLNC_LEG_SCTL_1_MASK   : constant := 16#07# * 2 ** 11;
   DISPIO_CR_TX_BLNC_LEG_SCTL_0_SHIFT  : constant :=                8;
   DISPIO_CR_TX_BLNC_LEG_SCTL_0_MASK   : constant := 16#07# * 2 **  8;

   type DDI_Buf_Trans_Regs_Array
      is array (Buf_Trans_Range) of Registers.Registers_Index;

   type DDI_Registers is record
      BUF_CTL        : Registers.Registers_Index;
      BUF_TRANS      : DDI_Buf_Trans_Regs_Array;
      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,
         BUF_TRANS      => DDI_Buf_Trans_Regs_Array'
                          (Registers.DDI_BUF_TRANS_A_S0T1,
                           Registers.DDI_BUF_TRANS_A_S0T2,
                           Registers.DDI_BUF_TRANS_A_S1T1,
                           Registers.DDI_BUF_TRANS_A_S1T2,
                           Registers.DDI_BUF_TRANS_A_S2T1,
                           Registers.DDI_BUF_TRANS_A_S2T2,
                           Registers.DDI_BUF_TRANS_A_S3T1,
                           Registers.DDI_BUF_TRANS_A_S3T2,
                           Registers.DDI_BUF_TRANS_A_S4T1,
                           Registers.DDI_BUF_TRANS_A_S4T2,
                           Registers.DDI_BUF_TRANS_A_S5T1,
                           Registers.DDI_BUF_TRANS_A_S5T2,
                           Registers.DDI_BUF_TRANS_A_S6T1,
                           Registers.DDI_BUF_TRANS_A_S6T2,
                           Registers.DDI_BUF_TRANS_A_S7T1,
                           Registers.DDI_BUF_TRANS_A_S7T2,
                           Registers.DDI_BUF_TRANS_A_S8T1,
                           Registers.DDI_BUF_TRANS_A_S8T2,
                           Registers.DDI_BUF_TRANS_A_S9T1,
                           Registers.DDI_BUF_TRANS_A_S9T2),
         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,
         BUF_TRANS      => DDI_Buf_Trans_Regs_Array'
                          (Registers.DDI_BUF_TRANS_B_S0T1,
                           Registers.DDI_BUF_TRANS_B_S0T2,
                           Registers.DDI_BUF_TRANS_B_S1T1,
                           Registers.DDI_BUF_TRANS_B_S1T2,
                           Registers.DDI_BUF_TRANS_B_S2T1,
                           Registers.DDI_BUF_TRANS_B_S2T2,
                           Registers.DDI_BUF_TRANS_B_S3T1,
                           Registers.DDI_BUF_TRANS_B_S3T2,
                           Registers.DDI_BUF_TRANS_B_S4T1,
                           Registers.DDI_BUF_TRANS_B_S4T2,
                           Registers.DDI_BUF_TRANS_B_S5T1,
                           Registers.DDI_BUF_TRANS_B_S5T2,
                           Registers.DDI_BUF_TRANS_B_S6T1,
                           Registers.DDI_BUF_TRANS_B_S6T2,
                           Registers.DDI_BUF_TRANS_B_S7T1,
                           Registers.DDI_BUF_TRANS_B_S7T2,
                           Registers.DDI_BUF_TRANS_B_S8T1,
                           Registers.DDI_BUF_TRANS_B_S8T2,
                           Registers.DDI_BUF_TRANS_B_S9T1,
                           Registers.DDI_BUF_TRANS_B_S9T2),
         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,
         BUF_TRANS      => DDI_Buf_Trans_Regs_Array'
                          (Registers.DDI_BUF_TRANS_C_S0T1,
                           Registers.DDI_BUF_TRANS_C_S0T2,
                           Registers.DDI_BUF_TRANS_C_S1T1,
                           Registers.DDI_BUF_TRANS_C_S1T2,
                           Registers.DDI_BUF_TRANS_C_S2T1,
                           Registers.DDI_BUF_TRANS_C_S2T2,
                           Registers.DDI_BUF_TRANS_C_S3T1,
                           Registers.DDI_BUF_TRANS_C_S3T2,
                           Registers.DDI_BUF_TRANS_C_S4T1,
                           Registers.DDI_BUF_TRANS_C_S4T2,
                           Registers.DDI_BUF_TRANS_C_S5T1,
                           Registers.DDI_BUF_TRANS_C_S5T2,
                           Registers.DDI_BUF_TRANS_C_S6T1,
                           Registers.DDI_BUF_TRANS_C_S6T2,
                           Registers.DDI_BUF_TRANS_C_S7T1,
                           Registers.DDI_BUF_TRANS_C_S7T2,
                           Registers.DDI_BUF_TRANS_C_S8T1,
                           Registers.DDI_BUF_TRANS_C_S8T2,
                           Registers.DDI_BUF_TRANS_C_S9T1,
                           Registers.DDI_BUF_TRANS_C_S9T2),
         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,
         BUF_TRANS      => DDI_Buf_Trans_Regs_Array'
                          (Registers.DDI_BUF_TRANS_D_S0T1,
                           Registers.DDI_BUF_TRANS_D_S0T2,
                           Registers.DDI_BUF_TRANS_D_S1T1,
                           Registers.DDI_BUF_TRANS_D_S1T2,
                           Registers.DDI_BUF_TRANS_D_S2T1,
                           Registers.DDI_BUF_TRANS_D_S2T2,
                           Registers.DDI_BUF_TRANS_D_S3T1,
                           Registers.DDI_BUF_TRANS_D_S3T2,
                           Registers.DDI_BUF_TRANS_D_S4T1,
                           Registers.DDI_BUF_TRANS_D_S4T2,
                           Registers.DDI_BUF_TRANS_D_S5T1,
                           Registers.DDI_BUF_TRANS_D_S5T2,
                           Registers.DDI_BUF_TRANS_D_S6T1,
                           Registers.DDI_BUF_TRANS_D_S6T2,
                           Registers.DDI_BUF_TRANS_D_S7T1,
                           Registers.DDI_BUF_TRANS_D_S7T2,
                           Registers.DDI_BUF_TRANS_D_S8T1,
                           Registers.DDI_BUF_TRANS_D_S8T2,
                           Registers.DDI_BUF_TRANS_D_S9T1,
                           Registers.DDI_BUF_TRANS_D_S9T2),
         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,
         BUF_TRANS      => DDI_Buf_Trans_Regs_Array'
                          (Registers.DDI_BUF_TRANS_E_S0T1,
                           Registers.DDI_BUF_TRANS_E_S0T2,
                           Registers.DDI_BUF_TRANS_E_S1T1,
                           Registers.DDI_BUF_TRANS_E_S1T2,
                           Registers.DDI_BUF_TRANS_E_S2T1,
                           Registers.DDI_BUF_TRANS_E_S2T2,
                           Registers.DDI_BUF_TRANS_E_S3T1,
                           Registers.DDI_BUF_TRANS_E_S3T2,
                           Registers.DDI_BUF_TRANS_E_S4T1,
                           Registers.DDI_BUF_TRANS_E_S4T2,
                           Registers.DDI_BUF_TRANS_E_S5T1,
                           Registers.DDI_BUF_TRANS_E_S5T2,
                           Registers.DDI_BUF_TRANS_E_S6T1,
                           Registers.DDI_BUF_TRANS_E_S6T2,
                           Registers.DDI_BUF_TRANS_E_S7T1,
                           Registers.DDI_BUF_TRANS_E_S7T2,
                           Registers.DDI_BUF_TRANS_E_S8T1,
                           Registers.DDI_BUF_TRANS_E_S8T2,
                           Registers.DDI_BUF_TRANS_E_S9T1,
                           Registers.DDI_BUF_TRANS_E_S9T2),
         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;

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

   procedure Program_Buffer_Translations (Port : Digital_Port)
   is
      Buffer_Translations : Buf_Trans_Array;
   begin
      Buffers.Translations (Buffer_Translations, Port);
      for I in Buf_Trans_Range loop
         Registers.Write
           (Register => DDI_Regs (Port).BUF_TRANS (I),
            Value    => Buffer_Translations (I));
      end loop;
   end Program_Buffer_Translations;

   procedure Initialize
   is
      Iboost_Value : constant Word32 := 1;
   begin
      if Config.Has_DDI_Buffer_Trans then
         for Port in Digital_Port range DIGI_A .. Config.Last_Digital_Port loop
            Program_Buffer_Translations (Port);
         end loop;
         if Config.Is_FDI_Port (Analog) then
            Program_Buffer_Translations (DIGI_E);
         end if;
      end if;

      if Config.Has_Iboost_Config then
         Registers.Unset_And_Set_Mask
           (Register    => Registers.DISPIO_CR_TX_BMU_CR0,
            Mask_Unset  => DISPIO_CR_TX_BLNC_LEG_DISBL_MASK or
                           DISPIO_CR_TX_BLNC_LEG_SCTL_4_MASK or
                           DISPIO_CR_TX_BLNC_LEG_SCTL_3_MASK or
                           DISPIO_CR_TX_BLNC_LEG_SCTL_2_MASK or
                           DISPIO_CR_TX_BLNC_LEG_SCTL_1_MASK or
                           DISPIO_CR_TX_BLNC_LEG_SCTL_0_MASK,
            Mask_Set    =>
               Shift_Left (Iboost_Value, DISPIO_CR_TX_BLNC_LEG_SCTL_4_SHIFT) or
               Shift_Left (Iboost_Value, DISPIO_CR_TX_BLNC_LEG_SCTL_3_SHIFT) or
               Shift_Left (Iboost_Value, DISPIO_CR_TX_BLNC_LEG_SCTL_2_SHIFT) or
               Shift_Left (Iboost_Value, DISPIO_CR_TX_BLNC_LEG_SCTL_1_SHIFT) or
               Shift_Left (Iboost_Value, DISPIO_CR_TX_BLNC_LEG_SCTL_0_SHIFT));
      end if;
   end Initialize;

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

   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
            declare
               HDMI_Level : constant DDI_Phy.HDMI_Buf_Trans_Range :=
                 (if Config.DDI_HDMI_Buffer_Translation
                     in DDI_Phy.HDMI_Buf_Trans_Range
                  then Config.DDI_HDMI_Buffer_Translation
                  else Config.Default_DDI_HDMI_Buffer_Translation);
            begin
               DDI_Phy.Set_HDMI_Signal_Levels (Port_Cfg.Port, HDMI_Level);
               Success := True;
            end;
         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 Config.Has_PCH_DAC and then 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;
         if Config.Has_PCH_DAC then
            PCH.FDI.Off (PCH.FDI_A, PCH.FDI.Clock_Off);
         end if;
      end if;
   end Off;

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

   procedure Post_Reset_Off
   is
      Clocks_Off : Word32 := 0;
   begin
      if not Config.Has_Per_DDI_Clock_Sel and not Config.Has_DDI_PHYs then
         for Port in Digital_Port loop
            Clocks_Off := Clocks_Off or DPLL_CTRL2_DDIx_CLOCK_OFF (Port);
         end loop;
         Registers.Set_Mask (Registers.DPLL_CTRL2, Clocks_Off);
      end if;
   end Post_Reset_Off;

end HW.GFX.GMA.Connectors.DDI;
