gma: Add a HW.PCI.Dev for dynamic MMIO setup

Remove `MMIO_Base` option from Initialize() and try to derive it
using libhwbase' PCI mechanism instead.

Change-Id: Iacd4d098954bb96c1c6b40fdfb2636191d9517c7
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/20600
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/common/hw-gfx-gma-config.ads.template b/common/hw-gfx-gma-config.ads.template
index dea26b8..b4e52f6 100644
--- a/common/hw-gfx-gma-config.ads.template
+++ b/common/hw-gfx-gma-config.ads.template
@@ -35,6 +35,8 @@
 
    ----------------------------------------------------------------------------
 
+   Default_MMIO_Base_Set   : constant Boolean := Default_MMIO_Base /= 0;
+
    Has_Internal_Display    : constant Boolean := Internal_Display /= None;
    Internal_Is_EDP         : constant Boolean := Internal_Display = DP;
    Has_Presence_Straps     : constant Boolean := CPU /= Broxton;
diff --git a/common/hw-gfx-gma-registers.adb b/common/hw-gfx-gma-registers.adb
index e240152..9e52c78 100644
--- a/common/hw-gfx-gma-registers.adb
+++ b/common/hw-gfx-gma-registers.adb
@@ -290,11 +290,15 @@
 
    ----------------------------------------------------------------------------
 
-   procedure Set_Register_Base (Base : Word64)
+   procedure Set_Register_Base (Base : Word64; GTT_Base : Word64 := 0)
    is
    begin
       Regs.Set_Base_Address (Base);
-      GTT.Set_Base_Address (Base + Config.GTT_Offset);
+      if GTT_Base = 0 then
+         GTT.Set_Base_Address (Base + Config.GTT_Offset);
+      else
+         GTT.Set_Base_Address (GTT_Base);
+      end if;
    end Set_Register_Base;
 
 end HW.GFX.GMA.Registers;
diff --git a/common/hw-gfx-gma-registers.ads b/common/hw-gfx-gma-registers.ads
index e526417..63df8be 100644
--- a/common/hw-gfx-gma-registers.ads
+++ b/common/hw-gfx-gma-registers.ads
@@ -1541,10 +1541,10 @@
       Post    => True;
    pragma Warnings (On, "declaration of ""Write_GTT"" hides one at *");
 
-   procedure Set_Register_Base (Base : Word64)
+   procedure Set_Register_Base (Base : Word64; GTT_Base : Word64 := 0)
    with
       Global   => (Output => Address_State),
-      Depends  => (Address_State => Base),
+      Depends  => (Address_State => (Base, GTT_Base)),
       Pre      => True,
       Post     => True;
 
diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb
index 1aecfab..387d6bd 100644
--- a/common/hw-gfx-gma.adb
+++ b/common/hw-gfx-gma.adb
@@ -1,5 +1,6 @@
 --
 -- Copyright (C) 2014-2017 secunet Security Networks AG
+-- Copyright (C) 2017 Nico Huber <nico.h@gmx.de>
 --
 -- This program is free software; you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
@@ -12,6 +13,11 @@
 -- GNU General Public License for more details.
 --
 
+with HW.MMIO_Range;
+pragma Elaborate_All (HW.MMIO_Range);
+with HW.PCI.Dev;
+pragma Elaborate_All (HW.PCI.Dev);
+
 with HW.GFX.GMA.Config;
 with HW.GFX.GMA.Config_Helpers;
 with HW.GFX.GMA.Registers;
@@ -23,8 +29,6 @@
 with HW.GFX.GMA.Connector_Info;
 with HW.GFX.GMA.Pipe_Setup;
 
-with System;
-
 with HW.Debug;
 with GNAT.Source_Info;
 
@@ -33,15 +37,17 @@
 package body HW.GFX.GMA
    with Refined_State =>
      (State =>
-        (Registers.Address_State,
+        (Dev.Address_State,
+         Registers.Address_State,
          PLLs.State, Panel.Panel_State,
          Cur_Configs, Allocated_PLLs,
          HPD_Delay, Wait_For_HPD),
       Init_State => Initialized,
       Config_State => Config.Valid_Port_GPU,
       Device_State =>
-        (Registers.Register_State, Registers.GTT_State))
+        (Dev.PCI_State, Registers.Register_State, Registers.GTT_State))
 is
