[coreboot-gerrit] Change in libgfxinit[master]: gma: Set tiled framebuffers up through Plane_Control

Nico Huber (Code Review) gerrit at coreboot.org
Tue Dec 5 13:05:28 CET 2017


Nico Huber has uploaded this change for review. ( https://review.coreboot.org/22709


Change subject: gma: Set tiled framebuffers up through Plane_Control
......................................................................

gma: Set tiled framebuffers up through Plane_Control

On platforms with Plane_Control registers (Broxton/Skylake+) we can
use X and Y tiled framebuffers for scanout (older platforms support
X tiling only). As our main use case is 90° rotation with Y tiled
framebuffers, we implement it for the newer platforms only for now.

We also set up a fence register for linear access to the tiled frame-
buffer through the aperture.

Change-Id: I913c82f62fd28b681a06ce13f41160a07e559799
Signed-off-by: Nico Huber <nico.h at gmx.de>
---
M common/hw-gfx-gma-config_helpers.adb
M common/hw-gfx-gma-pipe_setup.adb
M common/hw-gfx-gma.adb
M common/hw-gfx-gma.ads
M common/hw-gfx.ads
5 files changed, 60 insertions(+), 25 deletions(-)



  git pull ssh://review.coreboot.org:29418/libgfxinit refs/changes/09/22709/1

diff --git a/common/hw-gfx-gma-config_helpers.adb b/common/hw-gfx-gma-config_helpers.adb
index 0f60375..6eff5d2 100644
--- a/common/hw-gfx-gma-config_helpers.adb
+++ b/common/hw-gfx-gma-config_helpers.adb
@@ -186,16 +186,14 @@
       Pipe        : Pipe_Index)
       return Boolean
    is
-      function To_Bytes (Pixels : Width_Type) return Pos32 is
-      begin
-         return Pos32 (Pixels) * 4 * Pos32 (Framebuffer.BPC) / 8;
-      end To_Bytes;
    begin
       -- No downscaling
       -- Respect maximum scalable width
       -- VGA plane is only allowed on the primary pipe
       -- Only 32bpp RGB (ignored for VGA plane)
-      -- Stride must be a multiple of 64 bytes (ignored for VGA plane)
+      -- Stride must be big enough and a multiple of 64 bytes or the tile size
+      -- (ignored for VGA plane)
+      -- Tiling is only supported on newer generations (with Plane_Control)
       return
          ((Framebuffer.Width = Pos32 (Port_Cfg.Mode.H_Visible) and
            Framebuffer.Height = Pos32 (Port_Cfg.Mode.V_Visible)) or
@@ -205,8 +203,8 @@
          (Framebuffer.Offset /= VGA_PLANE_FRAMEBUFFER_OFFSET or Pipe = Primary)
          and
          (Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET or
-          (Framebuffer.BPC = 8 and
-           To_Bytes (Framebuffer.Stride) mod 64 = 0));
+          (Framebuffer.BPC = 8 and Valid_Stride (Framebuffer) and
+           (Config.Has_Plane_Control or Framebuffer.Tiling = Linear)));
    end Validate_Config;
 
 end HW.GFX.GMA.Config_Helpers;
diff --git a/common/hw-gfx-gma-pipe_setup.adb b/common/hw-gfx-gma-pipe_setup.adb
index 256c7f5..215b4de 100644
--- a/common/hw-gfx-gma-pipe_setup.adb
+++ b/common/hw-gfx-gma-pipe_setup.adb
@@ -39,6 +39,16 @@
    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;
