--
-- Copyright (C) 2015-2018 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.Debug;
with GNAT.Source_Info;

with HW.GFX.GMA.Config_Helpers;
with HW.GFX.GMA.DP_Info;

package body HW.GFX.GMA.Transcoder is

   type Default_Transcoder_Array is array (Pipe_Index) of Transcoder_Index;
   Default_Transcoder : constant Default_Transcoder_Array :=
     (Primary     => Trans_A,
      Secondary   => Trans_B,
      Tertiary    => Trans_C);

   function Get_Idx (Pipe : Pipe_Index; Port : GPU_Port) return Transcoder_Index
   is
   begin
      return
        (if Config.Has_EDP_Transcoder and then Port = DIGI_A then
            Trans_EDP
         else
            Default_Transcoder (Pipe));
   end Get_Idx;

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

   TRANS_CLK_SEL_PORT_NONE : constant := 0 * 2 ** 29;
   TRANS_CLK_SEL_MASK : constant := 16#f000_0000#;

   type TRANS_CLK_SEL_PORT_Array is
      array (Digital_Port) of Word32;
   TRANS_CLK_SEL_PORT : constant TRANS_CLK_SEL_PORT_Array :=
     (DIGI_A => 0 * 2 ** 29,   -- DDI A is not selectable
      DIGI_B => 2 * 2 ** 29,
      DIGI_C => 3 * 2 ** 29,
      DIGI_D => 4 * 2 ** 29,
      DIGI_E => 5 * 2 ** 29);

   function TGL_TRANS_CLK_SEL_PORT (Port : TGL_Digital_Port) return Word32
   is
     (case Port is
         when DIGI_A  => 1 * 2 ** 28,
         when DIGI_B  => 2 * 2 ** 28,
         when DIGI_C  => 3 * 2 ** 28,
         when DDI_TC1 => 4 * 2 ** 28,
         when DDI_TC2 => 5 * 2 ** 28,
         when DDI_TC3 => 6 * 2 ** 28,
         when DDI_TC4 => 7 * 2 ** 28,
         when DDI_TC5 => 8 * 2 ** 28,
         when DDI_TC6 => 9 * 2 ** 28,
         when others  => 0);

   function XELPD_TRANS_CLK_SEL_PORT (Port : XELPD_Digital_Port) return Word32
   is
     (case Port is
         when DIGI_A  => 1 * 2 ** 28,
         when DIGI_B  => 2 * 2 ** 28,
         when DIGI_C  => 3 * 2 ** 28,
         when DIGI_D  => 4 * 2 ** 28,
         when DIGI_E  => 5 * 2 ** 28,
         when DDI_TC1 => 6 * 2 ** 28,
         when DDI_TC2 => 7 * 2 ** 28,
         when DDI_TC3 => 8 * 2 ** 28,
         when DDI_TC4 => 9 * 2 ** 28);

   TRANS_CONF_ENABLE          : constant := 1 * 2 ** 31;
   TRANS_CONF_ENABLED_STATUS  : constant := 1 * 2 ** 30;
   TRANS_CONF_ENABLE_DITHER   : constant := 1 * 2 **  4;

   type BPC_Array is array (BPC_Type) of Word32;
   TRANS_CONF_BPC : constant BPC_Array :=
     (6        => 2 * 2 ** 5,
      8        => 0 * 2 ** 5,
      10       => 1 * 2 ** 5,
      12       => 3 * 2 ** 5,
      others   => 0 * 2 ** 5);   -- default to 8 BPC

   function BPC_Conf (BPC : BPC_Type; Dither : Boolean) return Word32 is
   begin
      return
        (if Config.Has_Pipeconf_BPC then TRANS_CONF_BPC (BPC) else 0) or
        (if Dither                  then TRANS_CONF_ENABLE_DITHER else 0);
   end BPC_Conf;

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

   DDI_FUNC_CTL_ENABLE                 : constant := 1 * 2 ** 31;
   DDI_FUNC_CTL_MODE_SELECT_MASK       : constant := 7 * 2 ** 24;
   DDI_FUNC_CTL_MODE_SELECT_HDMI       : constant := 0 * 2 ** 24;
   DDI_FUNC_CTL_MODE_SELECT_DVI        : constant := 1 * 2 ** 24;
   DDI_FUNC_CTL_MODE_SELECT_DP_SST     : constant := 2 * 2 ** 24;
   DDI_FUNC_CTL_MODE_SELECT_DP_MST     : constant := 3 * 2 ** 24;
   DDI_FUNC_CTL_MODE_SELECT_FDI        : constant := 4 * 2 ** 24;

   type DDI_Select_Array is array (Digital_Port) of Word32;
   DDI_FUNC_CTL_DDI_SELECT : constant DDI_Select_Array :=
     (DIGI_A => 0 * 2 ** 28,
      DIGI_B => 1 * 2 ** 28,
      DIGI_C => 2 * 2 ** 28,
      DIGI_D => 3 * 2 ** 28,
      DIGI_E => 4 * 2 ** 28);

   function TGL_DDI_FUNC_CTL_DDI_SELECT (Port : DDI_Port) return Word32
   is
     (case Port is
         when DIGI_A  => 1 * 2 ** 27,
         when DIGI_B  => 2 * 2 ** 27,
         when DIGI_C  => 3 * 2 ** 27,
         when DIGI_D  => 8 * 2 ** 27,  -- n/a on TGL, repositioned since ADL-P
         when DIGI_E  => 9 * 2 ** 27,  -- n/a on TGL, repositioned since ADL-P
         when DDI_TC1 => 4 * 2 ** 27,
         when DDI_TC2 => 5 * 2 ** 27,
         when DDI_TC3 => 6 * 2 ** 27,
         when DDI_TC4 => 7 * 2 ** 27,
         when DDI_TC5 => 8 * 2 ** 27,
         when DDI_TC6 => 9 * 2 ** 27);

   type DDI_Mode_Array is array (Display_Type) of Word32;
   DDI_FUNC_CTL_MODE_SELECT : constant DDI_Mode_Array :=
     (VGA      => DDI_FUNC_CTL_MODE_SELECT_FDI,
      HDMI     => DDI_FUNC_CTL_MODE_SELECT_DVI,
      DP       => DDI_FUNC_CTL_MODE_SELECT_DP_SST,
      others   => 0);

   type HV_Sync_Array is array (Boolean) of Word32;
   DDI_FUNC_CTL_VSYNC : constant HV_Sync_Array :=
     (False => 0 * 2 ** 17,
      True  => 1 * 2 ** 17);
   DDI_FUNC_CTL_HSYNC : constant HV_Sync_Array :=
     (False => 0 * 2 ** 16,
      True  => 1 * 2 ** 16);

   DDI_FUNC_CTL_EDP_SELECT_MASK        : constant := 7 * 2 ** 12;
   DDI_FUNC_CTL_EDP_SELECT_ALWAYS_ON   : constant := 0 * 2 ** 12;
   DDI_FUNC_CTL_EDP_SELECT : constant array (Pipe_Index) of Word32 :=
     (Primary     => 4 * 2 ** 12,
      Secondary   => 5 * 2 ** 12,
      Tertiary    => 6 * 2 ** 12);

   type Port_Width_Array is array (DP_Lane_Count) of Word32;
   DDI_FUNC_CTL_PORT_WIDTH : constant Port_Width_Array :=
     (DP_Lane_Count_1 => 0 * 2 ** 1,
      DP_Lane_Count_2 => 1 * 2 ** 1,
      DP_Lane_Count_4 => 3 * 2 ** 1);

   DDI_FUNC_CTL_BPC : constant BPC_Array :=
     (6        => 2 * 2 ** 20,
      8        => 0 * 2 ** 20,
      10       => 1 * 2 ** 20,
      12       => 3 * 2 ** 20,
      others   => 0 * 2 ** 20);  -- default to 8 BPC

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

   TRANS_MSA_MISC_SYNC_CLK : constant := 1 * 2 ** 0;
   TRANS_MSA_MISC_BPC      : constant BPC_Array :=
     (6        => 0 * 2 ** 5,
      8        => 1 * 2 ** 5,
      10       => 2 * 2 ** 5,
      12       => 3 * 2 ** 5,
      16       => 4 * 2 ** 5,
      others   => 1 * 2 ** 5);   -- default to 8 BPC

   function TRANS_DATA_M_TU (Transfer_Unit : Positive) return Word32 is
   begin
      return Shift_Left (Word32 (Transfer_Unit - 1), 25);
   end TRANS_DATA_M_TU;

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

   function Encode (LSW, MSW : Pos32) return Word32 is
   begin
      return Shift_Left (Word32 (MSW - 1), 16) or Word32 (LSW - 1);
   end Encode;

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

   procedure Setup_Link
     (Trans : Transcoder_Regs;
      Link  : DP_Link;
      Mode  : Mode_Type)
   with
      Global => (In_Out => Registers.Register_State),
      Depends => (Registers.Register_State =>+ (Trans, Link, Mode))
   is
      Data_M, Link_M : DP_Info.M_Type;
      Data_N, Link_N : DP_Info.N_Type;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      DP_Info.Calculate_M_N
        (Link     => Link,
         Mode     => Mode,
         Data_M   => Data_M,
         Data_N   => Data_N,
         Link_M   => Link_M,
         Link_N   => Link_N);

      Registers.Write
        (Register => Trans.DATA_M1,
         Value    => TRANS_DATA_M_TU (64) or
                     Word32 (Data_M));
      Registers.Write
        (Register => Trans.DATA_N1,
         Value    => Word32 (Data_N));

      Registers.Write
        (Register => Trans.LINK_M1,
         Value    => Word32 (Link_M));
      Registers.Write
        (Register => Trans.LINK_N1,
         Value    => Word32 (Link_N));

      if Config.Has_Pipe_MSA_Misc then
         Registers.Write
           (Register => Trans.MSA_MISC,
            Value    => TRANS_MSA_MISC_SYNC_CLK or
                        TRANS_MSA_MISC_BPC (Mode.BPC));
      end if;
   end Setup_Link;

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

   procedure Setup
     (Pipe     : Pipe_Index;
      Port_Cfg : Port_Config)
   is
      use type HW.GFX.GMA.Registers.Registers_Invalid_Index;

      Trans : Transcoder_Regs renames
               Transcoders (Get_Idx (Pipe, Port_Cfg.Port));
      M : constant Mode_Type := Port_Cfg.Mode;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      if Config.Has_Trans_Clk_Sel and then
         not Config.Need_Early_Transcoder_Setup and then
         Trans.CLK_SEL /= Registers.Invalid_Register and then
         Port_Cfg.Port in Digital_Port
      then
         Registers.Write
           (Register => Trans.CLK_SEL,
            Value    => TRANS_CLK_SEL_PORT (Port_Cfg.Port));
      end if;

      if Port_Cfg.Is_FDI then
         Setup_Link (Trans, Port_Cfg.FDI, Port_Cfg.Mode);
      elsif Port_Cfg.Display = DP then
         Setup_Link (Trans, Port_Cfg.DP, Port_Cfg.Mode);
      end if;

      Registers.Write (Trans.HTOTAL,   Encode (M.H_Visible,    M.H_Total));
      Registers.Write (Trans.HBLANK,   Encode (M.H_Visible,    M.H_Total));
      Registers.Write (Trans.HSYNC,    Encode (M.H_Sync_Begin, M.H_Sync_End));
      Registers.Write (Trans.VTOTAL,   Encode (M.V_Visible,    M.V_Total));
      Registers.Write (Trans.VBLANK,   Encode (M.V_Visible,    M.V_Total));
      Registers.Write (Trans.VSYNC,    Encode (M.V_Sync_Begin, M.V_Sync_End));
   end Setup;

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

   procedure Enable_Pipe_Clock (Pipe : Pipe_Index; Port_Cfg : Port_Config)
   is
      use type HW.GFX.GMA.Registers.Registers_Invalid_Index;

      Trans : Transcoder_Regs renames
               Transcoders (Get_Idx (Pipe, Port_Cfg.Port));
   begin
      if Config.Need_Early_Transcoder_Setup and then
         Trans.CLK_SEL /= Registers.Invalid_Register
      then
         if Config.Continuous_Port_Select then
            if Port_Cfg.Port in XELPD_Digital_Port then
               Registers.Unset_And_Set_Mask
                 (Register   => Trans.CLK_SEL,
                  Mask_Unset => TRANS_CLK_SEL_MASK,
                  Mask_Set   => XELPD_TRANS_CLK_SEL_PORT (Port_Cfg.Port));
            end if;
         else
            if Port_Cfg.Port in TGL_Digital_Port then
               Registers.Unset_And_Set_Mask
                 (Register   => Trans.CLK_SEL,
                  Mask_Unset => TRANS_CLK_SEL_MASK,
                  Mask_Set   => TGL_TRANS_CLK_SEL_PORT (Port_Cfg.Port));
            end if;
         end if;
      end if;
   end Enable_Pipe_Clock;

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

   procedure Configure (Pipe : Pipe_Index; Port_Cfg : Port_Config; Scale : Boolean)
   is
      Trans : Transcoder_Regs renames
               Transcoders (Get_Idx (Pipe, Port_Cfg.Port));
      Lane_Count : constant DP_Lane_Count :=
        (if Port_Cfg.Is_FDI then Port_Cfg.FDI.Lane_Count else Port_Cfg.DP.Lane_Count);
      EDP_Select : constant Word32 :=
        (if Config.Has_TGL_DDI_Select
         then 0
         else
           (if Pipe = Primary and
            (not Config.Use_PDW_For_EDP_Scaling or else not Scale)
            then
               DDI_FUNC_CTL_EDP_SELECT_ALWAYS_ON
            else
               DDI_FUNC_CTL_EDP_SELECT (Pipe)));
      DDI_Select : constant Word32 :=
        (if Config.Has_TGL_DDI_Select and then Port_Cfg.Port in DDI_Port then
            TGL_DDI_FUNC_CTL_DDI_SELECT (Port_Cfg.Port)
         else
            (if Port_Cfg.Port in Digital_Port
             then
                DDI_FUNC_CTL_DDI_SELECT (Port_Cfg.Port)
             else 0));
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
      if Config.Has_Pipe_DDI_Func then
         if Port_Cfg.Port in DDI_Port then
            Registers.Write
              (Register => Trans.DDI_FUNC_CTL,
               Value    => DDI_Select or
                        DDI_FUNC_CTL_MODE_SELECT (Port_Cfg.Display) or
                        DDI_FUNC_CTL_BPC (Port_Cfg.Mode.BPC) or
                        DDI_FUNC_CTL_VSYNC (Port_Cfg.Mode.V_Sync_Active_High) or
                        DDI_FUNC_CTL_HSYNC (Port_Cfg.Mode.H_Sync_Active_High) or
                        EDP_Select or
                        DDI_FUNC_CTL_PORT_WIDTH (Lane_Count));
         end if;
      end if;
   end Configure;

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

   procedure On
     (Pipe     : Pipe_Index;
      Port_Cfg : Port_Config;
      Dither   : Boolean;
      Scale    : Boolean)
   is
      use type HW.GFX.GMA.Registers.Registers_Invalid_Index;
      Trans : Transcoder_Regs renames
               Transcoders (Get_Idx (Pipe, Port_Cfg.Port));
      PIPE_ARB_USE_PROG_SLOTS : constant := 1 * 2 ** 13;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
      if not Config.Need_Early_Transcoder_Setup then
         Configure (Pipe, Port_Cfg, Scale);
      end if;

      if Config.Has_Pipe_DDI_Func and then Port_Cfg.Port in DDI_Port then
         Registers.Set_Mask
           (Register => Trans.DDI_FUNC_CTL,
            Mask     => DDI_FUNC_CTL_ENABLE);
      end if;

      if Config.Need_Pipe_Arb_Slots and then
         Trans.PIPE_ARB_CTL /= Registers.Invalid_Register
      then
         Registers.Set_Mask
           (Register => Trans.PIPE_ARB_CTL,
            Mask     => PIPE_ARB_USE_PROG_SLOTS);
      end if;

      Registers.Write
        (Register => Trans.CONF,
         Value    => TRANS_CONF_ENABLE or
                     (if not Config.Has_Pipeconf_Misc then
                        BPC_Conf (Port_Cfg.Mode.BPC, Dither) else 0));
      Registers.Posting_Read (Trans.CONF);
   end On;

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

   procedure Trans_Off (Trans : Transcoder_Regs)
   is
      Enabled : Boolean;
   begin
      Registers.Is_Set_Mask (Trans.CONF, TRANS_CONF_ENABLE, Enabled);

      if Enabled then
         Registers.Unset_Mask (Trans.CONF, TRANS_CONF_ENABLE);
      end if;

      -- Workaround for Broadwell:
      -- Status may be wrong if pipe hasn't been enabled since reset.
      if not Config.Pipe_Enabled_Workaround or else Enabled then
         -- synchronously wait until pipe is truly off
         Registers.Wait_Unset_Mask
           (Register => Trans.CONF,
            Mask     => TRANS_CONF_ENABLED_STATUS,
            TOut_MS  => 40);
      end if;

      if Config.Has_Pipe_DDI_Func then
         Registers.Is_Set_Mask (Trans.DDI_FUNC_CTL, DDI_FUNC_CTL_ENABLE, Enabled);
         if Enabled then
            Registers.Write (Trans.DDI_FUNC_CTL, 0);
         end if;
      end if;
   end Trans_Off;

   procedure Off (Pipe : Pipe_Index)
   is
      DDI_Func_Ctl : Word32;
   begin
      if Config.Has_EDP_Transcoder then
         Registers.Read (Registers.PIPE_EDP_DDI_FUNC_CTL, DDI_Func_Ctl);
         DDI_Func_Ctl := DDI_Func_Ctl and DDI_FUNC_CTL_EDP_SELECT_MASK;

         if (Pipe = Primary and
             DDI_Func_Ctl = DDI_FUNC_CTL_EDP_SELECT_ALWAYS_ON) or
            DDI_Func_Ctl = DDI_FUNC_CTL_EDP_SELECT (Pipe)
         then
            Trans_Off (Transcoders (Trans_EDP));
         end if;
      end if;

      Trans_Off (Transcoders (Default_Transcoder (Pipe)));
   end Off;

   procedure Clk_Off (Pipe : Pipe_Index)
   is
      use type Registers.Registers_Invalid_Index;

      Trans : Transcoder_Regs renames Transcoders (Default_Transcoder (Pipe));
   begin
      if Config.Has_Trans_Clk_Sel and then
         Trans.CLK_SEL /= Registers.Invalid_Register
      then
         Registers.Write (Trans.CLK_SEL, TRANS_CLK_SEL_PORT_NONE);
      end if;
   end Clk_Off;

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

   SRD_CTL_ENABLE          : constant := 1 * 2 ** 31;
   SRD_STATUS_STATE_MASK   : constant := 7 * 2 ** 29;

   type SRD_Regs is record
      CTL     : Registers.Registers_Index;
      STATUS  : Registers.Registers_Index;
   end record;
   type SRD_Per_Pipe_Regs is array (Transcoder_Index) of SRD_Regs;

   SRD : constant SRD_Per_Pipe_Regs := SRD_Per_Pipe_Regs'
     (Trans_EDP   => SRD_Regs'
        (CTL      => Registers.SRD_CTL_EDP,
         STATUS   => Registers.SRD_STATUS_EDP),
      Trans_A     => SRD_Regs'
        (CTL      => Registers.SRD_CTL_A,
         STATUS   => Registers.SRD_STATUS_A),
      Trans_B     => SRD_Regs'
        (CTL      => Registers.SRD_CTL_B,
         STATUS   => Registers.SRD_STATUS_B),
      Trans_C     => SRD_Regs'
        (CTL      => Registers.SRD_CTL_C,
         STATUS   => Registers.SRD_STATUS_C));

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

   procedure PSR_Off
   is
      Enabled : Boolean;
   begin
      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

      if Config.Has_Per_Pipe_SRD then
         declare
            First_Transcoder : constant Transcoder_Index :=
              (if Config.Has_EDP_Transcoder then Trans_EDP else Trans_A);
         begin
            for P in Transcoder_Index range First_Transcoder .. Transcoder_Index'Last loop
               Registers.Is_Set_Mask (SRD (P).CTL, SRD_CTL_ENABLE, Enabled);
               if Enabled then
                  Registers.Unset_Mask (SRD (P).CTL, SRD_CTL_ENABLE);
                  Registers.Wait_Unset_Mask (SRD (P).STATUS, SRD_STATUS_STATE_MASK);

                  pragma Debug (Debug.Put_Line ("Disabled PSR."));
               end if;
            end loop;
         end;
      else
         Registers.Is_Set_Mask (Registers.SRD_CTL, SRD_CTL_ENABLE, Enabled);
         if Enabled then
            Registers.Unset_Mask (Registers.SRD_CTL, SRD_CTL_ENABLE);
            Registers.Wait_Unset_Mask (Registers.SRD_STATUS, SRD_STATUS_STATE_MASK);

            pragma Debug (Debug.Put_Line ("Disabled PSR."));
         end if;
      end if;
   end PSR_Off;

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

end HW.GFX.GMA.Transcoder;
