--
-- Copyright (C) 2015-2016 secunet Security Networks AG
-- Copyright (C) 2019 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; 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.I2C;
with HW.GFX.GMA.Config;
with HW.GFX.GMA.Config_Helpers;
with HW.GFX.GMA.I2C;
with HW.GFX.GMA.DP_Aux_Ch;
with HW.GFX.GMA.Panel;
with HW.GFX.GMA.Port_Detect;
with HW.GFX.GMA.Power_And_Clocks;

with HW.Debug;
with GNAT.Source_Info;

package body HW.GFX.GMA.Display_Probing
is

   function Port_Configured (Configs : Pipe_Configs; Port : Port_Type)
      return Boolean is
     (Configs (Primary).Port    = Port or
      Configs (Secondary).Port  = Port or
      Configs (Tertiary).Port   = Port);

   -- DP and HDMI share physical pins.
   function Sibling_Port (Port : Port_Type) return Port_Type is
     (case Port is
         when HDMI1 => DP1,
         when HDMI2 => DP2,
         when HDMI3 => DP3,
         when DP1 => HDMI1,
         when DP2 => HDMI2,
         when DP3 => HDMI3,
         when HDMI_TC1 => DP_TC1,
         when HDMI_TC2 => DP_TC2,
         when HDMI_TC3 => DP_TC3,
         when HDMI_TC4 => DP_TC4,
         when DP_TC1 => HDMI_TC1,
         when DP_TC2 => HDMI_TC2,
         when DP_TC3 => HDMI_TC3,
         when DP_TC4 => HDMI_TC4,
         when others => Disabled);

   function Has_Sibling_Port (Port : Port_Type) return Boolean is
     (Sibling_Port (Port) /= Disabled);

   function Is_DVI_I (Port : Active_Port_Type) return Boolean is
     (Config.Have_DVI_I and
      (Port = Analog or
      Config_Helpers.To_PCH_Port (Port) = Config.Analog_I2C_Port));

   procedure Read_EDID
     (Raw_EDID :    out EDID.Raw_EDID_Data;
      Port     : in     Active_Port_Type;
      Success  :    out Boolean)
   is
      Raw_EDID_Length : GFX.I2C.Transfer_Length := Raw_EDID'Length;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      for I in 1 .. 2 loop
         if Config_Helpers.To_Display_Type (Port) = DP then
            -- May need power and CDClk to read EDID
            declare
               Temp_Configs : Pipe_Configs := Cur_Configs;
            begin
               Temp_Configs (Primary).Port := Port;
               Power_And_Clocks.Power_Up (Cur_Configs, Temp_Configs);
               Power_And_Clocks.Enable_CDClk;
            end;

            declare
               DP_Port : constant GMA.DP_Port :=
                 (if Config.Has_Type_C_Ports then
                    (case Config_Helpers.To_GPU_Port (Pipe_Index'First, 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
                    (case Port is
                        when eDP       => DP_A,
                        when DP1       => DP_B,
                        when DP2       => DP_C,
                        when DP3       => DP_D,
                        when others    => GMA.DP_Port'First));
            begin
               DP_Aux_Ch.I2C_Read
                 (Port     => DP_Port,
                  Address  => 16#50#,
                  Length   => Raw_EDID_Length,
                  Data     => Raw_EDID,
                  Success  => Success);
            end;
         else
            I2C.I2C_Read
              (Port     => (if Port = Analog
                            then Config.Analog_I2C_Port
                            else Config_Helpers.To_PCH_Port (Port)),
               Address  => 16#50#,
               Length   => Raw_EDID_Length,
               Data     => Raw_EDID,
               Success  => Success);
         end if;
         exit when not Success;  -- don't retry if reading itself failed

         pragma Debug (Debug.Put_Buffer ("EDID", Raw_EDID, Raw_EDID_Length));
         EDID.Sanitize (Raw_EDID, Success);
         exit when Success;
      end loop;
   end Read_EDID;

   procedure Probe_Port
     (Pipe_Cfg : in out Pipe_Config;
      Port     : in     Active_Port_Type;
      Success  :    out Boolean)
   with Pre => True
   is
      Raw_EDID : EDID.Raw_EDID_Data := (others => 16#00#);
   begin
      Success := Config.Valid_Port (Port);

      if Success then
         Panel.Wait_On (Config_Helpers.To_Panel (Port));
         Read_EDID (Raw_EDID, Port, Success);
      end if;

      if Success and then
         ((not Is_DVI_I (Port) or EDID.Compatible_Display
            (Raw_EDID, Config_Helpers.To_Display_Type (Port))) and
          EDID.Has_Preferred_Mode (Raw_EDID))
      then
         Pipe_Cfg.Port := Port;
         Pipe_Cfg.Mode := EDID.Preferred_Mode (Raw_EDID);

         pragma Warnings (GNATprove, Off, "unused assignment to ""Raw_EDID""",
            Reason => "We just want to check if it's readable.");
         pragma Warnings (GNATprove, Off, """Raw_EDID"" is set by * but*",
            Reason => "We just want to check if it's readable.");
         if Has_Sibling_Port (Port) then
            -- Probe sibling port too and bail out if something is detected.
            -- This is a precaution for adapters that expose the pins of a
            -- port for both HDMI/DVI and DP (like some ThinkPad docks). A
            -- user might have attached both by accident and there are ru-
            -- mors of displays that got fried by applying the wrong signal.
            declare
               Have_Sibling_EDID : Boolean;
            begin
               Read_EDID (Raw_EDID, Sibling_Port (Port), Have_Sibling_EDID);
               if Have_Sibling_EDID then
                  Pipe_Cfg.Port := Disabled;
                  Success := False;
               end if;
            end;
         end if;
         pragma Warnings (GNATprove, On, """Raw_EDID"" is set by * but*");
         pragma Warnings (GNATprove, On, "unused assignment to ""Raw_EDID""");
      else
         Success := False;
      end if;
   end Probe_Port;

   procedure Scan_Ports
     (Configs     :    out Pipe_Configs;
      Ports       : in     Port_List := All_Ports;
      Max_Pipe    : in     Pipe_Index := Pipe_Index'Last;
      Keep_Power  : in     Boolean := False)
   is
      Probed_Panels : array (Valid_Panels) of Boolean := (others => False);

      Port_Idx : Port_List_Range := Port_List_Range'First;
      Success  : Boolean;
   begin
      Configs := (Pipe_Index =>
                    (Port        => Disabled,
                     Mode        => Invalid_Mode,
                     Cursor      => Default_Cursor,
                     Framebuffer => Default_FB));

      -- Turn panel on early to probe other ports during the power on delay.
      for Idx in Port_List_Range loop
         exit when Ports (Idx) = Disabled;
         declare
            P : constant Panel_Control := Config_Helpers.To_Panel (Ports (Idx));
         begin
            if P /= No_Panel then
               Panel.On (P, Wait => False);
               Probed_Panels (P) := True;
            end if;
         end;
      end loop;

      for Pipe in Pipe_Index range
         Pipe_Index'First .. Pipe_Index'Min (Max_Pipe, Config.Max_Pipe)
      loop
         Success := False;
         while Ports (Port_Idx) /= Disabled loop
            if not Port_Configured (Configs, Ports (Port_Idx)) and
               (not Has_Sibling_Port (Ports (Port_Idx)) or
                not Port_Configured (Configs, Sibling_Port (Ports (Port_Idx))))
            then
               Probe_Port (Configs (Pipe), Ports (Port_Idx), Success);
            else
               Success := False;
            end if;

            exit when Port_Idx = Port_List_Range'Last;
            Port_Idx := Port_List_Range'Succ (Port_Idx);

            exit when Success;
         end loop;
         exit when not Success;
      end loop;

      -- On pre-i965 hardware, LVDS must use Pipe B (Secondary).
      -- If the scan assigned LVDS to Primary, swap with Secondary.
      if Config.LVDS_Needs_Pipe_B and
         Configs (Primary).Port = LVDS
      then
         declare
            Tmp : constant Pipe_Config := Configs (Secondary);
         begin
            Configs (Secondary) := Configs (Primary);
            Configs (Primary) := Tmp;
         end;
      end if;

      -- Restore power settings
      if not Keep_Power then
         Power_And_Clocks.Power_Set_To (Cur_Configs);
      end if;

      -- Turn panel power off if probing failed.
      for P in Valid_Panels loop
         if Probed_Panels (P) and not
            Port_Configured (Configs, Config.Panel_Ports (P))
         then
            Panel.Off (P);
         end if;
      end loop;
   end Scan_Ports;

   procedure Hotplug_Events (Ports : out Port_List)
   is
      I : Port_List_Range := Port_List_Range'First;
      Detected : Boolean;
   begin
      Ports := (others => Disabled);
      for P in Active_Port_Type loop
         Port_Detect.Hotplug_Detect (P, Detected);
         if Detected then
            Ports (I) := P;
            exit when I = Port_List_Range'Last;
            I := Port_List_Range'Succ (I);
         end if;
      end loop;
   end Hotplug_Events;

end HW.GFX.GMA.Display_Probing;
