gma pipe_setup: Update for TGL & ADL

Tiger Lake requires some differences in plane programming over prior
generations, including new chicken bits, wider watermarks, MBUS DBOX
programming and a few bits moved around. Alder Lake brings some more
chicken bits and requires arb-slot programming.

Signed-off-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Change-Id: I93329c0a012da83abc379d6782fabe257dc180f3
Reviewed-on: https://review.sourcearcade.org/c/libgfxinit/+/458
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: Nico Huber <nico.h@gmx.de>
diff --git a/common/hw-gfx-gma-config.ads.template b/common/hw-gfx-gma-config.ads.template
index 113bc10..9c150c4 100644
--- a/common/hw-gfx-gma-config.ads.template
+++ b/common/hw-gfx-gma-config.ads.template
@@ -223,6 +223,16 @@
 
    ----------- Transcoder -------
    Need_Early_Transcoder_Setup   : <genbool> := Tigerlake_On;
+   Need_Pipe_Arb_Slots           : <tglbool> := Alderlake_On;
+
+   ----------- Planes -----------
+   Has_Mbus_Dbox_Credits         : <genbool> := Tigerlake_On;
+   Has_Wide_Watermarks           : <genbool> := Tigerlake_On;
+   Has_Plane_Color_Control       : <genbool> := Tigerlake_On;
+   Has_New_Mbus_Dbox_Credits     : <tglbool> := (Alderlake_On and Is_LP);
+
+   ----------- Pipe -------------
+   Need_Underrun_Rec_Disable     : <tglbool> := Alderlake_On;
 
    --------- Panel power: -------
    Has_PP_Write_Protection       : <genbool> := Up_To_Ironlake;
diff --git a/common/hw-gfx-gma-pipe_setup.adb b/common/hw-gfx-gma-pipe_setup.adb
index 69d83a8..941a5e7 100644
--- a/common/hw-gfx-gma-pipe_setup.adb
+++ b/common/hw-gfx-gma-pipe_setup.adb
@@ -49,6 +49,8 @@
       DSPCNTR_DISABLE_TRICKLE_FEED or
       DSPCNTR_TILED_SURFACE_X_TILED;
 
+   PLANE_COLOR_CTL_PLANE_GAMMA_DISABLE : constant := 1 * 2 ** 13;
+
    PLANE_CTL_PLANE_ENABLE              : constant := 1 * 2 ** 31;
    PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888  : constant := 4 * 2 ** 24;
    PLANE_CTL_PLANE_GAMMA_DISABLE       : constant := 1 * 2 ** 13;
@@ -73,7 +75,11 @@
    PLANE_WM_ENABLE                     : constant :=        1 * 2 ** 31;
    PLANE_WM_LINES_SHIFT                : constant :=                 14;
    PLANE_WM_LINES_MASK                 : constant := 16#001f# * 2 ** 14;
