--
-- Copyright (C) 2015-2017 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 Ada.Unchecked_Conversion;

with HW.Debug;
with GNAT.Source_Info;

with HW.GFX.DP_Defs;

use type HW.Word8;
use type HW.Word16;

package body HW.GFX.DP_Info is

   procedure Read_Caps
     (Link     : in out DP_Link;
      Port     : in     T;
      Success  :    out Boolean)
   is
      Data : DP_Defs.Aux_Payload;
      Length : DP_Defs.Aux_Payload_Length;

      Caps_Size : constant := 15;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Length := Caps_Size;
      Aux_Ch.Aux_Read
        (Port     => Port,
         Address  => 16#00000#,
         Length   => Length,
         Data     => Data,
         Success  => Success);
      Success := Success and Length = Caps_Size;

      if Length = Caps_Size then
         Link.Receiver_Caps.Rev := Data (0);
         case Data (1) is
            when 16#06# =>
               Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_1_62;
            when 16#0a# =>
               Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_2_7;
            when 16#14# =>
               Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_5_4;
            when others =>
               if Data (1) > 16#14# then
                  Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_5_4;
               else
                  Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_1_62;
               end if;
         end case;
         case Data (2) and 16#1f# is
            when 0 | 1  =>
               Link.Receiver_Caps.Max_Lane_Count := DP_Lane_Count_1;
            when 2 | 3  =>
               Link.Receiver_Caps.Max_Lane_Count := DP_Lane_Count_2;
            when others =>
               Link.Receiver_Caps.Max_Lane_Count := DP_Lane_Count_4;
         end case;
         Link.Receiver_Caps.TPS3_Supported     := (Data (2) and 16#40#) /= 0;
         Link.Receiver_Caps.Enhanced_Framing   := (Data (2) and 16#80#) /= 0;
         Link.Receiver_Caps.No_Aux_Handshake   := (Data (3) and 16#40#) /= 0;
         Link.Receiver_Caps.Aux_RD_Interval    := Data (14) and 16#7f#;

         pragma Debug (Debug.New_Line);
         pragma Debug (Debug.Put_Line ("DPCD:"));
         pragma Debug (Debug.Put_Reg8 ("  Rev             ", Data (0)));
         pragma Debug (Debug.Put_Reg8 ("  Max_Link_Rate   ", Data (1)));
         pragma Debug (Debug.Put_Reg8 ("  Max_Lane_Count  ", Data (2) and 16#1f#));
         pragma Debug (Debug.Put_Reg8 ("  TPS3_Supported  ", Data (2) and 16#40#));
         pragma Debug (Debug.Put_Reg8 ("  Enhanced_Framing", Data (2) and 16#80#));
         pragma Debug (Debug.Put_Reg8 ("  No_Aux_Handshake", Data (3) and 16#40#));
         pragma Debug (Debug.Put_Reg8 ("  Aux_RD_Interval ", Data (14) and 16#7f#));
         pragma Debug (Debug.New_Line);
      end if;
   end Read_Caps;

   function Read_LE16
     (Raw_Payload : DP_Defs.Aux_Payload;
      Offset      : DP_Defs.Aux_Payload_Index)
      return Word16
   with
      Pre => Offset < DP_Defs.Aux_Payload_Index'Last
   is
   begin
      return Shift_Left (Word16 (Raw_Payload (Offset + 1)), 8) or
             Word16 (Raw_Payload (Offset));
   end Read_LE16;

   procedure Read_eDP_Rates
     (Link     : in out DP_Link;
      Port     : in     T)
   is
      Data : DP_Defs.Aux_Payload;
      Length : DP_Defs.Aux_Payload_Length;
      Max_Rate : Natural;
      Success  : Boolean;

      Caps_Size : constant := 3;
      Rates_Size : constant := 16;
      eDP_Rev_1_4 : constant := 3;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Length := Caps_Size;
      Aux_Ch.Aux_Read
          (Port    => Port,
          Address  => 16#00700#,
          Length   => Length,
          Data     => Data,
          Success  => Success);
      Success := Success and Length = Caps_Size;
      if not Success or Data (0) < eDP_Rev_1_4 then
         return;
      end if;

      Length := Rates_Size;
      Aux_Ch.Aux_Read
        (Port     => Port,
         Address  => 16#00010#,
         Length   => Length,
         Data     => Data,
         Success  => Success);
      Success := Success and Length = Rates_Size;
      if not Success then
         return;
      end if;

      pragma Debug (Debug.New_Line);
      pragma Debug (Debug.Put_Line ("DPCD eDP 1.4+ link rates:"));

      -- TODO: support individual link rates (storing them all)

      Max_Rate := Natural'First;
      for I in 0 .. Length / 2 - 1 loop
         pragma Loop_Invariant (Max_Rate <= Natural (Word16'Last));
         declare
            Rate : constant Word16 := Read_LE16 (Data, I * 2);
         begin
            exit when Rate = 0; -- prematurely exit the loop
            pragma Debug (Debug.Put (" - "));
            pragma Debug (Debug.Put_Int8 (Int8 (I)));
            pragma Debug (Debug.Put (": "));
            pragma Debug (Debug.Put_Word16 (Rate));
            pragma Debug (Debug.New_Line);
            if Natural (Rate) > Max_Rate then
               Max_Rate := Natural (Rate);
            end if;
         end;
      end loop;
      pragma Debug (Debug.New_Line);

      -- convert to KHz
      Max_Rate := Max_Rate * 20;

      if Max_Rate >= 540_000 then
         Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_5_4;
      elsif Max_Rate >= 270_000 then
         Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_2_7;
      elsif Max_Rate >= 162_000 then
         Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_1_62;
      end if;
   end Read_eDP_Rates;

   procedure Minimum_Lane_Count
     (Link        : in out DP_Link;
      Mode        : in     Mode_Type;
      Success     :    out Boolean)
   with
      Depends => ((Link, Success) => (Link, Mode))
   is
      Lane_Pixel_Per_Second : constant Pos64 :=
        (((DP_Symbol_Rate (Link.Bandwidth) * 8) / 3) / Mode.BPC);
      Count : constant Pos64 :=
         Div_Round_Up (Mode.Dotclock, Lane_Pixel_Per_Second);
   begin
      Success := True;
      case Count is
         when 1      => Link.Lane_Count := DP_Lane_Count_1;
         when 2      => Link.Lane_Count := DP_Lane_Count_2;
         when 3 | 4  => Link.Lane_Count := DP_Lane_Count_4;
         when others => Success := False;
      end case;
   end Minimum_Lane_Count;

   procedure Preferred_Link_Setting
     (Link        : in out DP_Link;
      Mode        : in     Mode_Type;
      Success     :    out Boolean)
   is
   begin
      Link.Bandwidth          := Link.Receiver_Caps.Max_Link_Rate;
      Link.Enhanced_Framing   := Link.Receiver_Caps.Enhanced_Framing;

      Minimum_Lane_Count (Link, Mode, Success);

      Success := Success and
                  Link.Lane_Count <= Link.Receiver_Caps.Max_Lane_Count;

      pragma Debug (not Success, Debug.Put_Line
        ("Mode requirements exceed available bandwidth!"));
   end Preferred_Link_Setting;

   procedure Next_Link_Setting
     (Link        : in out DP_Link;
      Mode        : in     Mode_Type;
      Success     :    out Boolean)
   is
   begin
      if Link.Bandwidth > DP_Bandwidth'First then
         Link.Bandwidth := DP_Bandwidth'Pred (Link.Bandwidth);

         Minimum_Lane_Count (Link, Mode, Success);

         Success := Success and
                    Link.Lane_Count <= Link.Receiver_Caps.Max_Lane_Count;
      else
         Success := False;
      end if;
   end Next_Link_Setting;

   procedure Dump_Link_Setting (Link : DP_Link)
   is
   begin
      Debug.Put ("Trying DP settings: Symbol Rate = ");
      Debug.Put_Int32 (Int32 (DP_Symbol_Rate (Link.Bandwidth)));
      Debug.Put ("; Lane Count = ");
      Debug.Put_Int32 (Int32 (Lane_Count_As_Integer (Link.Lane_Count)));
      Debug.New_Line;
      Debug.New_Line;
   end Dump_Link_Setting;

   ----------------------------------------------------------------------------

   procedure Calculate_M_N
     (Link     : in     DP_Link;
      Mode     : in     Mode_Type;
      Data_M   :    out M_Type;
      Data_N   :    out N_Type;
      Link_M   :    out M_Type;
      Link_N   :    out N_Type)
   is
      DATA_N_MAX : constant := 16#800000#;
      LINK_N_MAX : constant := 16#100000#;

      subtype Calc_M_Type is Int64 range 0 .. 2 ** 38;
      subtype Calc_N_Type is Int64 range 0 .. 2 ** 38;
      subtype N_Rounded_Type is Int64 range
         0 .. Int64'Max (DATA_N_MAX, LINK_N_MAX);

      M : Calc_M_Type;
      N : Calc_N_Type;

      procedure Cancel_M_N
        (M     : in out Calc_M_Type;
         N     : in out Calc_N_Type;
         N_Max : in     N_Rounded_Type)
      with
         Depends => ((M, N) => (M, N, N_Max)),
         Pre => (N > 0 and M in 0 .. Calc_M_Type'Last / 2),
         Post => (M <= M_N_Max and N <= M_N_Max)
      is
         Orig_N : constant Calc_N_Type := N;

         function Round_N (N : Calc_N_Type) return N_Rounded_Type
         with
            Post => (Round_N'Result <= N * 2)
         is
            RN : Calc_N_Type;
            RN2 : Calc_N_Type := N_Max;
         begin
            loop
               RN := RN2;
               RN2 := RN2 / 2;
               exit when RN2 < N;
               pragma Loop_Invariant (RN2 = RN / 2 and RN2 in N .. N_Max);
            end loop;
            return RN;
         end Round_N;
      begin
         N := Round_N (N);

         -- The automatic provers need a little nudge here.
         pragma Assert
            (if M <= Calc_M_Type'Last / 2 and
                N <= Orig_N * 2 and
                Orig_N > 0 and
                M > 0
             then
                M * N / Orig_N <= Calc_M_Type'Last);

         pragma Annotate (GNATprove, False_Positive,
            "assertion might fail",
            "The property cannot be proven automatically. An Isabelle proof is included as an axiom");

         M := M * N / Orig_N;

         -- This loop is never hit for sane values (i.e. M <= N) but
         -- we have to make sure returned values are always in range.
         while M > M_N_Max loop
            pragma Loop_Invariant (N <= M_N_Max);
            M := M / 2;
            N := N / 2;
         end loop;
      end Cancel_M_N;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      pragma Assert (3
                     * Mode.BPC
                     * Mode.Dotclock
                     in Pos64);
      M := 3
           * Mode.BPC
           * Mode.Dotclock;

      pragma Assert (8
                     * DP_Symbol_Rate (Link.Bandwidth)
                     * Lane_Count_As_Integer (Link.Lane_Count)
                     in Pos64);
      N := 8
           * DP_Symbol_Rate (Link.Bandwidth)
           * Lane_Count_As_Integer (Link.Lane_Count);

      Cancel_M_N (M, N, DATA_N_MAX);
      Data_M := M;
      Data_N := N;

      -------------------------------------------------------------------

      M := Pos64 (Mode.Dotclock);
      N := Pos64 (DP_Symbol_Rate (Link.Bandwidth));

      Cancel_M_N (M, N, LINK_N_MAX);
      Link_M := M;
      Link_N := N;
   end Calculate_M_N;

   ----------------------------------------------------------------------------

   procedure Read_Link_Status
     (Port     : in     T;
      Status   :    out Link_Status;
      Success  :    out Boolean)
   is
      subtype Status_Index is DP_Defs.Aux_Payload_Index range 0 .. 5;
      subtype Status_Buffer is Buffer (Status_Index)
      with
         Object_Size => 48;
      function Buffer_As_Status is new Ada.Unchecked_Conversion
        (Source => Status_Buffer, Target => Link_Status);

      Data : DP_Defs.Aux_Payload;
      Length : DP_Defs.Aux_Payload_Length;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Length := Status_Index'Last + 1;
      Aux_Ch.Aux_Read
        (Port     => Port,
         Address  => 16#00202#,
         Length   => Length,
         Data     => Data,
         Success  => Success);
      Success := Success and Length = Status_Index'Last + 1;
      Status := Buffer_As_Status (Data (Status_Index));
   end Read_Link_Status;

   function All_CR_Done
     (Status   : Link_Status;
      Link     : DP_Link)
      return Boolean
   is
      CR_Done : Boolean := True;
   begin
      for Lane in Lane_Index
         range 0 .. Lane_Index (Lane_Count_As_Integer (Link.Lane_Count) - 1)
      loop
         CR_Done := CR_Done and Status.Lanes (Lane).CR_Done;
      end loop;
      return CR_Done;
   end All_CR_Done;

   function All_EQ_Done
     (Status   : Link_Status;
      Link     : DP_Link)
      return Boolean
   is
      EQ_Done : Boolean := True;
   begin
      for Lane in Lane_Index
         range 0 .. Lane_Index (Lane_Count_As_Integer (Link.Lane_Count) - 1)
      loop
         EQ_Done := EQ_Done and Status.Lanes (Lane).CR_Done
                            and Status.Lanes (Lane).Channel_EQ_Done
                            and Status.Lanes (Lane).Symbol_Locked;
      end loop;
      return EQ_Done and Status.Interlane_Align_Done;
   end All_EQ_Done;

   function Max_Requested_VS
     (Status   : Link_Status;
      Link     : DP_Link)
      return DP_Voltage_Swing
   is
      VS : DP_Voltage_Swing := DP_Voltage_Swing'First;
   begin
      for Lane in Lane_Index
         range 0 .. Lane_Index (Lane_Count_As_Integer (Link.Lane_Count) - 1)
      loop
         if Status.Adjust_Requests (Lane).Voltage_Swing > VS then
            VS := Status.Adjust_Requests (Lane).Voltage_Swing;
         end if;
      end loop;
      return VS;
   end Max_Requested_VS;

   function Max_Requested_Emph
     (Status   : Link_Status;
      Link     : DP_Link)
      return DP_Pre_Emph
   is
      Emph : DP_Pre_Emph := DP_Pre_Emph'First;
   begin
      for Lane in Lane_Index
         range 0 .. Lane_Index (Lane_Count_As_Integer (Link.Lane_Count) - 1)
      loop
         if Status.Adjust_Requests (Lane).Pre_Emph > Emph then
            Emph := Status.Adjust_Requests (Lane).Pre_Emph;
         end if;
      end loop;
      return Emph;
   end Max_Requested_Emph;

end HW.GFX.DP_Info;
