<p>Nico Huber has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/22709">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gma: Set tiled framebuffers up through Plane_Control<br><br>On platforms with Plane_Control registers (Broxton/Skylake+) we can<br>use X and Y tiled framebuffers for scanout (older platforms support<br>X tiling only). As our main use case is 90° rotation with Y tiled<br>framebuffers, we implement it for the newer platforms only for now.<br><br>We also set up a fence register for linear access to the tiled frame-<br>buffer through the aperture.<br><br>Change-Id: I913c82f62fd28b681a06ce13f41160a07e559799<br>Signed-off-by: Nico Huber <nico.h@gmx.de><br>---<br>M common/hw-gfx-gma-config_helpers.adb<br>M common/hw-gfx-gma-pipe_setup.adb<br>M common/hw-gfx-gma.adb<br>M common/hw-gfx-gma.ads<br>M common/hw-gfx.ads<br>5 files changed, 60 insertions(+), 25 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/libgfxinit refs/changes/09/22709/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/common/hw-gfx-gma-config_helpers.adb b/common/hw-gfx-gma-config_helpers.adb<br>index 0f60375..6eff5d2 100644<br>--- a/common/hw-gfx-gma-config_helpers.adb<br>+++ b/common/hw-gfx-gma-config_helpers.adb<br>@@ -186,16 +186,14 @@<br>       Pipe        : Pipe_Index)<br>       return Boolean<br>    is<br>-      function To_Bytes (Pixels : Width_Type) return Pos32 is<br>-      begin<br>-         return Pos32 (Pixels) * 4 * Pos32 (Framebuffer.BPC) / 8;<br>-      end To_Bytes;<br>    begin<br>       -- No downscaling<br>       -- Respect maximum scalable width<br>       -- VGA plane is only allowed on the primary pipe<br>       -- Only 32bpp RGB (ignored for VGA plane)<br>-      -- Stride must be a multiple of 64 bytes (ignored for VGA plane)<br>+      -- Stride must be big enough and a multiple of 64 bytes or the tile size<br>+      -- (ignored for VGA plane)<br>+      -- Tiling is only supported on newer generations (with Plane_Control)<br>       return<br>          ((Framebuffer.Width = Pos32 (Port_Cfg.Mode.H_Visible) and<br>            Framebuffer.Height = Pos32 (Port_Cfg.Mode.V_Visible)) or<br>@@ -205,8 +203,8 @@<br>          (Framebuffer.Offset /= VGA_PLANE_FRAMEBUFFER_OFFSET or Pipe = Primary)<br>          and<br>          (Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET or<br>-          (Framebuffer.BPC = 8 and<br>-           To_Bytes (Framebuffer.Stride) mod 64 = 0));<br>+          (Framebuffer.BPC = 8 and Valid_Stride (Framebuffer) and<br>+           (Config.Has_Plane_Control or Framebuffer.Tiling = Linear)));<br>    end Validate_Config;<br> <br> end HW.GFX.GMA.Config_Helpers;<br>diff --git a/common/hw-gfx-gma-pipe_setup.adb b/common/hw-gfx-gma-pipe_setup.adb<br>index 256c7f5..215b4de 100644<br>--- a/common/hw-gfx-gma-pipe_setup.adb<br>+++ b/common/hw-gfx-gma-pipe_setup.adb<br>@@ -39,6 +39,16 @@<br>    PLANE_CTL_PLANE_ENABLE              : constant := 1 * 2 ** 31;<br>    PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888  : constant := 4 * 2 ** 24;<br>    PLANE_CTL_PLANE_GAMMA_DISABLE       : constant := 1 * 2 ** 13;<br>+   PLANE_CTL_TILED_SURFACE_MASK        : constant := 7 * 2 ** 10;<br>+   PLANE_CTL_TILED_SURFACE_LINEAR      : constant := 0 * 2 ** 10;<br>+   PLANE_CTL_TILED_SURFACE_X_TILED     : constant := 1 * 2 ** 10;<br>+   PLANE_CTL_TILED_SURFACE_Y_TILED     : constant := 4 * 2 ** 10;<br>+   PLANE_CTL_TILED_SURFACE_YF_TILED    : constant := 5 * 2 ** 10;<br>+<br>+   PLANE_CTL_TILED_SURFACE : constant array (Tiling_Type) of Word32 :=<br>+     (Linear   => PLANE_CTL_TILED_SURFACE_LINEAR,<br>+      X_Tiled  => PLANE_CTL_TILED_SURFACE_X_TILED,<br>+      Y_Tiled  => PLANE_CTL_TILED_SURFACE_Y_TILED);<br> <br>    PLANE_WM_ENABLE                     : constant :=        1 * 2 ** 31;<br>    PLANE_WM_LINES_SHIFT                : constant :=                 14;<br>@@ -131,7 +141,7 @@<br> <br>    procedure Setup_Hires_Plane<br>      (Controller  : Controller_Type;<br>-      Framebuffer : HW.GFX.Framebuffer_Type)<br>+      FB          : HW.GFX.Framebuffer_Type)<br>    with<br>       Global => (In_Out => Registers.Register_State),<br>       Depends =><br>@@ -139,19 +149,11 @@<br>             =>+<br>               (Registers.Register_State,<br>                Controller,<br>-               Framebuffer))<br>+               FB))<br>    is<br>       -- FIXME: setup correct format, based on framebuffer RGB format<br>       Format : constant Word32 := 6 * 2 ** 26;<br>       PRI : Word32 := DSPCNTR_ENABLE or Format;<br>-<br>-      function To_Bytes (Pixels : Width_Type) return Word32<br>-      with<br>-         Pre => (Pos64 (Pixels) <= Pos64 (Word32'Last) / 4 / BPC_Type'Last * 8)<br>-      is<br>-      begin<br>-         return Word32 (Pos64 (Pixels) * 4 * Framebuffer.BPC / 8);<br>-      end To_Bytes;<br>    begin<br>       pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));<br> <br>@@ -160,14 +162,16 @@<br>            (Register    => Controller.PLANE_CTL,<br>             Value       => PLANE_CTL_PLANE_ENABLE or<br>                            PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888 or<br>-                           PLANE_CTL_PLANE_GAMMA_DISABLE);<br>+                           PLANE_CTL_PLANE_GAMMA_DISABLE or<br>+                           PLANE_CTL_TILED_SURFACE (FB.Tiling));<br>          Registers.Write (Controller.PLANE_OFFSET, 16#0000_0000#);<br>          Registers.Write<br>            (Controller.PLANE_SIZE,<br>-            Encode (Pos16 (Framebuffer.Width), Pos16 (Framebuffer.Height)));<br>-         Registers.Write (Controller.PLANE_STRIDE, To_Bytes (Framebuffer.Stride) / 64);<br>+            Encode (Pos16 (FB.Width), Pos16 (FB.Height)));<br>+         Registers.Write<br>+           (Controller.PLANE_STRIDE, Word32 (FB_Pitch (FB.Stride, FB)));<br>          Registers.Write (Controller.PLANE_POS,    16#0000_0000#);<br>-         Registers.Write (Controller.PLANE_SURF,   Framebuffer.Offset and 16#ffff_f000#);<br>+         Registers.Write (Controller.PLANE_SURF,   FB.Offset and 16#ffff_f000#);<br>       else<br>          if Config.Disable_Trickle_Feed then<br>             PRI := PRI or DSPCNTR_DISABLE_TRICKLE_FEED;<br>@@ -179,8 +183,9 @@<br>              Mask_Unset => DSPCNTR_MASK,<br>              Mask_Set   => PRI);<br> <br>-         Registers.Write (Controller.DSPSTRIDE, To_Bytes (Framebuffer.Stride));<br>-         Registers.Write (Controller.DSPSURF, Framebuffer.Offset and 16#ffff_f000#);<br>+         Registers.Write<br>+           (Controller.DSPSTRIDE, Word32 (Pixel_To_Bytes (FB.Stride, FB)));<br>+         Registers.Write (Controller.DSPSURF, FB.Offset and 16#ffff_f000#);<br>          if Config.Has_DSP_Linoff then<br>             Registers.Write (Controller.DSPLINOFF, 0);<br>          end if;<br>diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb<br>index 9f835d2..76b271d 100644<br>--- a/common/hw-gfx-gma.adb<br>+++ b/common/hw-gfx-gma.adb<br>@@ -464,7 +464,7 @@<br> <br>    -- Check basics and that it fits in GTT<br>    function Valid_FB (FB : Framebuffer_Type) return Boolean is<br>-     (FB.Width <= FB.Stride and FB_Last_Page (FB) <= GTT_Range'Last);<br>+     (Valid_Stride (FB) and FB_Last_Page (FB) <= GTT_Range'Last);<br> <br>    -- Also check that we don't overflow the GTT's 39-bit space<br>    -- (always true with a 32-bit base)<br>@@ -611,6 +611,20 @@<br>          Success := Phys_Base /= GMA_Phys_Base_Mask and Phys_Base /= 0;<br>          pragma Debug (not Success, Debug.Put_Line<br>            ("Failed to read stolen memory base."));<br>+<br>+         if Success then<br>+            if FB.Tiling in XY_Tiling then<br>+               Registers.Add_Fence<br>+                 (First_Page  => FB_First_Page (FB),<br>+                  Last_Page   => FB_Last_Page (FB),<br>+                  Tiling      => FB.Tiling,<br>+                  Pitch       => FB_Pitch (FB.Stride, FB),<br>+                  Success     => Success);<br>+            end if;<br>+            pragma Debug (not Success, Debug.Put_Line<br>+              ("Tiled framebuffer but no fence regs available."));<br>+         end if;<br>+<br>          if Success then<br>             Setup_Default_GTT (FB, Phys_Base);<br>          end if;<br>diff --git a/common/hw-gfx-gma.ads b/common/hw-gfx-gma.ads<br>index cd992b8..9943e44 100644<br>--- a/common/hw-gfx-gma.ads<br>+++ b/common/hw-gfx-gma.ads<br>@@ -157,4 +157,17 @@<br> <br>    subtype DDI_HDMI_Buf_Trans_Range is Integer range 0 .. 11;<br> <br>+   ----------------------------------------------------------------------------<br>+<br>+   Tile_Width : constant array (Tiling_Type) of Pos32 :=<br>+     (Linear => 16, X_Tiled => 128, Y_Tiled => 32);<br>+<br>+   function FB_Pitch (Px : Pixel_Type; FB : Framebuffer_Type) return Natural is<br>+     (Natural (Div_Round_Up<br>+        (Pixel_To_Bytes (Px, FB), Tile_Width (FB.Tiling) * 4)));<br>+<br>+   function Valid_Stride (FB : Framebuffer_Type) return Boolean is<br>+     (FB.Width <= FB.Stride and<br>+      Pixel_To_Bytes (FB.Stride, FB) mod (Tile_Width (FB.Tiling) * 4) = 0);<br>+<br> end HW.GFX.GMA;<br>diff --git a/common/hw-gfx.ads b/common/hw-gfx.ads<br>index c5d9631..67662ed 100644<br>--- a/common/hw-gfx.ads<br>+++ b/common/hw-gfx.ads<br>@@ -20,6 +20,9 @@<br> <br> package HW.GFX is<br> <br>+   -- such that the count of pixels in any framebuffer may fit<br>+   subtype Pixel_Type is Pos32 range 1 .. 8192 * 8192;<br>+<br>    -- implementation only supports 4800p for now ;-)<br>    subtype Width_Type  is Pos32 range 1 .. 4800;<br>    subtype Height_Type is Pos32 range 1 .. 7680;<br>@@ -40,8 +43,10 @@<br>       Offset   : Word32;<br>    end record;<br> <br>+   function Pixel_To_Bytes (Pixel : Pixel_Type; FB : Framebuffer_Type)<br>+      return Pos32 is (Pixel * Pos32 (FB.BPC) / (8 / 4));<br>    function FB_Size (FB : Framebuffer_Type) return Pos32 is<br>-     (FB.Stride * FB.Height * Pos32 (FB.BPC) / (8 / 4));<br>+     (Pixel_To_Bytes (FB.Stride * FB.Height, FB));<br> <br>    Default_FB : constant Framebuffer_Type := Framebuffer_Type'<br>      (Width    => 1,<br></pre><p>To view, visit <a href="https://review.coreboot.org/22709">change 22709</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/22709"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libgfxinit </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I913c82f62fd28b681a06ce13f41160a07e559799 </div>
<div style="display:none"> Gerrit-Change-Number: 22709 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Nico Huber <nico.h@gmx.de> </div>