--
-- Copyright (C) 2015-2016 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 HW.Time;

with HW.Debug;
with GNAT.Source_Info;

with HW.GFX.GMA.Config;
with HW.GFX.GMA.Registers;

use type HW.Word8;
use type HW.GFX.GMA.Registers.Registers_Invalid_Index;

package body HW.GFX.GMA.DP_Aux_Request is

   DP_AUX_CTL_SEND_BUSY             : constant :=    1 * 2 ** 31;
   DP_AUX_CTL_DONE                  : constant :=    1 * 2 ** 30;
   DP_AUX_CTL_INTERRUPT_ON_DONE     : constant :=    1 * 2 ** 29;
   DP_AUX_CTL_TIME_OUT_ERROR        : constant :=    1 * 2 ** 28;
   DP_AUX_CTL_TIME_OUT_TIMER_MASK   : constant :=    3 * 2 ** 26;
   DP_AUX_CTL_TIME_OUT_TIMER_400US  : constant :=    0 * 2 ** 26;
   DP_AUX_CTL_TIME_OUT_TIMER_600US  : constant :=    1 * 2 ** 26;
   DP_AUX_CTL_TIME_OUT_TIMER_800US  : constant :=    2 * 2 ** 26;
   DP_AUX_CTL_TIME_OUT_TIMER_1600US : constant :=    3 * 2 ** 26;
   DP_AUX_CTL_RECEIVE_ERROR         : constant :=    1 * 2 ** 25;
   DP_AUX_CTL_MESSAGE_SIZE_MASK     : constant :=   31 * 2 ** 20;
   DP_AUX_CTL_MESSAGE_SIZE_SHIFT    : constant :=        2 ** 20;
   DP_AUX_CTL_PRECHARGE_TIME_MASK   : constant :=   15 * 2 ** 16;
   DP_AUX_CTL_PRECHARGE_TIME_SHIFT  : constant :=        2 ** 16;
   DP_AUX_CTL_2X_BIT_CLOCK_DIV_MASK : constant := 2047 * 2 **  0;
   -- TODO: HSW/BDW with LPT-H might need a workaround for the 2x bit clock.

   subtype DP_AUX_CTL_MESSAGE_SIZE_T is Natural range 1 .. 20;
   function DP_AUX_CTL_MESSAGE_SIZE
     (Message_Length : DP_AUX_CTL_MESSAGE_SIZE_T)
      return Word32;

   DDI_AUX_MUTEX_MUTEX_ENABLE : constant := 1 * 2 ** 31;
   DDI_AUX_MUTEX_MUTEX_STATUS : constant := 1 * 2 ** 30;

   type AUX_CH_Data_Regs is new Positive range 1 .. 5;

   type AUX_CH_Data_Regs_Array is
      array (AUX_CH_Data_Regs) of Registers.Registers_Index;

   type AUX_CH_Registers is record
      CTL   : Registers.Registers_Index;
      DATA  : AUX_CH_Data_Regs_Array;
      MUTEX : Registers.Registers_Invalid_Index;
   end record;

   type AUX_CH_Registers_Array is array (DP_Port) of AUX_CH_Registers;

   AUX_CH : constant AUX_CH_Registers_Array :=
     (if Config.Has_PCH_Aux_Channels then
         AUX_CH_Registers_Array'
        (DP_A => AUX_CH_Registers'
           (CTL   => Registers.DP_AUX_CTL_A,
            DATA  => AUX_CH_Data_Regs_Array'
              (1  => Registers.DP_AUX_DATA_A_1,
               2  => Registers.DP_AUX_DATA_A_2,
               3  => Registers.DP_AUX_DATA_A_3,
               4  => Registers.DP_AUX_DATA_A_4,
               5  => Registers.DP_AUX_DATA_A_5),
            MUTEX => Registers.Invalid_Register),
         DP_B => AUX_CH_Registers'
           (CTL   => Registers.PCH_DP_AUX_CTL_B,
            DATA  => AUX_CH_Data_Regs_Array'
              (1  => Registers.PCH_DP_AUX_DATA_B_1,
               2  => Registers.PCH_DP_AUX_DATA_B_2,
               3  => Registers.PCH_DP_AUX_DATA_B_3,
               4  => Registers.PCH_DP_AUX_DATA_B_4,
               5  => Registers.PCH_DP_AUX_DATA_B_5),
            MUTEX => Registers.Invalid_Register),
         DP_C => AUX_CH_Registers'
           (CTL   => Registers.PCH_DP_AUX_CTL_C,
            DATA  => AUX_CH_Data_Regs_Array'
              (1  => Registers.PCH_DP_AUX_DATA_C_1,
               2  => Registers.PCH_DP_AUX_DATA_C_2,
               3  => Registers.PCH_DP_AUX_DATA_C_3,
               4  => Registers.PCH_DP_AUX_DATA_C_4,
               5  => Registers.PCH_DP_AUX_DATA_C_5),
            MUTEX => Registers.Invalid_Register),
         DP_D => AUX_CH_Registers'
           (CTL   => Registers.PCH_DP_AUX_CTL_D,
            DATA  => AUX_CH_Data_Regs_Array'
              (1  => Registers.PCH_DP_AUX_DATA_D_1,
               2  => Registers.PCH_DP_AUX_DATA_D_2,
               3  => Registers.PCH_DP_AUX_DATA_D_3,
               4  => Registers.PCH_DP_AUX_DATA_D_4,
               5  => Registers.PCH_DP_AUX_DATA_D_5),
            MUTEX => Registers.Invalid_Register))
      else
         AUX_CH_Registers_Array'
        (DP_A => AUX_CH_Registers'
           (CTL   => Registers.DDI_AUX_CTL_A,
            DATA  => AUX_CH_Data_Regs_Array'
              (1  => Registers.DDI_AUX_DATA_A_1,
               2  => Registers.DDI_AUX_DATA_A_2,
               3  => Registers.DDI_AUX_DATA_A_3,
               4  => Registers.DDI_AUX_DATA_A_4,
               5  => Registers.DDI_AUX_DATA_A_5),
            MUTEX => Registers.DDI_AUX_MUTEX_A),
         DP_B => AUX_CH_Registers'
           (CTL   => Registers.DDI_AUX_CTL_B,
            DATA  => AUX_CH_Data_Regs_Array'
              (1  => Registers.DDI_AUX_DATA_B_1,
               2  => Registers.DDI_AUX_DATA_B_2,
               3  => Registers.DDI_AUX_DATA_B_3,
               4  => Registers.DDI_AUX_DATA_B_4,
               5  => Registers.DDI_AUX_DATA_B_5),
            MUTEX => Registers.DDI_AUX_MUTEX_B),
         DP_C => AUX_CH_Registers'
           (CTL   => Registers.DDI_AUX_CTL_C,
            DATA  => AUX_CH_Data_Regs_Array'
              (1  => Registers.DDI_AUX_DATA_C_1,
               2  => Registers.DDI_AUX_DATA_C_2,
               3  => Registers.DDI_AUX_DATA_C_3,
               4  => Registers.DDI_AUX_DATA_C_4,
               5  => Registers.DDI_AUX_DATA_C_5),
            MUTEX => Registers.DDI_AUX_MUTEX_C),
         DP_D => AUX_CH_Registers'
           (CTL   => Registers.DDI_AUX_CTL_D,
            DATA  => AUX_CH_Data_Regs_Array'
              (1  => Registers.DDI_AUX_DATA_D_1,
               2  => Registers.DDI_AUX_DATA_D_2,
               3  => Registers.DDI_AUX_DATA_D_3,
               4  => Registers.DDI_AUX_DATA_D_4,
               5  => Registers.DDI_AUX_DATA_D_5),
            MUTEX => Registers.DDI_AUX_MUTEX_D)));

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

   function DP_AUX_CTL_MESSAGE_SIZE
     (Message_Length : DP_AUX_CTL_MESSAGE_SIZE_T)
      return Word32
   is
   begin
      return Word32 (Message_Length) * DP_AUX_CTL_MESSAGE_SIZE_SHIFT;
   end DP_AUX_CTL_MESSAGE_SIZE;

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

   procedure Aux_Request_Low
     (Port              : in     DP_Port;
      Request           : in     DP_Defs.Aux_Request;
      Request_Length    : in     DP_Defs.Aux_Request_Length;
      Response          :    out DP_Defs.Aux_Response;
      Response_Length   :    out DP_Defs.Aux_Response_Length;
      Success           :    out Boolean)
   with
      Global => (In_Out => Registers.Register_State,
                 Input  => Time.State),
      Depends =>
        ((Registers.Register_State,
          Response,
          Response_Length,
          Success)
             =>
               (Registers.Register_State,
                Time.State,
                Port,
                Request,
                Request_Length))
   is
      procedure Write_Data_Reg
        (Register : in     Registers.Registers_Index;
         Buf      : in     DP_Defs.Aux_Request;
         Length   : in     DP_Defs.Aux_Request_Length;
         Offset   : in     DP_Defs.Aux_Request_Index)
      is
         Value : Word32;
         Count : Natural;
      begin
         if Offset < Length then
            if Length - Offset > 4 then
               Count := 4;
            else
               Count := Length - Offset;
            end if;

            Value := 0;
            for Idx in DP_Defs.Aux_Request_Index range 0 .. Count - 1 loop
               Value := Value or
                  Shift_Left (Word32 (Buf (Offset + Idx)), (3 - Idx) * 8);
            end loop;
            Registers.Write (Register => Register, Value => Value);
         end if;
      end Write_Data_Reg;

      procedure Read_Data_Reg
        (Register : in     Registers.Registers_Index;
         Buf      : in out DP_Defs.Aux_Response;
         Length   : in     DP_Defs.Aux_Response_Length;
         Offset   : in     DP_Defs.Aux_Response_Index)
      is
         Value : Word32;
         Count : DP_Defs.Aux_Response_Length;
      begin
         if Offset < Length then
            if Length - Offset > 4 then
               Count := 4;
            else
               Count := Length - Offset;
            end if;

            Registers.Read (Register => Register, Value => Value);
            for Idx in 0 .. Count - 1 loop
               Buf (Offset + Idx) :=
                  Word8 (Shift_Right (Value, (3 - Idx) * 8) and 16#ff#);
            end loop;
         end if;
      end Read_Data_Reg;

      DP_AUX_CTL_2x_Clock_Mask : constant :=
        (if Config.Has_PCH_Aux_Channels then
            DP_AUX_CTL_2X_BIT_CLOCK_DIV_MASK else 0);
      DP_AUX_CTL_2x_Clock : constant Word32 :=
        (if Config.Has_PCH_Aux_Channels then
           (if Port = DP_A then
               Word32 ((Config.Default_CDClk_Freq + 1_000_000) / 2_000_000)
            else
               Word32 ((Config.Default_RawClk_Freq + 1_000_000) / 2_000_000))
         else 0);

      Busy : Boolean;
      Status : Word32;
   begin
      Response := (others => 0); -- Don't care
      Response_Length := DP_Defs.Aux_Response_Length'First;

      if Config.Need_DP_Aux_Mutex then
         Registers.Set_Mask
           (Register => AUX_CH (Port).MUTEX,
            Mask     => DDI_AUX_MUTEX_MUTEX_ENABLE);
         Registers.Wait_Set_Mask
           (Register => AUX_CH (Port).MUTEX,
            Mask     => DDI_AUX_MUTEX_MUTEX_STATUS);
      end if;

      Registers.Is_Set_Mask
        (Register => AUX_CH (Port).CTL,
         Mask     => DP_AUX_CTL_SEND_BUSY,
         Result   => Busy);
      if Busy then
         Success := False;
      else
         for Idx in AUX_CH_Data_Regs loop
            Write_Data_Reg
              (Register => AUX_CH (Port).DATA (Idx),
               Buf      => Request,
               Length   => Request_Length,
               Offset   => (Natural (Idx) - 1) * 4);
         end loop;

         Registers.Unset_And_Set_Mask
           (Register    => AUX_CH (Port).CTL,
            Mask_Unset  => DP_AUX_CTL_INTERRUPT_ON_DONE or
                           DP_AUX_CTL_TIME_OUT_TIMER_MASK or
                           DP_AUX_CTL_MESSAGE_SIZE_MASK or
                           DP_AUX_CTL_2x_Clock_Mask,
            Mask_Set    => DP_AUX_CTL_SEND_BUSY or          -- starts transfer
                           DP_AUX_CTL_DONE or               -- clears the status
                           DP_AUX_CTL_TIME_OUT_ERROR or     -- clears the status
                           DP_AUX_CTL_RECEIVE_ERROR or      -- clears the status
                           DP_AUX_CTL_TIME_OUT_TIMER_600US or
                           DP_AUX_CTL_MESSAGE_SIZE (Request_Length) or
                           DP_AUX_CTL_2x_Clock);

         Registers.Wait_Unset_Mask
           (Register => AUX_CH (Port).CTL,
            Mask     => DP_AUX_CTL_SEND_BUSY);
         Registers.Read (Register => AUX_CH (Port).CTL, Value => Status);
         Success := (Status and
                     (DP_AUX_CTL_TIME_OUT_ERROR or DP_AUX_CTL_RECEIVE_ERROR))
                    = 0;

         if Success then
            Status := (Status and DP_AUX_CTL_MESSAGE_SIZE_MASK)
                      / DP_AUX_CTL_MESSAGE_SIZE_SHIFT;
            if Natural (Status) < DP_Defs.Aux_Response_Length'First then
               Success := False;
            elsif Natural (Status) > DP_Defs.Aux_Response_Length'Last then
               Response_Length := DP_Defs.Aux_Response_Length'Last;
            else
               Response_Length := Natural (Status);
            end if;
         end if;

         if Success then
            for Idx in AUX_CH_Data_Regs loop
               Read_Data_Reg
                 (Register => AUX_CH (Port).DATA (Idx),
                  Buf      => Response,
                  Length   => Response_Length,
                  Offset   => (Natural (Idx) - 1) * 4);
            end loop;
         end if;
      end if;

      if Config.Need_DP_Aux_Mutex then
         Registers.Unset_And_Set_Mask
           (Register    => AUX_CH (Port).MUTEX,
            Mask_Unset  => DDI_AUX_MUTEX_MUTEX_ENABLE,
            Mask_Set    => DDI_AUX_MUTEX_MUTEX_STATUS);  -- frees the mutex
      end if;
   end Aux_Request_Low;

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

   procedure Do_Aux_Request
     (Port              : in     DP_Port;
      Request           : in     DP_Defs.Aux_Request;
      Request_Length    : in     DP_Defs.Aux_Request_Length;
      Response          :    out DP_Defs.Aux_Response;
      Response_Length   :    out DP_Defs.Aux_Response_Length;
      Success           :    out Boolean)
   is
   begin
      for Try in Positive range 1 .. 3 loop
         Aux_Request_Low
           (Port              => Port,
            Request           => Request,
            Request_Length    => Request_Length,
            Response          => Response,
            Response_Length   => Response_Length,
            Success           => Success);
         exit when Success;
      end loop;
   end Do_Aux_Request;

end HW.GFX.GMA.DP_Aux_Request;
