Add Start_X and Start_Y offsets for framebuffer panning
For tiled modes, the offsets add to the stride. To keep things simple,
we always assume that they are accounted for (even in linear mode).
To make the panning visible, the offsets are added in `gfx_test` and
the test image is drawn larger by two times the offsets. Also add the
new parameters to Dump_Configs() along with the forgotten tiling and
rotation parameters.
Change-Id: I5d1e1f2ed8b1872a2b82be23a6a622d948f7831f
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/22866
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/common/hw-gfx-gma-config_helpers.ads b/common/hw-gfx-gma-config_helpers.ads
index e684f22..1dc2390 100644
--- a/common/hw-gfx-gma-config_helpers.ads
+++ b/common/hw-gfx-gma-config_helpers.ads
@@ -50,6 +50,6 @@
Rotated_Width (FB) <= Port_Cfg.Mode.H_Visible and
Rotated_Height (FB) <= Port_Cfg.Mode.V_Visible and
(FB.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET or
- FB.Height <= FB.V_Stride));
+ FB.Height + FB.Start_Y <= FB.V_Stride));
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 e2d2567..5c6df37 100644
--- a/common/hw-gfx-gma-pipe_setup.adb
+++ b/common/hw-gfx-gma-pipe_setup.adb
@@ -162,7 +162,7 @@
(Registers.Register_State,
Controller,
FB)),
- Pre => FB.Height <= FB.V_Stride
+ Pre => FB.Height + FB.Start_Y <= FB.V_Stride
is
-- FIXME: setup correct format, based on framebuffer RGB format
Format : constant Word32 := 6 * 2 ** 26;
@@ -177,11 +177,13 @@
Height : constant Pos16 := Rotated_Height (FB);
begin
if Rotation_90 (FB) then
- Stride := Word32 (FB_Pitch (FB.V_Stride, FB));
- Offset := Word32 (FB.V_Stride - FB.Height);
+ Stride := Word32 (FB_Pitch (FB.V_Stride, FB));
+ Offset := Shift_Left (Word32 (FB.Start_X), 16) or
+ Word32 (FB.V_Stride - FB.Height - FB.Start_Y);
else
- Stride := Word32 (FB_Pitch (FB.Stride, FB));
- Offset := 0;
+ Stride := Word32 (FB_Pitch (FB.Stride, FB));
+ Offset := Shift_Left (Word32 (FB.Start_Y), 16) or
+ Word32 (FB.Start_X);
end if;
Registers.Write
(Register => Controller.PLANE_CTL,
@@ -211,9 +213,17 @@
(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);
+ Registers.Write
+ (Register => Controller.DSPLINOFF,
+ Value => Word32 (Pixel_To_Bytes
+ (FB.Start_Y * FB.Stride + FB.Start_X, FB)));
+ Registers.Write (Controller.DSPTILEOFF, 0);
+ else
+ Registers.Write
+ (Register => Controller.DSPTILEOFF,
+ Value => Shift_Left (Word32 (FB.Start_Y), 16) or
+ Word32 (FB.Start_X));
end if;
- Registers.Write (Controller.DSPTILEOFF, 0);
end if;
end Setup_Hires_Plane;
@@ -237,7 +247,7 @@
(Framebuffer)),
Pre =>
Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET or
- Framebuffer.Height <= Framebuffer.V_Stride
+ Framebuffer.Height + Framebuffer.Start_Y <= Framebuffer.V_Stride
is
use type Word8;
diff --git a/common/hw-gfx-gma-pipe_setup.ads b/common/hw-gfx-gma-pipe_setup.ads
index 35d9e87..3ef5dcf 100644
--- a/common/hw-gfx-gma-pipe_setup.ads
+++ b/common/hw-gfx-gma-pipe_setup.ads
@@ -28,7 +28,7 @@
Rotated_Width (Framebuffer) <= Port_Cfg.Mode.H_Visible and
Rotated_Height (Framebuffer) <= Port_Cfg.Mode.V_Visible and
(Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET or
- Framebuffer.Height <= Framebuffer.V_Stride);
+ Framebuffer.Height + Framebuffer.Start_Y <= Framebuffer.V_Stride);
procedure Off (Pipe : Pipe_Index);
diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb
index 6f4594b..0e2c835 100644
--- a/common/hw-gfx-gma.adb
+++ b/common/hw-gfx-gma.adb
@@ -723,6 +723,21 @@
(Primary => "Primary ",
Secondary => "Secondary",
Tertiary => "Tertiary ");
+
+ subtype Tiling_Name is String (1 .. 7);
+ type Tiling_Name_Array is array (Tiling_Type) of Tiling_Name;
+ Tilings : constant Tiling_Name_Array :=
+ (Linear => "Linear ",
+ X_Tiled => "X_Tiled",
+ Y_Tiled => "Y_Tiled");
+
+ subtype Rotation_Name is String (1 .. 11);
+ type Rotation_Name_Array is array (Rotation_Type) of Rotation_Name;
+ Rotations : constant Rotation_Name_Array :=
+ (No_Rotation => "No_Rotation",
+ Rotated_90 => "Rotated_90 ",
+ Rotated_180 => "Rotated_180",
+ Rotated_270 => "Rotated_270");
begin
Debug.New_Line;
Debug.Put_Line ("CONFIG =>");
@@ -736,15 +751,28 @@
Debug.Put_Line
(" (Port => " & Port_Names (Configs (Pipe).Port) & ",");
Debug.Put_Line (" Framebuffer =>");
- Debug.Put (" (Width => ");
+ Debug.Put (" (Width => ");
Debug.Put_Int32 (Configs (Pipe).Framebuffer.Width);
Debug.Put_Line (",");
- Debug.Put (" Height => ");
+ Debug.Put (" Height => ");
Debug.Put_Int32 (Configs (Pipe).Framebuffer.Height);
Debug.Put_Line (",");
- Debug.Put (" Stride => ");
+ Debug.Put (" Start_X => ");
+ Debug.Put_Int32 (Configs (Pipe).Framebuffer.Start_X);
+ Debug.Put_Line (",");
+ Debug.Put (" Start_Y => ");
+ Debug.Put_Int32 (Configs (Pipe).Framebuffer.Start_Y);
+ Debug.Put_Line (",");
+ Debug.Put (" Stride => ");
Debug.Put_Int32 (Configs (Pipe).Framebuffer.Stride);
Debug.Put_Line (",");
+ Debug.Put (" V_Stride => ");
+ Debug.Put_Int32 (Configs (Pipe).Framebuffer.V_Stride);
+ Debug.Put_Line (",");
+ Debug.Put (" Tiling => ");
+ Debug.Put_Line (Tilings (Configs (Pipe).Framebuffer.Tiling) & ",");
+ Debug.Put (" Rotation => ");
+ Debug.Put_Line (Rotations (Configs (Pipe).Framebuffer.Rotation) & ",");
Debug.Put (" Offset => ");
Debug.Put_Word32 (Configs (Pipe).Framebuffer.Offset);
Debug.Put_Line (",");
diff --git a/common/hw-gfx-gma.ads b/common/hw-gfx-gma.ads
index 77def8e..c35c687 100644
--- a/common/hw-gfx-gma.ads
+++ b/common/hw-gfx-gma.ads
@@ -177,14 +177,14 @@
Tile_Rows : constant array (Tiling_Type) of Pos32 :=
(Linear => 1, X_Tiled => 8, 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 FB_Pitch (Px : Pos_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
+ (FB.Width + FB.Start_X <= FB.Stride and
Pixel_To_Bytes (FB.Stride, FB) mod (Tile_Width (FB.Tiling) * 4) = 0 and
- FB.Height <= FB.V_Stride and
+ FB.Height + FB.Start_Y <= FB.V_Stride and
FB.V_Stride mod Tile_Rows (FB.Tiling) = 0);
end HW.GFX.GMA;
diff --git a/common/hw-gfx.ads b/common/hw-gfx.ads
index 5d8ae59..1ab2518 100644
--- a/common/hw-gfx.ads
+++ b/common/hw-gfx.ads
@@ -21,11 +21,13 @@
package HW.GFX is
-- such that the count of pixels in any framebuffer may fit
- subtype Pixel_Type is Pos32 range 1 .. 8192 * 8192;
+ subtype Pixel_Type is Int32 range 0 .. 8192 * 8192;
+ subtype Pos_Pixel_Type is Pixel_Type range 1 .. Pixel_Type'Last;
-- Allow same range for width and height (for rotated framebuffers)
subtype Width_Type is Pos32 range 1 .. 8192;
subtype Height_Type is Pos32 range 1 .. 8192;
+ subtype Pos_Type is Int32 range 0 .. 4095;
Auto_BPC : constant := 5;
subtype BPC_Type is Int64 range Auto_BPC .. 16;
@@ -39,6 +41,8 @@
record
Width : Width_Type;
Height : Height_Type;
+ Start_X : Pos_Type;
+ Start_Y : Pos_Type;
BPC : BPC_Type;
Stride : Width_Type;
V_Stride : Height_Type;
@@ -56,13 +60,15 @@
(if Rotation_90 (FB) then Pos16 (FB.Width) else Pos16 (FB.Height));
function Pixel_To_Bytes (Pixel : Pixel_Type; FB : Framebuffer_Type)
- return Pos32 is (Pixel * Pos32 (FB.BPC) / (8 / 4));
+ return Int32 is (Pixel * Pos32 (FB.BPC) / (8 / 4));
function FB_Size (FB : Framebuffer_Type) return Pos32 is
(Pixel_To_Bytes (FB.Stride * FB.V_Stride, FB));
Default_FB : constant Framebuffer_Type := Framebuffer_Type'
(Width => 1,
Height => 1,
+ Start_X => 0,
+ Start_Y => 0,
BPC => 8,
Stride => 1,
V_Stride => 1,