-   PLANE_WM_BLOCKS_MASK                : constant := 16#03ff# * 2 **  0;
+   PLANE_WM_BLOCKS_MASK                : constant :=
+      (if Config.Has_Wide_Watermarks then 16#7ff# else 16#3ff#);
+
+   PIPEMISC_HDR_MODE_PRECISION         : constant := 1 * 2 ** 23;
+   PIPEMISC_PIXEL_ROUNDING_TRUNC       : constant := 1 * 2 **  8;
 
    VGA_SR_INDEX                        : constant :=   16#03c4#;
    VGA_SR_DATA                         : constant :=   16#03c5#;
@@ -95,6 +101,9 @@
         (Cursor_64x64   => 16#27#,
          Cursor_128x128 => 16#22#,
          Cursor_256x256 => 16#23#));
+   subtype ARB_Slots is Natural range 0 .. 7;
+   function MCURSOR_ARB_SLOTS (N : ARB_Slots) return Word32 is
+     (Shift_Left (Word32 (N), 28));
 
    function CUR_POS_Y (Y : Int32) return Word32 is
      ((if Y >= 0 then 0 else 1 * 2 ** 31) or Shift_Left (Word32 (abs Y), 16))
@@ -207,13 +216,6 @@
      (Controller  : Controller_Type;
       FB          : HW.GFX.Framebuffer_Type)
    with
-      Global => (In_Out => Registers.Register_State),
-      Depends =>
-        (Registers.Register_State
-            =>+
-              (Registers.Register_State,
-               Controller,
-               FB)),
       Pre => FB.Height + FB.Start_Y <= FB.V_Stride
    is
       -- FIXME: setup correct format, based on framebuffer RGB format
@@ -227,6 +229,22 @@
             Stride, Offset : Word32;
             Width : constant Width_Type := Rotated_Width (FB);
             Height : constant Width_Type := Rotated_Height (FB);
+
+            function PLANE_CTL_ARB_SLOTS (N : Word32) return Word32 is
+              (if Config.Need_Pipe_Arb_Slots then Shift_Left (N, 28) else 0);
+
+            -- TODO: Hard coded format and arbitration slots for now,
+            --       for 4B-per-pixel XRGB, just like `Format` above.
+            --       ARB_SLOTS(1) matches the 4B per pixel.
+            Plane_Ctl : constant Word32 :=
+               PLANE_CTL_PLANE_ENABLE or
+               PLANE_CTL_TILED_SURFACE (FB.Tiling) or
+               PLANE_CTL_PLANE_ROTATION (FB.Rotation) or
+               PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888 or
+               PLANE_CTL_ARB_SLOTS (1) or
+              (if not Config.Has_Plane_Color_Control
+               then PLANE_CTL_PLANE_GAMMA_DISABLE
+               else 0);
          begin
             if Rotation_90 (FB) then
                Stride   := Word32 (FB_Pitch (FB.V_Stride, FB));
@@ -237,13 +255,14 @@
                Offset   := Shift_Left (Word32 (FB.Start_Y), 16) or
                            Word32 (FB.Start_X);
             end if;
-            Registers.Write
-              (Register    => Controller.PLANE_CTL,
-               Value       => PLANE_CTL_PLANE_ENABLE or
-                              PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888 or
-                              PLANE_CTL_PLANE_GAMMA_DISABLE or
-                              PLANE_CTL_TILED_SURFACE (FB.Tiling) or
-                              PLANE_CTL_PLANE_ROTATION (FB.Rotation));
+
+            if Config.Has_Plane_Color_Control then
+               Registers.Write
+                 (Register => Controller.PLANE_COLOR_CTL,
+                  Value    => PLANE_COLOR_CTL_PLANE_GAMMA_DISABLE);
+            end if;
+            Registers.Write (Controller.PLANE_AUX_DIST, 0);
+            Registers.Write (Controller.PLANE_CTL, Plane_Ctl);
             Registers.Write (Controller.PLANE_OFFSET, Offset);
             Registers.Write (Controller.PLANE_SIZE, Encode (Width, Height));
             Registers.Write (Controller.PLANE_STRIDE, Stride);
@@ -332,13 +351,88 @@
       use type Word8;
 
       Reg8 : Word8;
+
+      type BW_Credit is new Natural range 0 .. 3;
+      function MBUS_DBOX_BW_CREDIT (C : BW_Credit) return Word32 is
+        (Shift_Left (Word32 (C), 14));
+
+      type B_Credit is new Natural range 0 .. 31;
+      function MBUS_DBOX_B_CREDIT (C : B_Credit) return Word32 is
+        (Shift_Left (Word32 (C), 8));
+
+      type A_Credit is new Natural range 0 .. 15;
+      function MBUS_DBOX_A_CREDIT (C : A_Credit) return Word32 is
+        (Word32 (C));
+
+      type B2B_Trans_Max is new Natural range 0 .. 31;
+      function MBUS_DBOX_B2B_TRANSACTIONS_MAX (B : B2B_Trans_Max) return Word32 is
+        (Shift_Left (Word32 (B), 20));
+
+      type B2B_Trans_Delay is new Natural range 0 .. 7;
+      function MBUS_DBOX_B2B_TRANSACTIONS_DELAY (B : B2B_Trans_Delay) return Word32 is
+        (Shift_Left (Word32 (B), 17));
+      MBUS_DBOX_REGULATE_B2B_TRANSACTIONS_EN : constant := 1 * 2 ** 16;
+
+      procedure Program_Mbus_Dbox_Credits is
+         Tmp : Word32;
+      begin
+         Tmp := MBUS_DBOX_B2B_TRANSACTIONS_MAX (16) or
+                MBUS_DBOX_B2B_TRANSACTIONS_DELAY (1) or
+                MBUS_DBOX_REGULATE_B2B_TRANSACTIONS_EN;
+
+         if Config.Has_New_Mbus_Dbox_Credits then
+            Tmp := Tmp or MBUS_DBOX_BW_CREDIT (2) or
+                          MBUS_DBOX_B_CREDIT (8) or
+                          MBUS_DBOX_A_CREDIT (4);  -- No joined MBus support,
+                                                   -- hence always use 4 for now.
+         else
+            Tmp := Tmp or MBUS_DBOX_BW_CREDIT (2) or
+                          MBUS_DBOX_B_CREDIT (12) or
+                          MBUS_DBOX_A_CREDIT (2);
+         end if;
+
+         Registers.Write
+           (Register => Controller.MBUS_DBOX_CTL,
+            Value    => Tmp);
+      end Program_Mbus_Dbox_Credits;
+
+      -- Display WA # 1605353570: icl
+      -- Set the pixel rounding bit to 1 for allowing
+      -- passthrough of Frame buffer pixels unmodified
+      -- across pipe
+      PIXEL_ROUNDING_TRUNC_FB_PASSTHRU : constant := 1 * 2 ** 15;
+
+      -- Display WA #1153: icl
+      -- enable hardware to bypass the alpha math
+      -- and rounding for per-pixel values 00 and 0xff
+      PER_PIXEL_ALPHA_BYPASS_EN : constant := 1 * 2 ** 7;
+
+      -- ADL_P requires that we disable underrun recovery when
+      -- downscaling (or using the scaler for YUV420 pipe output),
+      -- using DSC, or using PSR2.
+      -- i915 always disables underrun recovery for gen 13+.
+      UNDERRUN_RECOVERY_DISABLE : constant := 1 * 2 ** 30;
    begin
       pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
 
+      if Config.Has_Type_C_Ports then
+         Registers.Set_Mask
+           (Register => Controller.PIPE_CHICKEN,
+            Mask     => PER_PIXEL_ALPHA_BYPASS_EN or
+                        PIXEL_ROUNDING_TRUNC_FB_PASSTHRU or
+                        (if Config.Need_Underrun_Rec_Disable
+                         then UNDERRUN_RECOVERY_DISABLE
+                         else 0));
+      end if;
+
       if Config.Has_Plane_Control then
          Setup_Watermarks (Controller);
       end if;
 
+      if Config.Has_Mbus_Dbox_Credits then
+         Program_Mbus_Dbox_Credits;
+      end if;
+
       if Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET then
          if Config.VGA_Plane_Workaround then
             Registers.Unset_And_Set_Mask
@@ -374,7 +468,10 @@
       if Config.Has_Pipeconf_Misc then
          Registers.Write
            (Register => Controller.PIPEMISC,
-            Value    => Transcoder.BPC_Conf (Dither_BPC, Dither));
+            Value    => Transcoder.BPC_Conf (Dither_BPC, Dither) or
+                        -- FIXME: Should we set these at all?
+                        (if Config.Has_Plane_Color_Control then
+                           (PIPEMISC_PIXEL_ROUNDING_TRUNC or PIPEMISC_HDR_MODE_PRECISION) else 0));
       end if;
    end Setup_Display;
 
@@ -390,8 +487,10 @@
       -- so keep it first
       Registers.Write
         (Register => Cursors (Pipe).CTL,
-         Value    => CUR_CTL_PIPE_SELECT (Pipe) or
-                     CUR_CTL_MODE (Cursor.Mode, Cursor.Size));
+         Value    => CUR_CTL_MODE (Cursor.Mode, Cursor.Size) or
+                     (if Config.Need_Pipe_Arb_Slots
+                      then MCURSOR_ARB_SLOTS (1)
+                      else CUR_CTL_PIPE_SELECT (Pipe)));
       Place_Cursor (Pipe, FB, Cursor);
    end Update_Cursor;
 
