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

package body HW.GFX.GMA.Connector_Info is

   procedure Preferred_Link_Setting
     (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
           (case Port_Cfg.Port is
              when DIGI_A => DP_A,
              when DIGI_B => DP_B,
              when DIGI_C => DP_C,
              when DDI_TC1 => DP_D,
              when DDI_TC2 => DP_E,
              when DDI_TC3 => DP_F,
              when DDI_TC4 => DP_G,
              when DDI_TC5 => DP_H,
              when DDI_TC6 => DP_I,
              when others => GMA.DP_Port'First)
         else
           (if Port_Cfg.Port = DIGI_A then
               DP_A
            else
              (case Port_Cfg.PCH_Port is
                  when PCH_DP_B  => DP_B,
                  when PCH_DP_C  => DP_C,
                  when PCH_DP_D  => DP_D,
                  when others    => GMA.DP_Port'First)));
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      if Port_Cfg.Display = DP then
         if GMA.Config.Use_PP_VDD_Override then
            Panel.VDD_Override (Port_Cfg.Panel);
         else
            Panel.On (Port_Cfg.Panel);
         end if;

         DP_Dual_Mode.Switch_LSPCON (DP_Port);

         DP_Info.Read_Caps
           (Link     => Port_Cfg.DP,
            Port     => DP_Port,
            Success  => Success);
         if Success then
            DP_Info.Read_eDP_Rates
              (Link     => Port_Cfg.DP,
               Port     => DP_Port);

            DP_Info.Preferred_Link_Setting
              (Link     => Port_Cfg.DP,
               Mode     => Port_Cfg.Mode,
               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;
   end Preferred_Link_Setting;

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

      if Port_Cfg.Display = DP then
         DP_Info.Next_Link_Setting
           (Link     => Port_Cfg.DP,
            Mode     => Port_Cfg.Mode,
            Success  => Success);
         pragma Debug (Success, DP_Info.Dump_Link_Setting (Port_Cfg.DP));
      else
         Success := False;
      end if;
   end Next_Link_Setting;

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

   function Default_BPC (Port_Cfg : Port_Config) return HW.GFX.BPC_Type
   is
   begin
      return
        (if (Port_Cfg.Port = DIGI_A and Port_Cfg.Display /= HDMI) or
           (Port_Cfg.Is_FDI and Port_Cfg.PCH_Port = PCH_LVDS) or
           Port_Cfg.Port = LVDS
         then 6
         else 8);
   end Default_BPC;

end HW.GFX.GMA.Connector_Info;