+   PLANE_CTL_TILED_SURFACE_MASK        : constant := 7 * 2 ** 10;
+   PLANE_CTL_TILED_SURFACE_LINEAR      : constant := 0 * 2 ** 10;
+   PLANE_CTL_TILED_SURFACE_X_TILED     : constant := 1 * 2 ** 10;
+   PLANE_CTL_TILED_SURFACE_Y_TILED     : constant := 4 * 2 ** 10;
+   PLANE_CTL_TILED_SURFACE_YF_TILED    : constant := 5 * 2 ** 10;
+
+   PLANE_CTL_TILED_SURFACE : constant array (Tiling_Type) of Word32 :=
+     (Linear   => PLANE_CTL_TILED_SURFACE_LINEAR,
+      X_Tiled  => PLANE_CTL_TILED_SURFACE_X_TILED,
+      Y_Tiled  => PLANE_CTL_TILED_SURFACE_Y_TILED);
 
    PLANE_WM_ENABLE                     : constant :=        1 * 2 ** 31;
    PLANE_WM_LINES_SHIFT                : constant :=                 14;
@@ -131,7 +141,7 @@
 
    procedure Setup_Hires_Plane
      (Controller  : Controller_Type;
-      Framebuffer : HW.GFX.Framebuffer_Type)
+      FB          : HW.GFX.Framebuffer_Type)
    with
       Global => (In_Out => Registers.Register_State),
       Depends =>
@@ -139,19 +149,11 @@
             =>+
               (Registers.Register_State,
                Controller,
-               Framebuffer))
+               FB))
    is
       -- FIXME: setup correct format, based on framebuffer RGB format
       Format : constant Word32 := 6 * 2 ** 26;
       PRI : Word32 := DSPCNTR_ENABLE or Format;
