--
-- Copyright (C) 2015-2016 secunet Security Networks AG
-- Copyright (C) 2016 Nico Huber <nico.h@gmx.de>
--
-- 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; version 2 of the License.
--
-- 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.GMA.Config;
with HW.GFX.GMA.Panel;
with HW.GFX.GMA.Connectors.EDP;
with HW.GFX.GMA.Connectors.FDI;
with HW.GFX.GMA.PCH.VGA;
with HW.GFX.GMA.PCH.LVDS;
with HW.GFX.GMA.PCH.HDMI;
with HW.GFX.GMA.PCH.DP;
with HW.GFX.GMA.PCH.Transcoder;

with HW.Debug;
with GNAT.Source_Info;

package body HW.GFX.GMA.Connectors
is

   function Is_Internal (Port_Cfg : Port_Config) return Boolean
   is
   begin
      return
         Port_Cfg.Port = DIGI_A or
         (Port_Cfg.Is_FDI and Port_Cfg.PCH_Port = PCH_LVDS);
   end Is_Internal;

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

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

      if Port_Cfg.Port = DIGI_A then
         EDP.Pre_On (Port_Cfg, Pipe_Hint);
      elsif Port_Cfg.Port in FDI.GPU_FDI_Port then
         FDI.Pre_On (Port_Cfg);
      end if;
      Success := True;
   end Pre_On;

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

      if Port_Cfg.Port = DIGI_A then
         EDP.Pre_Training;
         Success := True;
      elsif Port_Cfg.Port in FDI.GPU_FDI_Port then
         declare
            FDI_Port : constant PCH.FDI_Port_Type :=
               FDI.PCH_FDIs (Port_Cfg.Port);
         begin
            FDI.Post_On (Port_Cfg, Success);

            if Success then
               PCH.Transcoder.On (Port_Cfg, FDI_Port, PLL_Hint);
               if Port_Cfg.PCH_Port = PCH_DAC then
                  PCH.VGA.On (FDI_Port, Port_Cfg.Mode);
               elsif Port_Cfg.PCH_Port = PCH_LVDS then
                  PCH.LVDS.On (Port_Cfg, FDI_Port);
               elsif Port_Cfg.PCH_Port in PCH_HDMI_Port then
                  PCH.HDMI.On (Port_Cfg, FDI_Port);
               elsif Port_Cfg.PCH_Port in PCH_DP_Port then
                  PCH.DP.On (Port_Cfg, Success);
               end if;
            end if;
         end;
      else
         Success := False;
      end if;

      if Success and Is_Internal (Port_Cfg) then
         Panel.On;
      end if;

      if Port_Cfg.Port = DIGI_A then
         EDP.Post_On (Port_Cfg.DP, Success);
      end if;

      if Success and Is_Internal (Port_Cfg) then
         Panel.Backlight_On;
      end if;
   end Post_On;

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

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

      if Is_Internal (Port_Cfg) then
         Panel.Backlight_Off;
         Panel.Off;
      end if;
   end Pre_Off;

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

      if Port_Cfg.Port = DIGI_A then
         EDP.Off (Port_Cfg.Port);
      elsif Port_Cfg.Port in FDI.GPU_FDI_Port then
         declare
            FDI_Port : constant PCH.FDI_Port_Type :=
               FDI.PCH_FDIs (Port_Cfg.Port);
         begin
            if Port_Cfg.PCH_Port in PCH_DP_Port then
               PCH.DP.Off (Port_Cfg.PCH_Port);
            end if;

            FDI.Off (Port_Cfg.Port, FDI.Link_Off);

            if Port_Cfg.PCH_Port = PCH_DAC then
               PCH.VGA.Off;
            elsif Port_Cfg.PCH_Port = PCH_LVDS then
               PCH.LVDS.Off;
            elsif Port_Cfg.PCH_Port in PCH_HDMI_Port then
               PCH.HDMI.Off (Port_Cfg.PCH_Port);
            end if;
            PCH.Transcoder.Off (FDI_Port);

            FDI.Off (Port_Cfg.Port, FDI.Clock_Off);
         end;
      end if;
   end Post_Off;

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

   procedure Pre_All_Off
   is
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Panel.Backlight_Off;
      Panel.Off;
   end Pre_All_Off;

   procedure Post_All_Off
   is
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      EDP.Off (DIGI_A);

      for Port in FDI.GPU_FDI_Port loop
         FDI.Off (Port, FDI.Link_Off);
      end loop;
      PCH.VGA.Off;
      PCH.LVDS.Off;
      PCH.HDMI.All_Off;
      PCH.DP.All_Off;
      for Port in PCH.FDI_Port_Type loop
         PCH.Transcoder.Off (Port);
      end loop;
      for Port in FDI.GPU_FDI_Port loop
         FDI.Off (Port, FDI.Clock_Off);
      end loop;
   end Post_All_Off;

end HW.GFX.GMA.Connectors;
