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@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,