--
-- 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.Connectors;
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
            Power_And_Clocks.Power_Up (Port, Success);
            exit when not Success;
            Power_And_Clocks.Enable_CDClk;

            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 with Relaxed_Initialization;
   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,
                     Alignment   => Center,
                     Scaling     => Fit,
                     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;
