gma: Add Setup_Default_FB()

Add new public procedure Setup_Default_FB() to configure a framebuffer
in stolen memory. The optional parameter `Clear` tells it to clear the
configured framebuffer.

Also remove Setup_Default_GTT() from the public interface.

Change-Id: I6ece4f56bbd34126ef34f0107d5ccdbde8a007ac
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/20603
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
diff --git a/common/Makefile.inc b/common/Makefile.inc
index 0f34127..fc985b3 100644
--- a/common/Makefile.inc
+++ b/common/Makefile.inc
@@ -42,8 +42,8 @@
 gfxinit-y += hw-gfx-gma.ads
 gfxinit-y += hw-gfx-i2c.ads
 gfxinit-y += hw-gfx.ads
-gfxinit-$(CONFIG_HWBASE_DYNAMIC_MMIO) += hw-gfx-framebuffer_filler.adb
-gfxinit-$(CONFIG_HWBASE_DYNAMIC_MMIO) += hw-gfx-framebuffer_filler.ads
+gfxinit-y += hw-gfx-framebuffer_filler.adb
+gfxinit-y += hw-gfx-framebuffer_filler.ads
 
 CONFIG_GFX_GMA_CPU		:= $(call strip_quotes,$(CONFIG_GFX_GMA_CPU))
 CONFIG_GFX_GMA_CPU_VARIANT	:= $(call strip_quotes,$(CONFIG_GFX_GMA_CPU_VARIANT))
diff --git a/common/hw-gfx-framebuffer_filler.adb b/common/hw-gfx-framebuffer_filler.adb
index e55e9be..250d903 100644
--- a/common/hw-gfx-framebuffer_filler.adb
+++ b/common/hw-gfx-framebuffer_filler.adb
@@ -12,6 +12,7 @@
 -- GNU General Public License for more details.
 --
 
+with HW.Config;
 with HW.MMIO_Range;
 pragma Elaborate_All (HW.MMIO_Range);
 
@@ -27,6 +28,10 @@
    is
       Line_Start : Int32 := 0;
    begin
+      if not HW.Config.Dynamic_MMIO then
+         return;
+      end if;
+
       FB.Set_Base_Address (Linear_FB);
       for Line in 0 .. Framebuffer.Height - 1 loop
          pragma Loop_Invariant (Line_Start = Line * Framebuffer.Stride);
diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb
index dae8d27..f9cbb10 100644
--- a/common/hw-gfx-gma.adb
+++ b/common/hw-gfx-gma.adb
@@ -18,6 +18,8 @@
 with HW.PCI.Dev;
 pragma Elaborate_All (HW.PCI.Dev);
 
+with HW.GFX.Framebuffer_Filler;
+
 with HW.GFX.GMA.Config;
 with HW.GFX.GMA.Config_Helpers;
 with HW.GFX.GMA.Registers;
@@ -429,15 +431,39 @@
 
    ----------------------------------------------------------------------------
 
