--
-- 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.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 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 :=
                 (case Port is
                     when Internal  => 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
         if Port = Internal then
            Panel.Wait_On;
         end if;
         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.");
         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, "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
      Probe_Internal : Boolean := 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;
         if Ports (Idx) = Internal then
            Panel.On (Wait => False);
            Probe_Internal := True;
            exit;
         end if;
      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;

      -- 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.
      if Probe_Internal and not Port_Configured (Configs, Internal) then
         Panel.Off;
      end if;
   end Scan_Ports;

end HW.GFX.GMA.Display_Probing;
