--
-- Copyright (C) Google, LLC
-- Copyright (C) 2024 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.GMA.Config;
with HW.GFX.GMA.Registers;
with HW.GFX.GMA.Config_Helpers;
with HW.GFX.GMA.Connectors.TC;

with HW.Debug;
with GNAT.Source_Info;

package body HW.GFX.GMA.Port_Detect
is
   SHOTPLUG_CTL_DDI_HPD_STATUS_MASK    : constant := 16#0333#;

   function SHOTPLUG_CTL_DDI_HPD_ENABLE (P : Combo_Port) return Word32 is
     (Shift_Left (8, 4 * (GPU_Port'Pos (P) - GPU_Port'Pos (Combo_Port'First))));

   function SHOTPLUG_CTL_DDI_HPD_STATUS (P : Combo_Port) return Word32 is
     (Shift_Left (3, 4 * (GPU_Port'Pos (P) - GPU_Port'Pos (Combo_Port'First))));

   function SHOTPLUG_CTL_DDI_HPD_LONG_DETECT (P : Combo_Port) return Word32 is
     (Shift_Left (2, 4 * (GPU_Port'Pos (P) - GPU_Port'Pos (Combo_Port'First))));

   SHOTPLUG_CTL_TC_DDI_HPD_STATUS_MASK : constant := 16#0033_3333#;

   function SHOTPLUG_CTL_TC_DDI_HPD_ENABLE (P : USBC_Port) return Word32 is
     (Shift_Left (8, 4 * (GPU_Port'Pos (P) - GPU_Port'Pos (USBC_Port'First))));

   function SHOTPLUG_CTL_TC_DDI_HPD_STATUS (P : USBC_Port) return Word32 is
     (Shift_Left (3, 4 * (GPU_Port'Pos (P) - GPU_Port'Pos (USBC_Port'First))));

   function SHOTPLUG_CTL_TC_DDI_HPD_LONG_DETECT (P : USBC_Port) return Word32 is
     (Shift_Left (2, 4 * (GPU_Port'Pos (P) - GPU_Port'Pos (USBC_Port'First))));

   TC_HOTPLUG_CTL_HPD_STATUS_MASK : constant := 16#0033_3333#;

   function TC_HOTPLUG_CTL_HPD_ENABLE (P : USBC_Port) return Word32 renames
      SHOTPLUG_CTL_TC_DDI_HPD_ENABLE;

   function TC_HOTPLUG_CTL_HPD_STATUS (P : USBC_Port) return Word32 renames
      SHOTPLUG_CTL_TC_DDI_HPD_STATUS;

   procedure Initialize
   is
      Success : Boolean;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Registers.Unset_And_Set_Mask
        (Register => Registers.SHPD_FILTER_CNT,
         Mask_Unset => 16#1_ffff#,
         Mask_Set   => 16#1d9#); -- constant from i915 (SHPD_FILTER_CNT_500_ADJ)

      -- Hotplug for combo ports
      Registers.Set_Mask
        (Register => Registers.SHOTPLUG_CTL,
         Mask     =>
            SHOTPLUG_CTL_DDI_HPD_ENABLE (DIGI_A) or
            SHOTPLUG_CTL_DDI_HPD_ENABLE (DIGI_B) or
            SHOTPLUG_CTL_DDI_HPD_ENABLE (DIGI_C) or
            SHOTPLUG_CTL_DDI_HPD_STATUS_MASK); -- clear status

      -- Validity can only be detected via hotplug.
      -- DP3/HDMI3 doesn't exist in any TGL SKU.
      for Port in DP1 .. DP2 loop
         Config.Valid_Port (Port) := True;
      end loop;
      for Port in DP_TC1 .. DP_TC4 loop
         Config.Valid_Port (Port) := True;
      end loop;
      for Port in HDMI1 .. HDMI2 loop
         Config.Valid_Port (Port) := True;
      end loop;
      for Port in HDMI_TC1 .. HDMI_TC4 loop
         Config.Valid_Port (Port) := True;
      end loop;
      for Port in USBC1 .. USBC4 loop
         Config.Valid_Port (Port) := True;
      end loop;

      for Port in DDI_TC1 .. Config.Last_TC_Port loop
         -- Hotplug for Type-C ports in legacy mode
         Registers.Set_Mask
           (Register => Registers.SHOTPLUG_CTL_TC,
            Mask     => SHOTPLUG_CTL_TC_DDI_HPD_ENABLE (Port));
         -- Hotplug for Type-C ports in DP-Alt mode
         Registers.Set_Mask
           (Register => Registers.TC_HOTPLUG_CTL,
            Mask     => TC_HOTPLUG_CTL_HPD_ENABLE (Port));
      end loop;

      -- Clear status:
      Registers.Set_Mask
        (Register => Registers.SHOTPLUG_CTL_TC,
         Mask     => SHOTPLUG_CTL_TC_DDI_HPD_STATUS_MASK);
      Registers.Set_Mask
        (Register => Registers.TC_HOTPLUG_CTL,
         Mask     => TC_HOTPLUG_CTL_HPD_STATUS_MASK);

      -- TCCOLD should be blocked first before accessing FIA registers
      -- during e.g. connect flows. It can be unblocked only after done
      -- accessing FIA registers and there is no longer a connection
      -- i.e., after all ports are disconnected.
      -- In order to avoid keeping track of the state and constantly
      -- blocking and unblocking, we just block it once at the beginning
      -- and leave it that way.
      if Config.Block_TC_Cold then
         Connectors.TC.TC_Cold_Request (Connectors.TC.Block, Success);
         if not Success then
            Debug.Put_Line ("Failed to block TCCOLD, Type-C will not work!");
            return;
         end if;
      end if;
   end Initialize;

   procedure Hotplug_Detect
     (Port     : in Active_Port_Type;
      Detected : out Boolean)
   is
      GPU_Port : constant GMA.GPU_Port := Config_Helpers.To_GPU_Port (Pipe_Index'First, Port);
      North32, South32 : Word32;
   begin
      Detected := False;

      if GPU_Port in USBC_Port then
         Registers.Read (Registers.TC_HOTPLUG_CTL, North32, Verbose => False);
         Registers.Read (Registers.SHOTPLUG_CTL_TC, South32, Verbose => False);

         Detected := ((North32 or South32) and
            SHOTPLUG_CTL_TC_DDI_HPD_LONG_DETECT (GPU_Port)) /= 0;

         if (North32 and TC_HOTPLUG_CTL_HPD_STATUS (GPU_Port)) /= 0 then
            Registers.Unset_And_Set_Mask
              (Register    => Registers.TC_HOTPLUG_CTL,
               Mask_Unset  => TC_HOTPLUG_CTL_HPD_STATUS_MASK,
               Mask_Set    => TC_HOTPLUG_CTL_HPD_STATUS (GPU_Port));
         end if;
         if (South32 and TC_HOTPLUG_CTL_HPD_STATUS (GPU_Port)) /= 0 then
            Registers.Unset_And_Set_Mask
              (Register    => Registers.SHOTPLUG_CTL_TC,
               Mask_Unset  => SHOTPLUG_CTL_TC_DDI_HPD_STATUS_MASK,
               Mask_Set    => SHOTPLUG_CTL_TC_DDI_HPD_STATUS (GPU_Port));
         end if;
      end if;

      if GPU_Port in Combo_Port then
         Registers.Read (Registers.SHOTPLUG_CTL, South32, Verbose => False);
         Detected := (South32 and SHOTPLUG_CTL_DDI_HPD_LONG_DETECT (GPU_Port)) /= 0;

         if (South32 and SHOTPLUG_CTL_DDI_HPD_STATUS (GPU_Port)) /= 0 then
            Registers.Unset_And_Set_Mask
              (Register    => Registers.SHOTPLUG_CTL,
               Mask_Unset  => SHOTPLUG_CTL_DDI_HPD_STATUS_MASK,
               Mask_Set    => SHOTPLUG_CTL_DDI_HPD_STATUS (GPU_Port));
         end if;
      end if;
   end Hotplug_Detect;

   procedure Clear_Hotplug_Detect (Port : Active_Port_Type)
   is
      Ignored_HPD : Boolean;
   begin
      pragma Warnings (GNATprove, Off, "unused assignment to ""Ignored_HPD""",
                       Reason => "We want to clear pending events only");
      Port_Detect.Hotplug_Detect (Port, Ignored_HPD);
      pragma Warnings (GNATprove, On, "unused assignment to ""Ignored_HPD""");
   end Clear_Hotplug_Detect;

end HW.GFX.GMA.Port_Detect;
