--
-- 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 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;

   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;
