--
-- 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;
with HW.GFX.GMA.Power_And_Clocks;

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, Config.Variable)),
      Depends =>
        ((Registers.Register_State,
          Response,
          Response_Length,
          Success)
             =>
               (Registers.Register_State,
                Config.Variable,
                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.CDClk + 1_000_000) / 2_000_000)
            else
               Word32 ((Config.Raw_Clock + 1_000_000) / 2_000_000))
         elsif Config.Has_GMCH_RawClk then
            Word32 (Div_Round_Closest (Config.Raw_Clock, 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;