diff --git a/common/hw-gfx-gma-pipe_setup.ads b/common/hw-gfx-gma-pipe_setup.ads
index f047a64..bdb1700 100644
--- a/common/hw-gfx-gma-pipe_setup.ads
+++ b/common/hw-gfx-gma-pipe_setup.ads
@@ -102,6 +102,10 @@
          PLANE_WM          : PLANE_WM_Type;
          CUR_BUF_CFG       : Registers.Registers_Index;
          CUR_WM            : PLANE_WM_Type;
+         MBUS_DBOX_CTL     : Registers.Registers_Index;
+         PIPE_CHICKEN      : Registers.Registers_Index;
+         PLANE_COLOR_CTL   : Registers.Registers_Index;
+         PLANE_AUX_DIST    : Registers.Registers_Index;
       end record;
 
    type Controller_Array is array (Pipe_Index) of Controller_Type;
@@ -172,7 +176,11 @@
                               Registers.CUR_WM_A_4,
                               Registers.CUR_WM_A_5,
                               Registers.CUR_WM_A_6,
-                              Registers.CUR_WM_A_7)),
+                              Registers.CUR_WM_A_7),
+         MBUS_DBOX_CTL     => Registers.PIPE_MBUS_DBOX_CTL_A,
+         PIPE_CHICKEN      => Registers.PIPEA_CHICKEN,
+         PLANE_COLOR_CTL   => Registers.PLANE_COLOR_CTL_1_A,
+         PLANE_AUX_DIST    => Registers.PLANE_AUX_DIST_1_A),
       Secondary => Controller_Type'
         (Pipe              => Secondary,
          PIPESRC           => Registers.PIPEBSRC,
@@ -233,7 +241,11 @@
                               Registers.CUR_WM_B_4,
                               Registers.CUR_WM_B_5,
                               Registers.CUR_WM_B_6,
-                              Registers.CUR_WM_B_7)),
+                              Registers.CUR_WM_B_7),
+         MBUS_DBOX_CTL     => Registers.PIPE_MBUS_DBOX_CTL_B,
+         PIPE_CHICKEN      => Registers.PIPEB_CHICKEN,
+         PLANE_COLOR_CTL   => Registers.PLANE_COLOR_CTL_1_B,
+         PLANE_AUX_DIST    => Registers.PLANE_AUX_DIST_1_B),
       Tertiary => Controller_Type'
         (Pipe              => Tertiary,
          PIPESRC           => Registers.PIPECSRC,
@@ -280,7 +292,11 @@
                               Registers.CUR_WM_C_4,
                               Registers.CUR_WM_C_5,
                               Registers.CUR_WM_C_6,
-                              Registers.CUR_WM_C_7)));
+                              Registers.CUR_WM_C_7),
+         MBUS_DBOX_CTL     => Registers.PIPE_MBUS_DBOX_CTL_C,
+         PIPE_CHICKEN      => Registers.PIPEC_CHICKEN,
+         PLANE_COLOR_CTL   => Registers.PLANE_COLOR_CTL_1_C,
+         PLANE_AUX_DIST    => Registers.PLANE_AUX_DIST_1_C));
 
    type Cursor_Regs is record
       CTL      : Registers.Registers_Index;
diff --git a/common/hw-gfx-gma-transcoder.adb b/common/hw-gfx-gma-transcoder.adb
index 6eea451..213af3b 100644
--- a/common/hw-gfx-gma-transcoder.adb
+++ b/common/hw-gfx-gma-transcoder.adb
@@ -328,8 +328,10 @@
       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
@@ -342,6 +344,14 @@
             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