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

with HW.Debug;
with GNAT.Source_Info;

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

use type HW.Word8;

package body HW.GFX.GMA.I2C is

   PCH_DSPCLK_GATE_D_GMBUS_UNIT_LVL : constant :=   1 * 2 ** 31;

   function GMBUS0_PIN_PAIR_SELECT_MASK return Word32 is
      (if Config.Has_Type_C_Ports then 15 * 2 ** 0 else 7 * 2 ** 0);

   GMBUS0_GMBUS_RATE_SELECT_MASK    : constant :=   7 * 2 **  8;
   GMBUS0_GMBUS_RATE_SELECT_100KHZ  : constant :=   0 * 2 **  8;
   GMBUS0_GMBUS_RATE_SELECT_50KHZ   : constant :=   1 * 2 **  8;
   GMBUS0_PIN_PAIR_SELECT_NONE      : constant :=   0 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_DAC       : constant :=   2 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_LVDS      : constant :=   3 * 2 **  0;
   -- Order is C, B, D: no typo!
   GMBUS0_PIN_PAIR_SELECT_DIGI_C    : constant :=   4 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_DIGI_B    : constant :=   5 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_DIGI_D    : constant :=   6 * 2 **  0;
   -- Broxton and later use different pins
   GMBUS0_PIN_PAIR_SELECT_BXT_B     : constant :=   1 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_BXT_C     : constant :=   2 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_BXT_D     : constant :=   3 * 2 **  0;
   -- Tiger Lake and later use even different pins
   GMBUS0_PIN_PAIR_SELECT_TGL_1     : constant :=   1 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_TGL_2     : constant :=   2 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_TGL_3     : constant :=   3 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_TGL_TC1   : constant :=   9 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_TGL_TC2   : constant :=  10 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_TGL_TC3   : constant :=  11 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_TGL_TC4   : constant :=  12 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_TGL_TC5   : constant :=  13 * 2 **  0;
   GMBUS0_PIN_PAIR_SELECT_TGL_TC6   : constant :=  14 * 2 **  0;

   GMBUS1_SOFTWARE_CLEAR_INTERRUPT  : constant :=   1 * 2 ** 31;
   GMBUS1_SOFTWARE_READY            : constant :=   1 * 2 ** 30;
   GMBUS1_ENABLE_TIMEOUT            : constant :=   1 * 2 ** 29;
   GMBUS1_BUS_CYCLE_SELECT_MASK     : constant :=   7 * 2 ** 25;
   GMBUS1_BUS_CYCLE_STOP            : constant :=   1 * 2 ** 27;
   GMBUS1_BUS_CYCLE_INDEX           : constant :=   1 * 2 ** 26;
   GMBUS1_BUS_CYCLE_WAIT            : constant :=   1 * 2 ** 25;
   GMBUS1_TOTAL_BYTE_COUNT_MASK     : constant := 511 * 2 ** 16;
   GMBUS1_TOTAL_BYTE_COUNT_SHIFT    : constant :=            16;
   GMBUS1_8BIT_SLAVE_INDEX_MASK     : constant := 255 * 2 **  8;
   GMBUS1_8BIT_SLAVE_INDEX_SHIFT    : constant :=             8;
   GMBUS1_SLAVE_ADDRESS_MASK        : constant := 127 * 2 **  1;
   GMBUS1_SLAVE_ADDRESS_SHIFT       : constant :=             1;
   GMBUS1_DIRECTION_MASK            : constant :=   1 * 2 **  0;
   GMBUS1_DIRECTION_WRITE           : constant :=   0 * 2 **  0;
   GMBUS1_DIRECTION_READ            : constant :=   1 * 2 **  0;

   GMBUS2_INUSE                     : constant :=   1 * 2 ** 15;
   GMBUS2_HARDWARE_WAIT_PHASE       : constant :=   1 * 2 ** 14;
   GMBUS2_SLAVE_STALL_TIMEOUT_ERROR : constant :=   1 * 2 ** 13;
   GMBUS2_GMBUS_INTERRUPT_STATUS    : constant :=   1 * 2 ** 12;
   GMBUS2_HARDWARE_READY            : constant :=   1 * 2 ** 11;
   GMBUS2_NAK_INDICATOR             : constant :=   1 * 2 ** 10;
   GMBUS2_GMBUS_ACTIVE              : constant :=   1 * 2 **  9;
   GMBUS2_CURRENT_BYTE_COUNT_MASK   : constant := 511 * 2 **  0;

   GMBUS4_INTERRUPT_MASK            : constant :=  31 * 2 **  0;

   GMBUS5_2BYTE_INDEX_ENABLE        : constant :=   1 * 2 ** 31;

   GMBUS_Regs : constant array (0 .. 5) of Registers.Registers_Index :=
     (if Config.Has_PCH_GMBUS then
        (0 => Registers.PCH_GMBUS0,
         1 => Registers.PCH_GMBUS1,
         2 => Registers.PCH_GMBUS2,
         3 => Registers.PCH_GMBUS3,
         4 => Registers.PCH_GMBUS4,
         5 => Registers.PCH_GMBUS5)
      else
        (0 => Registers.GMCH_GMBUS0,
         1 => Registers.GMCH_GMBUS1,
         2 => Registers.GMCH_GMBUS2,
         3 => Registers.GMCH_GMBUS3,
         4 => Registers.GMCH_GMBUS4,
         5 => Registers.GMCH_GMBUS5));

   function GMBUS1_TOTAL_BYTE_COUNT
     (Count : HW.GFX.I2C.Transfer_Length)
      return Word32 is
   begin
      return Shift_Left (Word32 (Count), GMBUS1_TOTAL_BYTE_COUNT_SHIFT);
   end GMBUS1_TOTAL_BYTE_COUNT;

   function GMBUS1_SLAVE_ADDRESS
     (Address : HW.GFX.I2C.Transfer_Address)
      return Word32 is
   begin
      return Shift_Left (Word32 (Address), GMBUS1_SLAVE_ADDRESS_SHIFT);
   end GMBUS1_SLAVE_ADDRESS;

   function GMBUS0_PIN_PAIR_SELECT (Port : PCH_Port) return Word32 is
   begin
      return
        (if Config.Has_Type_C_Ports then
	   (case Port is
	       when PCH_HDMI_A   => GMBUS0_PIN_PAIR_SELECT_TGL_1,
	       when PCH_HDMI_B   => GMBUS0_PIN_PAIR_SELECT_TGL_2,
	       when PCH_HDMI_C   => GMBUS0_PIN_PAIR_SELECT_TGL_3,
	       when PCH_TC1      => GMBUS0_PIN_PAIR_SELECT_TGL_TC1,
	       when PCH_TC2      => GMBUS0_PIN_PAIR_SELECT_TGL_TC2,
	       when PCH_TC3      => GMBUS0_PIN_PAIR_SELECT_TGL_TC3,
	       when PCH_TC4      => GMBUS0_PIN_PAIR_SELECT_TGL_TC4,
	       when PCH_TC5      => GMBUS0_PIN_PAIR_SELECT_TGL_TC5,
	       when PCH_TC6      => GMBUS0_PIN_PAIR_SELECT_TGL_TC6,
	       when others       => GMBUS0_PIN_PAIR_SELECT_NONE)
        elsif Config.GMBUS_Alternative_Pins then
           (case Port is
               when PCH_HDMI_B   => GMBUS0_PIN_PAIR_SELECT_BXT_B,
               when PCH_HDMI_C   => GMBUS0_PIN_PAIR_SELECT_BXT_C,
               when PCH_HDMI_D   => GMBUS0_PIN_PAIR_SELECT_BXT_D,
               when others       => GMBUS0_PIN_PAIR_SELECT_NONE)
         else
           (case Port is
               when PCH_DAC      => GMBUS0_PIN_PAIR_SELECT_DAC,
               when PCH_LVDS     => GMBUS0_PIN_PAIR_SELECT_LVDS,
               when PCH_HDMI_B   => GMBUS0_PIN_PAIR_SELECT_DIGI_B,
               when PCH_HDMI_C   => GMBUS0_PIN_PAIR_SELECT_DIGI_C,
               when PCH_HDMI_D   => GMBUS0_PIN_PAIR_SELECT_DIGI_D,
               when others       => GMBUS0_PIN_PAIR_SELECT_NONE));
   end GMBUS0_PIN_PAIR_SELECT;

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

   function GMBUS_Ready (GMBUS2 : Word32) return Boolean is
     ((GMBUS2 and (GMBUS2_HARDWARE_WAIT_PHASE or
                   GMBUS2_SLAVE_STALL_TIMEOUT_ERROR or
                   GMBUS2_GMBUS_INTERRUPT_STATUS or
                   GMBUS2_NAK_INDICATOR or
                   GMBUS2_GMBUS_ACTIVE)) = 0);

   procedure Check_And_Reset (Success : out Boolean)
   is
      GMBUS2 : Word32;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Registers.Read (GMBUS_Regs (2), GMBUS2);
      if (GMBUS2 and GMBUS2_GMBUS_ACTIVE) /= 0 then
         Registers.Write
           (Register => GMBUS_Regs (1),
            Value    => GMBUS1_SOFTWARE_READY or GMBUS1_BUS_CYCLE_STOP);
         Registers.Wait_Unset_Mask
           (Register => GMBUS_Regs (2),
            Mask     => GMBUS2_GMBUS_ACTIVE,
            TOut_MS  => 1);
         Registers.Read (GMBUS_Regs (2), GMBUS2);
      end if;
      Success := GMBUS_Ready (GMBUS2);

      if not Success then
         Registers.Write (GMBUS_Regs (1), GMBUS1_SOFTWARE_CLEAR_INTERRUPT);
         Registers.Write (GMBUS_Regs (1), 0);
         Registers.Read (GMBUS_Regs (2), GMBUS2);
         Success := GMBUS_Ready (GMBUS2);
      end if;
   end Check_And_Reset;

   procedure Init_GMBUS (Port : PCH_Port; Success : out Boolean) is
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      if Config.Ungate_GMBUS_Unit_Level then
         Registers.Set_Mask
           (Register => Registers.PCH_DSPCLK_GATE_D,
            Mask     => PCH_DSPCLK_GATE_D_GMBUS_UNIT_LVL);
      end if;

      -- TODO: Refactor + check for timeout.
      Registers.Wait_Unset_Mask (GMBUS_Regs (2), GMBUS2_INUSE);

      Registers.Write (GMBUS_Regs (4), 0);
      Registers.Write (GMBUS_Regs (5), 0);

      -- Resetting the state machine only works if a valid port
      -- is selected and we don't always know which ports are
      -- valid. So do the cleanup before we use the GMBUS with
      -- the current port. If the port is valid, the reset should
      -- work, if not, it shouldn't matter.
      Registers.Write
        (Register => GMBUS_Regs (0),
         Value    => GMBUS0_GMBUS_RATE_SELECT_100KHZ or
                     GMBUS0_PIN_PAIR_SELECT (Port));
      Check_And_Reset (Success);
   end Init_GMBUS;

   procedure Release_GMBUS
   is
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Registers.Write (GMBUS_Regs (0), GMBUS0_PIN_PAIR_SELECT_NONE);

      -- Clear INUSE. TODO: Don't do it, if timeout occured (see above).
      Registers.Write (GMBUS_Regs (2), GMBUS2_INUSE);

      if Config.Ungate_GMBUS_Unit_Level then
         Registers.Unset_Mask
           (Register => Registers.PCH_DSPCLK_GATE_D,
            Mask     => PCH_DSPCLK_GATE_D_GMBUS_UNIT_LVL);
      end if;
   end Release_GMBUS;

   procedure I2C_Read
     (Port     : in     PCH_Port;
      Address  : in     HW.GFX.I2C.Transfer_Address;
      Length   : in out HW.GFX.I2C.Transfer_Length;
      Data     :    out HW.GFX.I2C.Transfer_Data;
      Success  :    out Boolean)
   is
      GMBUS2 : Word32 := 0;
      GMBUS3 : Word32;

      Current     : HW.GFX.I2C.Transfer_Length;
      Transfered  : HW.GFX.I2C.Transfer_Length := 0;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      Data := (others => 0);

      Init_GMBUS (Port, Success);
      if Success then
         Registers.Write
           (Register => GMBUS_Regs (1),
            Value    => GMBUS1_SOFTWARE_READY or
                        GMBUS1_BUS_CYCLE_INDEX or
                        GMBUS1_BUS_CYCLE_WAIT or
                        GMBUS1_TOTAL_BYTE_COUNT (Length) or
                        GMBUS1_SLAVE_ADDRESS (Address) or
                        GMBUS1_DIRECTION_READ);

         while Success and then Transfered < Length loop
	    -- Some GMBUS state machines never set HW_RDY nor NAK.
	    --
	    -- Keep delay at a minimum, but big enough that
	    -- regular EDID transfers can be finished within
	    -- the timeout.
            Registers.Wait_Set_Mask
              (Register => GMBUS_Regs (2),
               Mask     => GMBUS2_HARDWARE_READY,
               TOut_MS  => 50);

            Registers.Read (GMBUS_Regs (2), GMBUS2);
            Success :=  (GMBUS2 and GMBUS2_HARDWARE_READY) /= 0 and
                        (GMBUS2 and GMBUS2_NAK_INDICATOR) = 0;
            if Success then
               Current := GFX.I2C.Transfer_Length'Min (Length, Transfered + 4);

               Registers.Read (GMBUS_Regs (3), GMBUS3);
               for I in Transfered .. Current - 1 loop
                  Data (I) := Byte (GMBUS3 and 16#ff#);
                  GMBUS3 := Shift_Right (GMBUS3, 8);
               end loop;
               Transfered := Current;
            end if;
         end loop;
         if Success then
            Registers.Wait_Set_Mask
              (Register => GMBUS_Regs (2),
               Mask     => GMBUS2_HARDWARE_WAIT_PHASE);
            Registers.Write
              (Register => GMBUS_Regs (1),
               Value    => GMBUS1_SOFTWARE_READY or GMBUS1_BUS_CYCLE_STOP);
            Registers.Wait_Unset_Mask
              (Register => GMBUS_Regs (2),
               Mask     => GMBUS2_GMBUS_ACTIVE);
         elsif (GMBUS2 and GMBUS2_NAK_INDICATOR) /= 0 then
            Registers.Wait_Unset_Mask
              (Register => GMBUS_Regs (2),
               Mask     => GMBUS2_GMBUS_ACTIVE);
            Registers.Write (GMBUS_Regs (1), GMBUS1_SOFTWARE_CLEAR_INTERRUPT);
            Registers.Write (GMBUS_Regs (1), 0);
         end if;
      end if;
      Length := Transfered;

      Release_GMBUS;
   end I2C_Read;

end HW.GFX.GMA.I2C;