-
-      function To_Bytes (Pixels : Width_Type) return Word32
-      with
-         Pre => (Pos64 (Pixels) <= Pos64 (Word32'Last) / 4 / BPC_Type'Last * 8)
-      is
-      begin
-         return Word32 (Pos64 (Pixels) * 4 * Framebuffer.BPC / 8);
-      end To_Bytes;
    begin
       pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
 
@@ -160,14 +162,16 @@
            (Register    => Controller.PLANE_CTL,
             Value       => PLANE_CTL_PLANE_ENABLE or
                            PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888 or
-                           PLANE_CTL_PLANE_GAMMA_DISABLE);
+                           PLANE_CTL_PLANE_GAMMA_DISABLE or
+                           PLANE_CTL_TILED_SURFACE (FB.Tiling));
          Registers.Write (Controller.PLANE_OFFSET, 16#0000_0000#);
          Registers.Write
            (Controller.PLANE_SIZE,
-            Encode (Pos16 (Framebuffer.Width), Pos16 (Framebuffer.Height)));
-         Registers.Write (Controller.PLANE_STRIDE, To_Bytes (Framebuffer.Stride) / 64);
+            Encode (Pos16 (FB.Width), Pos16 (FB.Height)));
+         Registers.Write
+           (Controller.PLANE_STRIDE, Word32 (FB_Pitch (FB.Stride, FB)));
          Registers.Write (Controller.PLANE_POS,    16#0000_0000#);
-         Registers.Write (Controller.PLANE_SURF,   Framebuffer.Offset and 16#ffff_f000#);
+         Registers.Write (Controller.PLANE_SURF,   FB.Offset and 16#ffff_f000#);
       else
          if Config.Disable_Trickle_Feed then
             PRI := PRI or DSPCNTR_DISABLE_TRICKLE_FEED;
@@ -179,8 +183,9 @@
              Mask_Unset => DSPCNTR_MASK,
              Mask_Set   => PRI);
 
-         Registers.Write (Controller.DSPSTRIDE, To_Bytes (Framebuffer.Stride));
-         Registers.Write (Controller.DSPSURF, Framebuffer.Offset and 16#ffff_f000#);
+         Registers.Write
+           (Controller.DSPSTRIDE, Word32 (Pixel_To_Bytes (FB.Stride, FB)));
+         Registers.Write (Controller.DSPSURF, FB.Offset and 16#ffff_f000#);
          if Config.Has_DSP_Linoff then
             Registers.Write (Controller.DSPLINOFF, 0);
          end if;
diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb
index 9f835d2..76b271d 100644
--- a/common/hw-gfx-gma.adb
+++ b/common/hw-gfx-gma.adb
@@ -464,7 +464,7 @@
 
    -- Check basics and that it fits in GTT
    function Valid_FB (FB : Framebuffer_Type) return Boolean is
-     (FB.Width <= FB.Stride and FB_Last_Page (FB) <= GTT_Range'Last);
+     (Valid_Stride (FB) and FB_Last_Page (FB) <= GTT_Range'Last);
 
    -- Also check that we don't overflow the GTT's 39-bit space
    -- (always true with a 32-bit base)
@@ -611,6 +611,20 @@
          Success := Phys_Base /= GMA_Phys_Base_Mask and Phys_Base /= 0;
          pragma Debug (not Success, Debug.Put_Line
            ("Failed to read stolen memory base."));
+
+         if Success then
+            if FB.Tiling in XY_Tiling then
+               Registers.Add_Fence
+                 (First_Page  => FB_First_Page (FB),
+                  Last_Page   => FB_Last_Page (FB),
+                  Tiling      => FB.Tiling,
+                  Pitch       => FB_Pitch (FB.Stride, FB),
+                  Success     => Success);
+            end if;
+            pragma Debug (not Success, Debug.Put_Line
+              ("Tiled framebuffer but no fence regs available."));
+         end if;
+
          if Success then
             Setup_Default_GTT (FB, Phys_Base);
          end if;
diff --git a/common/hw-gfx-gma.ads b/common/hw-gfx-gma.ads
index cd992b8..9943e44 100644
--- a/common/hw-gfx-gma.ads
+++ b/common/hw-gfx-gma.ads
@@ -157,4 +157,17 @@
 
    subtype DDI_HDMI_Buf_Trans_Range is Integer range 0 .. 11;
 
+   ----------------------------------------------------------------------------
+
+   Tile_Width : constant array (Tiling_Type) of Pos32 :=
+     (Linear => 16, X_Tiled => 128, Y_Tiled => 32);
+
+   function FB_Pitch (Px : Pixel_Type; FB : Framebuffer_Type) return Natural is
+     (Natural (Div_Round_Up
+        (Pixel_To_Bytes (Px, FB), Tile_Width (FB.Tiling) * 4)));
+
+   function Valid_Stride (FB : Framebuffer_Type) return Boolean is
+     (FB.Width <= FB.Stride and
+      Pixel_To_Bytes (FB.Stride, FB) mod (Tile_Width (FB.Tiling) * 4) = 0);
+
 end HW.GFX.GMA;
diff --git a/common/hw-gfx.ads b/common/hw-gfx.ads
index c5d9631..67662ed 100644
--- a/common/hw-gfx.ads
+++ b/common/hw-gfx.ads
@@ -20,6 +20,9 @@
 
 package HW.GFX is
 
+   -- such that the count of pixels in any framebuffer may fit
+   subtype Pixel_Type is Pos32 range 1 .. 8192 * 8192;
+
    -- implementation only supports 4800p for now ;-)
    subtype Width_Type  is Pos32 range 1 .. 4800;
    subtype Height_Type is Pos32 range 1 .. 7680;
@@ -40,8 +43,10 @@
       Offset   : Word32;
    end record;
 
+   function Pixel_To_Bytes (Pixel : Pixel_Type; FB : Framebuffer_Type)
+      return Pos32 is (Pixel * Pos32 (FB.BPC) / (8 / 4));
    function FB_Size (FB : Framebuffer_Type) return Pos32 is
-     (FB.Stride * FB.Height * Pos32 (FB.BPC) / (8 / 4));
+     (Pixel_To_Bytes (FB.Stride * FB.Height, FB));
 
    Default_FB : constant Framebuffer_Type := Framebuffer_Type'
      (Width    => 1,

-- 
To view, visit https://review.coreboot.org/22709
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: libgfxinit
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I913c82f62fd28b681a06ce13f41160a07e559799
Gerrit-Change-Number: 22709
Gerrit-PatchSet: 1
Gerrit-Owner: Nico Huber <nico.h at gmx.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171205/1060d7ad/attachment-0001.html>


More information about the coreboot-gerrit mailing list