+   pragma Disable_Atomic_Synchronization;
 
    subtype Port_Name is String (1 .. 8);
    type Port_Name_Array is array (Port_Type) of Port_Name;
@@ -56,6 +62,8 @@
       HDMI3    => "HDMI3   ",
       Analog   => "Analog  ");
 
+   package Dev is new HW.PCI.Dev (PCI.Address'(0, 2, 0));
+
    package Display_Controller renames Pipe_Setup;
 
    type PLLs_Type is array (Pipe_Index) of PLLs.T;
@@ -287,8 +295,7 @@
    ----------------------------------------------------------------------------
 
    procedure Initialize
-     (MMIO_Base   : in     Word64 := 0;
-      Write_Delay : in     Word64 := 0;
+     (Write_Delay : in     Word64 := 0;
       Clean_State : in     Boolean := False;
       Success     :    out Boolean)
    with
@@ -299,13 +306,16 @@
          Input =>
            (Time.State),
          Output =>
-           (Registers.Address_State,
+           (Dev.Address_State,
+            Registers.Address_State,
             PLLs.State, Panel.Panel_State,
             Cur_Configs, Allocated_PLLs,
             HPD_Delay, Wait_For_HPD, Initialized))
    is
       use type HW.Word64;
 
+      PCI_MMIO_Base, PCI_GTT_Base : Word64;
+
       Now : constant Time.T := Time.Now;
 
       procedure Check_Platform (Success : out Boolean)
@@ -345,14 +355,32 @@
            (Port        => Disabled,
             Framebuffer => HW.GFX.Default_FB,
             Mode        => HW.GFX.Invalid_Mode));
-      Registers.Set_Register_Base
-        (if MMIO_Base /= 0 then
-            MMIO_Base
-         else
-            Config.Default_MMIO_Base);
       PLLs.Initialize;
 
-      Check_Platform (Success);
+      Dev.Initialize (Success);
+
+      if Success then
+         Dev.Map (PCI_MMIO_Base, PCI.Res0, Length => Config.GTT_Offset);
+         Dev.Map (PCI_GTT_Base, PCI.Res0, Offset => Config.GTT_Offset);
+         if PCI_MMIO_Base /= 0 and PCI_GTT_Base /= 0 then
+            Registers.Set_Register_Base (PCI_MMIO_Base, PCI_GTT_Base);
+         else
+            pragma Debug (Debug.Put_Line
+              ("ERROR: Couldn't map resoure0."));
+            Registers.Set_Register_Base (Config.Default_MMIO_Base);
+            Success := Config.Default_MMIO_Base_Set;
+         end if;
+      else
+         pragma Debug (Debug.Put_Line
+           ("WARNING: Couldn't initialize PCI dev."));
+         Registers.Set_Register_Base (Config.Default_MMIO_Base);
+         Success := Config.Default_MMIO_Base_Set;
+      end if;
+
+      if Success then
+         Check_Platform (Success);
+      end if;
+
       if not Success then
          pragma Debug (Debug.Put_Line ("ERROR: Incompatible CPU or PCH."));
 
diff --git a/common/hw-gfx-gma.ads b/common/hw-gfx-gma.ads
index c8fc398..8285dcb 100644
--- a/common/hw-gfx-gma.ads
+++ b/common/hw-gfx-gma.ads
@@ -62,8 +62,7 @@
    VGA_PLANE_FRAMEBUFFER_OFFSET : constant := 16#ffff_ffff#;
 
    procedure Initialize
-     (MMIO_Base   : in     Word64 := 0;
-      Write_Delay : in     Word64 := 0;
+     (Write_Delay : in     Word64 := 0;
       Clean_State : in     Boolean := False;
       Success     :    out Boolean)
    with