+   function FB_First_Page (FB : Framebuffer_Type) return Natural is
+     (Natural (FB.Offset / GTT_Page_Size));
+   function FB_Pages (FB : Framebuffer_Type) return Natural is
+     (Natural (Div_Round_Up (FB_Size (FB), GTT_Page_Size)));
+   function FB_Last_Page (FB : Framebuffer_Type) return Natural is
+     (FB_First_Page (FB) + FB_Pages (FB) - 1);
+
+   -- 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);
+
+   -- Also check that we don't overflow the GTT's 39-bit space
+   -- (always true with a 32-bit base)
+   function Valid_Phys_FB (FB : Framebuffer_Type; Phys_Base : Word32)
+      return Boolean is
+     (Valid_FB (FB) and
+      Int64 (Phys_Base) + Int64 (FB.Offset) + Int64 (FB_Size (FB)) <=
+         Int64 (GTT_Address_Type'Last))
+   with
+      Ghost;
+
    procedure Write_GTT
      (GTT_Page       : GTT_Range;
       Device_Address : GTT_Address_Type;
-      Valid          : Boolean) is
+      Valid          : Boolean)
+   is
    begin
       Registers.Write_GTT (GTT_Page, Device_Address, Valid);
    end Write_GTT;
 
    procedure Setup_Default_GTT (FB : Framebuffer_Type; Phys_Base : Word32)
+   with
+      Pre => Is_Initialized and Valid_Phys_FB (FB, Phys_Base)
    is
       Phys_Addr : GTT_Address_Type :=
          GTT_Address_Type (Phys_Base) + GTT_Address_Type (FB.Offset);
@@ -453,6 +479,46 @@
 
    ----------------------------------------------------------------------------
 
+   procedure Setup_Default_FB
+     (FB       : in     Framebuffer_Type;
+      Clear    : in     Boolean := True;
+      Success  :    out Boolean)
+   is
+      GMA_Phys_Base      : constant PCI.Index := 16#5c#;
+      GMA_Phys_Base_Mask : constant := 16#fff0_0000#;
+
+      Phys_Base : Word32;
+   begin
+      Success := Valid_FB (FB);
+
+      if Success then
+         Dev.Read32 (Phys_Base, GMA_Phys_Base);
+         Phys_Base := Phys_Base and GMA_Phys_Base_Mask;
+         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
+            Setup_Default_GTT (FB, Phys_Base);
+         end if;
+      end if;
+
+      if Success and then Clear then
+         declare
+            use type HW.Word64;
+            Linear_FB : Word64;
+         begin
+            Dev.Map (Linear_FB, PCI.Res2);
+            if Linear_FB /= 0 then
+               Framebuffer_Filler.Fill (Linear_FB + Word64 (FB.Offset), FB);
+            end if;
+            pragma Debug
+              (Linear_FB = 0, Debug.Put_Line ("Failed to map resource2."));
+         end;
+      end if;
+   end Setup_Default_FB;
+
+   ----------------------------------------------------------------------------
+
    procedure Dump_Configs (Configs : Pipe_Configs)
    is
       subtype Pipe_Name is String (1 .. 9);
diff --git a/common/hw-gfx-gma.ads b/common/hw-gfx-gma.ads
index a91c83b..5b66803 100644
--- a/common/hw-gfx-gma.ads
+++ b/common/hw-gfx-gma.ads
@@ -94,32 +94,12 @@
       Device_Address : GTT_Address_Type;
       Valid          : Boolean);
 
-   ----------------------------------------------------------------------------
-
-   function FB_First_Page (FB : Framebuffer_Type) return Natural is
-     (Natural (FB.Offset / GTT_Page_Size));
-   function FB_Pages (FB : Framebuffer_Type) return Natural is
-     (Natural (Div_Round_Up (FB_Size (FB), GTT_Page_Size)));
-   function FB_Last_Page (FB : Framebuffer_Type) return Natural is
-     (FB_First_Page (FB) + FB_Pages (FB) - 1);
-
-   -- 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);
-
-   -- Also check that we don't overflow the GTT's 39-bit space
-   -- (always true with a 32-bit base)
-   function Valid_Phys_FB (FB : Framebuffer_Type; Phys_Base : Word32)
-      return Boolean is
-     (Valid_FB (FB) and
-      Int64 (Phys_Base) + Int64 (FB.Offset) + Int64 (FB_Size (FB)) <=
-         Int64 (GTT_Address_Type'Last))
+   procedure Setup_Default_FB
+     (FB       : in     Framebuffer_Type;
+      Clear    : in     Boolean := True;
+      Success  :    out Boolean)
    with
-      Ghost;
-
-   procedure Setup_Default_GTT (FB : Framebuffer_Type; Phys_Base : Word32)
-   with
-      Pre => Is_Initialized and Valid_Phys_FB (FB, Phys_Base);
+      Pre => Is_Initialized and HW.Config.Dynamic_MMIO;
 
 private