Nico Huber has uploaded this change for review. ( https://review.coreboot.org/22866
Change subject: Add Start_X and Start_Y offsets for framebuffer panning ......................................................................
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 --- M common/hw-gfx-gma-config_helpers.ads M common/hw-gfx-gma-pipe_setup.adb M common/hw-gfx-gma-pipe_setup.ads M common/hw-gfx-gma.adb M common/hw-gfx-gma.ads M common/hw-gfx.ads M gfxtest/hw-gfx-gma-gfx_test.adb 7 files changed, 86 insertions(+), 33 deletions(-)
git pull ssh://review.coreboot.org:29418/libgfxinit refs/changes/66/22866/1
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 4dc6e2b..e64edc9 100644 --- a/common/hw-gfx-gma-pipe_setup.adb +++ b/common/hw-gfx-gma-pipe_setup.adb @@ -157,7 +157,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; @@ -172,11 +172,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, @@ -208,7 +210,10 @@ if Config.Has_DSP_Linoff then Registers.Write (Controller.DSPLINOFF, 0); end if; - Registers.Write (Controller.DSPTILEOFF, 0); + Registers.Write + (Register => Controller.DSPTILEOFF, + Value => Shift_Left (Word32 (FB.Start_Y), 16) or + Word32 (FB.Start_X)); end if; end Setup_Hires_Plane;
@@ -232,7 +237,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 b325000..420c1a3 100644 --- a/common/hw-gfx-gma.adb +++ b/common/hw-gfx-gma.adb @@ -721,6 +721,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 =>"); @@ -734,15 +749,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 c59b392..77536d4 100644 --- a/common/hw-gfx-gma.ads +++ b/common/hw-gfx-gma.ads @@ -180,9 +180,9 @@ (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..30e6e56 100644 --- a/common/hw-gfx.ads +++ b/common/hw-gfx.ads @@ -26,6 +26,7 @@ -- 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 +40,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; @@ -63,6 +66,8 @@ Default_FB : constant Framebuffer_Type := Framebuffer_Type' (Width => 1, Height => 1, + Start_X => 0, + Start_Y => 0, BPC => 8, Stride => 1, V_Stride => 1, diff --git a/gfxtest/hw-gfx-gma-gfx_test.adb b/gfxtest/hw-gfx-gma-gfx_test.adb index cb09c63..833240f 100644 --- a/gfxtest/hw-gfx-gma-gfx_test.adb +++ b/gfxtest/hw-gfx-gma-gfx_test.adb @@ -14,6 +14,9 @@ is pragma Disable_Atomic_Synchronization;
+ Start_X : constant := 0; + Start_Y : constant := 0; + package Dev is new PCI.Dev (PCI.Address'(0, 2, 0));
type GTT_PTE_Type is mod 2 ** (Config.GTT_PTE_Size * 8); @@ -105,6 +108,12 @@ end loop; end Restore_Screen;
+ function Drawing_Width (FB : Framebuffer_Type) return Natural is + (Natural (FB.Width + 2 * Start_X)); + + function Drawing_Height (FB : Framebuffer_Type) return Natural is + (Natural (FB.Height + 2 * Start_Y)); + function Corner_Fill (X, Y : Natural; FB : Framebuffer_Type; @@ -112,9 +121,9 @@ return Pixel_Type is Xrel : constant Integer := - (if X < 32 then X else X - (Natural (FB.Width) - 32)); + (if X < 32 then X else X - (Drawing_Width (FB) - 32)); Yrel : constant Integer := - (if Y < 32 then Y else Y - (Natural (FB.Height) - 32)); + (if Y < 32 then Y else Y - (Drawing_Height (FB) - 32));
function Color (Idx : Natural) return Pixel_Type is (case (Idx + Pipe_Index'Pos (Pipe)) mod 4 is @@ -138,8 +147,8 @@ is use type HW.Byte;
- Xp : constant Natural := X * 256 / Natural (Framebuffer.Width); - Yp : constant Natural := Y * 256 / Natural (Framebuffer.Height); + Xp : constant Natural := X * 256 / Drawing_Width (Framebuffer); + Yp : constant Natural := Y * 256 / Drawing_Height (Framebuffer); Xn : constant Natural := 255 - Xp; Yn : constant Natural := 255 - Yp;
@@ -166,22 +175,22 @@
function Top_Test (X, Y : Natural) return Boolean is - C : constant Natural := Natural (Framebuffer.Width) / 2; - S_Y : constant Natural := 3 * Y / 2; + C : constant Natural := Drawing_Width (Framebuffer) / 2; + S_Y : constant Natural := 3 * (Y - Start_Y) / 2; Left : constant Integer := X - C + S_Y; Right : constant Integer := X - C - S_Y; begin return - Y < 12 and + (Y - Start_Y) < 12 and ((-1 <= Left and Left <= 0) or (0 <= Right and Right <= 1)); end Top_Test; begin - for Y in 0 .. Natural (Framebuffer.Height) - 1 loop + for Y in 0 .. Drawing_Height (Framebuffer) - 1 loop Offset := Offset_Y; - for X in 0 .. Natural (Framebuffer.Width) - 1 loop - if (X < 32 or X >= Natural (Framebuffer.Width) - 32) and - (Y < 32 or Y >= Natural (Framebuffer.Height) - 32) + for X in 0 .. Drawing_Width (Framebuffer) - 1 loop + if (X < 32 or X >= Drawing_Width (Framebuffer) - 32) and + (Y < 32 or Y >= Drawing_Height (Framebuffer) - 32) then P := Corner_Fill (X, Y, Framebuffer, Pipe); elsif Framebuffer.Rotation /= No_Rotation and then @@ -206,25 +215,31 @@ Rotation : in Rotation_Type; Offset : in out Word32) is + Width : constant Width_Type := Width_Type (Mode.H_Visible); + Height : constant Height_Type := Height_Type (Mode.V_Visible); begin Offset := (Offset + FB_Align - 1) and not (FB_Align - 1); if Rotation = Rotated_90 or Rotation = Rotated_270 then FB := - (Width => Width_Type (Mode.V_Visible), - Height => Height_Type (Mode.H_Visible), + (Width => Width_Type (Height), + Height => Height_Type (Width), + Start_X => Start_X, + Start_Y => Start_Y, BPC => 8, - Stride => Div_Round_Up (Pos32 (Mode.V_Visible), 32) * 32, - V_Stride => Div_Round_Up (Pos32 (Mode.H_Visible), 32) * 32, + Stride => Div_Round_Up (Pos32 (Height + 2 * Start_X), 32) * 32, + V_Stride => Div_Round_Up (Pos32 (Width + 2 * Start_Y), 32) * 32, Tiling => Y_Tiled, Rotation => Rotation, Offset => Offset + Word32 (GTT_Rotation_Offset) * GTT_Page_Size); else FB := - (Width => Width_Type (Mode.H_Visible), - Height => Width_Type (Mode.V_Visible), + (Width => Width, + Height => Height, + Start_X => Start_X, + Start_Y => Start_Y, BPC => 8, - Stride => Div_Round_Up (Pos32 (Mode.H_Visible), 16) * 16, - V_Stride => Height_Type (Mode.V_Visible), + Stride => Div_Round_Up (Width + 2 * Start_X, 16) * 16, + V_Stride => Height + 2 * Start_Y, Tiling => Linear, Rotation => Rotation, Offset => Offset);