--
-- Copyright (C) 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.GMA.Config;
with HW.GFX.GMA.PCH.FDI;
with HW.GFX.GMA.Registers;

with HW.Debug;
with GNAT.Source_Info;

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

   use all type PCH.FDI.Training_Pattern;

   PCH_FDI_CHICKEN_B_AND_C             : constant :=      1 * 2 ** 12;

   type TX_CTL_Regs is array (GPU_FDI_Port) of Registers.Registers_Index;
   TX_CTL : constant TX_CTL_Regs :=
     (DIGI_B => Registers.FDI_TX_CTL_A,
      DIGI_C => Registers.FDI_TX_CTL_B,
      DIGI_D => Registers.FDI_TX_CTL_C);

   FDI_TX_CTL_FDI_TX_ENABLE            : constant :=      1 * 2 ** 31;
   FDI_TX_CTL_VP_MASK                  : constant := 16#3f# * 2 ** 22;
   FDI_TX_CTL_PORT_WIDTH_SEL_SHIFT     : constant :=               19;
   FDI_TX_CTL_ENHANCED_FRAMING_ENABLE  : constant :=      1 * 2 ** 18;
   FDI_TX_CTL_FDI_PLL_ENABLE           : constant :=      1 * 2 ** 14;
   FDI_TX_CTL_COMPOSITE_SYNC_SELECT    : constant :=      1 * 2 ** 11;
   FDI_TX_CTL_AUTO_TRAIN_ENABLE        : constant :=      1 * 2 ** 10;
   FDI_TX_CTL_AUTO_TRAIN_DONE          : constant :=      1 * 2 **  1;

   function TP_SHIFT return Natural is
     (if Config.Has_New_FDI_Source then 8 else 28);

   function FDI_TX_CTL_TRAINING_PATTERN_MASK
      return Word32 is (Shift_Left (3, TP_SHIFT));

   function FDI_TX_CTL_TRAINING_PATTERN (TP : PCH.FDI.Training_Pattern)
      return Word32 is
     (case TP is
         when TP_1      => Shift_Left (0, TP_SHIFT),
         when TP_2      => Shift_Left (1, TP_SHIFT),
         when TP_Idle   => Shift_Left (2, TP_SHIFT),
         when TP_None   => Shift_Left (3, TP_SHIFT));

   subtype FDI_TX_CTL_VP_T is Natural range 0 .. 3;
   type Vswing_Preemph_Values is array (FDI_TX_CTL_VP_T) of Word32;
   FDI_TX_CTL_VSWING_PREEMPH : constant Vswing_Preemph_Values :=
     (0 => 16#00# * 2 ** 22,
      1 => 16#3a# * 2 ** 22,
      2 => 16#39# * 2 ** 22,
      3 => 16#38# * 2 ** 22);

   function FDI_TX_CTL_PORT_WIDTH_SEL (Lane_Count : DP_Lane_Count) return Word32
   is
   begin
      return Shift_Left
        (Word32 (Lane_Count_As_Integer (Lane_Count)) - 1,
         FDI_TX_CTL_PORT_WIDTH_SEL_SHIFT);
   end FDI_TX_CTL_PORT_WIDTH_SEL;

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

   --
   -- This is usually used with Ivy Bridge.
   --
   procedure Auto_Training
     (Port_Cfg : in     Port_Config;
      Success  :    out Boolean)
   with
      Pre => Port_Cfg.Port in GPU_FDI_Port
   is
      PCH_FDI_Port : constant PCH.FDI_Port_Type := PCH_FDIs (Port_Cfg.Port);
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      -- try each preemph/voltage pair twice
      for VP2 in Natural range 0 .. FDI_TX_CTL_VP_T'Last * 2 + 1
      loop
         Registers.Unset_And_Set_Mask
           (Register    => TX_CTL (Port_Cfg.Port),
            Mask_Unset  => FDI_TX_CTL_VP_MASK or
                           FDI_TX_CTL_TRAINING_PATTERN_MASK,
            Mask_Set    => FDI_TX_CTL_FDI_TX_ENABLE or
                           FDI_TX_CTL_VSWING_PREEMPH (VP2 / 2) or
                           FDI_TX_CTL_AUTO_TRAIN_ENABLE or
                           FDI_TX_CTL_TRAINING_PATTERN (TP_1));
         Registers.Posting_Read (TX_CTL (Port_Cfg.Port));

         PCH.FDI.Auto_Train (PCH_FDI_Port);

         -- read at least twice
         for I in 0 .. 3 loop
            Registers.Is_Set_Mask
              (Register => TX_CTL (Port_Cfg.Port),
               Mask     => FDI_TX_CTL_AUTO_TRAIN_DONE,
               Result   => Success);
            exit when Success or I = 3;
            Time.U_Delay (1);
         end loop;
         exit when Success;

         Registers.Unset_And_Set_Mask
           (Register    => TX_CTL (Port_Cfg.Port),
            Mask_Unset  => FDI_TX_CTL_FDI_TX_ENABLE or
                           FDI_TX_CTL_AUTO_TRAIN_ENABLE or
                           FDI_TX_CTL_TRAINING_PATTERN_MASK,
            Mask_Set    => FDI_TX_CTL_TRAINING_PATTERN (TP_1));

         PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Rx_Off);
      end loop;

      if Success then
         PCH.FDI.Enable_EC (PCH_FDI_Port);
      else
         Registers.Unset_Mask
           (Register => TX_CTL (Port_Cfg.Port),
            Mask     => FDI_TX_CTL_FDI_PLL_ENABLE);

         PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Clock_Off);
      end if;
   end Auto_Training;

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

   --
   -- Used with Sandy Bridge (should work with Ivy Bridge too)
   --
   procedure Full_Training
     (Port_Cfg : in     Port_Config;
      Success  :    out Boolean)
   with
      Pre => Port_Cfg.Port in GPU_FDI_Port
   is
      PCH_FDI_Port : constant PCH.FDI_Port_Type := PCH_FDIs (Port_Cfg.Port);
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      -- try each preemph/voltage pair twice
      for VP2 in Natural range 0 .. FDI_TX_CTL_VP_T'Last * 2 + 1
      loop
         Registers.Unset_And_Set_Mask
           (Register    => TX_CTL (Port_Cfg.Port),
            Mask_Unset  => FDI_TX_CTL_VP_MASK or
                           FDI_TX_CTL_TRAINING_PATTERN_MASK,
            Mask_Set    => FDI_TX_CTL_FDI_TX_ENABLE or
                           FDI_TX_CTL_VSWING_PREEMPH (VP2 / 2) or
                           FDI_TX_CTL_TRAINING_PATTERN (TP_1));
         Registers.Posting_Read (TX_CTL (Port_Cfg.Port));

         PCH.FDI.Train (PCH_FDI_Port, TP_1, Success);

         if Success then
            Registers.Unset_And_Set_Mask
              (Register    => TX_CTL (Port_Cfg.Port),
               Mask_Unset  => FDI_TX_CTL_TRAINING_PATTERN_MASK,
               Mask_Set    => FDI_TX_CTL_TRAINING_PATTERN (TP_2));
            Registers.Posting_Read (TX_CTL (Port_Cfg.Port));

            PCH.FDI.Train (PCH_FDI_Port, TP_2, Success);
         end if;
         exit when Success;

         Registers.Unset_And_Set_Mask
           (Register    => TX_CTL (Port_Cfg.Port),
            Mask_Unset  => FDI_TX_CTL_FDI_TX_ENABLE or
                           FDI_TX_CTL_TRAINING_PATTERN_MASK,
            Mask_Set    => FDI_TX_CTL_TRAINING_PATTERN (TP_1));

         PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Rx_Off);
      end loop;

      if Success then
         Registers.Unset_And_Set_Mask
           (Register    => TX_CTL (Port_Cfg.Port),
            Mask_Unset  => FDI_TX_CTL_TRAINING_PATTERN_MASK,
            Mask_Set    => FDI_TX_CTL_TRAINING_PATTERN (TP_None));
         Registers.Posting_Read (TX_CTL (Port_Cfg.Port));

         PCH.FDI.Train (PCH_FDI_Port, TP_None, Success);
      else
         Registers.Unset_Mask
           (Register => TX_CTL (Port_Cfg.Port),
            Mask     => FDI_TX_CTL_FDI_PLL_ENABLE);

         PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Clock_Off);
      end if;
   end Full_Training;

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

   --
   -- Used with original Ironlake (Nehalem CPU)
   --
   -- This is close to what Linux' i915 does. A comment in i915_reg.h
   -- states that it uses only the lowest voltage / pre-emphasis levels
   -- which is why we leave them at zero here and don't try different
   -- values.
   --
   -- It's actually not clear from i915's code if the values really are
   -- at zero or if it's just reusing what the Video BIOS set. Some code
   -- in coreboot sets them to zero explicitly.
   --
   procedure Simple_Training
     (Port_Cfg : in     Port_Config;
      Success  :    out Boolean)
   with
      Pre => Port_Cfg.Port in GPU_FDI_Port
   is
      PCH_FDI_Port : constant PCH.FDI_Port_Type := PCH_FDIs (Port_Cfg.Port);
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Registers.Unset_And_Set_Mask
        (Register    => TX_CTL (Port_Cfg.Port),
         Mask_Unset  => FDI_TX_CTL_TRAINING_PATTERN_MASK,
         Mask_Set    => FDI_TX_CTL_FDI_TX_ENABLE or
                        FDI_TX_CTL_TRAINING_PATTERN (TP_1));
      Registers.Posting_Read (TX_CTL (Port_Cfg.Port));

      PCH.FDI.Train (PCH_FDI_Port, TP_1, Success);

      if Success then
         Registers.Unset_And_Set_Mask
           (Register    => TX_CTL (Port_Cfg.Port),
            Mask_Unset  => FDI_TX_CTL_TRAINING_PATTERN_MASK,
            Mask_Set    => FDI_TX_CTL_TRAINING_PATTERN (TP_2));
         Registers.Posting_Read (TX_CTL (Port_Cfg.Port));

         PCH.FDI.Train (PCH_FDI_Port, TP_2, Success);
      end if;

      if Success then
         Registers.Unset_And_Set_Mask
           (Register    => TX_CTL (Port_Cfg.Port),
            Mask_Unset  => FDI_TX_CTL_TRAINING_PATTERN_MASK,
            Mask_Set    => FDI_TX_CTL_TRAINING_PATTERN (TP_None));
         Registers.Posting_Read (TX_CTL (Port_Cfg.Port));

         PCH.FDI.Train (PCH_FDI_Port, TP_None, Success);
      else
         Registers.Unset_And_Set_Mask
           (Register    => TX_CTL (Port_Cfg.Port),
            Mask_Unset  => FDI_TX_CTL_FDI_TX_ENABLE or
                           FDI_TX_CTL_TRAINING_PATTERN_MASK,
            Mask_Set    => FDI_TX_CTL_TRAINING_PATTERN (TP_1));
         PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Rx_Off);

         Registers.Unset_Mask
           (Register => TX_CTL (Port_Cfg.Port),
            Mask     => FDI_TX_CTL_FDI_PLL_ENABLE);
         PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Clock_Off);
      end if;
   end Simple_Training;

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

   procedure Pre_On (Port_Cfg : Port_Config)
   is
      Composite_Sel : constant Word32 :=
        (if Config.Has_FDI_Composite_Sel then
            FDI_TX_CTL_COMPOSITE_SYNC_SELECT else 0);
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      -- The PCH_FDI_CHICKEN_B_AND_C bit may not be changed when any of
      -- both ports is active. Bandwidth calculations before calling us
      -- should ensure this.
      if Config.Has_FDI_C then
         if Port_Cfg.Port = DIGI_D or
            (Port_Cfg.Port = DIGI_C and
             Port_Cfg.FDI.Lane_Count <= DP_Lane_Count_2)
         then
            Registers.Set_Mask
              (Register => Registers.PCH_FDI_CHICKEN_B_C,
               Mask     => PCH_FDI_CHICKEN_B_AND_C);
         elsif Port_Cfg.Port = DIGI_C then
            Registers.Unset_Mask
              (Register => Registers.PCH_FDI_CHICKEN_B_C,
               Mask     => PCH_FDI_CHICKEN_B_AND_C);
         end if;
      end if;

      PCH.FDI.Pre_Train (PCH_FDIs (Port_Cfg.Port), Port_Cfg);

      Registers.Write
        (Register => TX_CTL (Port_Cfg.Port),
         Value    => FDI_TX_CTL_PORT_WIDTH_SEL (Port_Cfg.FDI.Lane_Count) or
                     FDI_TX_CTL_ENHANCED_FRAMING_ENABLE or
                     FDI_TX_CTL_FDI_PLL_ENABLE or
                     Composite_Sel or
                     FDI_TX_CTL_TRAINING_PATTERN (TP_1));
      Registers.Posting_Read (TX_CTL (Port_Cfg.Port));
      Time.U_Delay (100);
   end Pre_On;

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

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

      case Config.FDI_Training is
         when GMA.Simple_Training   => Simple_Training (Port_Cfg, Success);
         when GMA.Full_Training     => Full_Training (Port_Cfg, Success);
         when GMA.Auto_Training     => Auto_Training (Port_Cfg, Success);
      end case;
   end Post_On;

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

   procedure Off (Port : GPU_FDI_Port; OT : Off_Type)
   is
      PCH_FDI_Port : constant PCH.FDI_Port_Type := PCH_FDIs (Port);
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Registers.Unset_And_Set_Mask
        (Register    => TX_CTL (Port),
         Mask_Unset  => FDI_TX_CTL_FDI_TX_ENABLE or
                        FDI_TX_CTL_AUTO_TRAIN_ENABLE or
                        FDI_TX_CTL_TRAINING_PATTERN_MASK,
         Mask_Set    => FDI_TX_CTL_TRAINING_PATTERN (TP_1));

      PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Rx_Off);

      if OT >= Clock_Off then
         Registers.Unset_Mask
           (Register => TX_CTL (Port),
            Mask     => FDI_TX_CTL_FDI_PLL_ENABLE);

         PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Clock_Off);
      end if;
   end Off;

end HW.GFX.GMA.Connectors.FDI;
