gma: Implement automatic CPU detection

In dynamic CPU configurations, Config.Detect_CPU() sets the CPU
variables according to the given PCI device id. In static confi-
gurations it does nothing.

We update the default configs to make use of this feature where
applicable. This should still give us full build-test coverage
while cutting the amount of tests in half.

Change-Id: I8ce31c867f97c8d6ef99ca096cb45f7719e78a19
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/libgfxinit/+/27138
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/common/Makefile.inc b/common/Makefile.inc
index ba48f85..7c5403b 100644
--- a/common/Makefile.inc
+++ b/common/Makefile.inc
@@ -79,6 +79,7 @@
 	    -e's/<\(ilk\|hsw\|skl\)\(...\)\?var>/$(_GEN_CONST_TARGET)/' \
 	    -e's/\(.*: *<cpufunc>.*:=\) *\(.*\);/\1\n     (\2);/' \
 	    -e's/\([^ ]\+\) *: *<cpufunc> \+\([^ ]*\) *:=/function \1 return \2 is/' \
+	    -e's/<cpunull>//' \
 	    $< >$@
 else
 $(hw-gfx-gma-config-ads): $(dir)/hw-gfx-gma-config.ads.template $(cnf)
@@ -93,18 +94,20 @@
 	    -e'/Dyn_CPU\(_Var\)\?/d' \
 	    -e's/<\(gen\|\(ilk\|hsw\|skl\)\(...\)\?\)bool>/constant Boolean/' \
 	    -e's/<\(\(ilk\|hsw\|skl\)\(...\)\?\)var>/constant/' \
+	    -e's/<cpunull>/ is null/' \
 	    $< >$@
 endif
 gfxinit-gen-y += $(hw-gfx-gma-config-ads)
+gfxinit-$(CONFIG_GFX_GMA_DYN_CPU) += dyncpu/hw-gfx-gma-config.adb
 
-ifneq ($(filter G45,$(CONFIG_GFX_GMA_CPU)),)
+ifneq ($(filter G45,$(CONFIG_GFX_GMA_GENERATION)),)
 subdirs-y += g45
-else ifneq ($(filter Ironlake Sandybridge Ivybridge,$(CONFIG_GFX_GMA_CPU)),)
+else ifneq ($(filter Ironlake,$(CONFIG_GFX_GMA_GENERATION)),)
 subdirs-y += ironlake
-else ifneq ($(filter Haswell Broadwell,$(CONFIG_GFX_GMA_CPU)),)
+else ifneq ($(filter Haswell,$(CONFIG_GFX_GMA_GENERATION)),)
 subdirs-y += haswell_shared haswell
-else ifneq ($(filter Broxton,$(CONFIG_GFX_GMA_CPU)),)
+else ifneq ($(filter Broxton,$(CONFIG_GFX_GMA_GENERATION)),)
 subdirs-y += haswell_shared broxton
-else ifneq ($(filter Skylake,$(CONFIG_GFX_GMA_CPU)),)
+else ifneq ($(filter Skylake,$(CONFIG_GFX_GMA_GENERATION)),)
 subdirs-y += haswell_shared skylake
 endif
diff --git a/common/dyncpu/hw-gfx-gma-config.adb b/common/dyncpu/hw-gfx-gma-config.adb
new file mode 100644
index 0000000..762ff6f
--- /dev/null
+++ b/common/dyncpu/hw-gfx-gma-config.adb
@@ -0,0 +1,31 @@
+--
+-- Copyright (C) 2018 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
+-- the Free Software Foundation; either version 2 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+
+package body HW.GFX.GMA.Config
+is
+
+   procedure Detect_CPU (Device : Word16) is
+   begin
+      for CPU in Gen_CPU_Type loop
+         for CPU_Var in Gen_CPU_Variant loop
+            if Is_GPU (Device, CPU, CPU_Var) then
+               Config.CPU := CPU;
+               Config.CPU_Var := CPU_Var;
+               exit;
+            end if;
+         end loop;
+      end loop;
+   end Detect_CPU;
+
+end HW.GFX.GMA.Config;
diff --git a/common/hw-gfx-gma-config.ads.template b/common/hw-gfx-gma-config.ads.template
index 044036e..721252b 100644
--- a/common/hw-gfx-gma-config.ads.template
+++ b/common/hw-gfx-gma-config.ads.template
@@ -361,4 +361,8 @@
    function Compatible_GPU (Device_Id : Word16) return Boolean is
      (Is_GPU (Device_Id, CPU, CPU_Var));
 
+   pragma Warnings (GNATprove, Off, "subprogram ""Detect_CPU"" has no effect",
+                    Reason => "only effective in dynamic cpu config");
+   procedure Detect_CPU (Device : Word16)<cpunull>;
+
 end HW.GFX.GMA.Config;
diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb
index 885072c..171d224 100644
--- a/common/hw-gfx-gma.adb
+++ b/common/hw-gfx-gma.adb
@@ -425,6 +425,7 @@
          Dev.Read16 (Vendor, PCI.Vendor_Id);
          Dev.Read16 (Device, PCI.Device_Id);
 
+         Config.Detect_CPU (Device);
          Success := Vendor = 16#8086# and Config.Compatible_GPU (Device);
       end Check_Platform_PCI;
    begin
@@ -443,29 +444,27 @@
             Cursor      => Default_Cursor,
             Mode        => HW.GFX.Invalid_Mode));
       Config.Variable := Config.Initial_Settings;
+      Registers.Set_Register_Base (Config.Default_MMIO_Base);
       PLLs.Initialize;
 
       Dev.Initialize (Success);
 
       if Success then
-         Dev.Map (PCI_MMIO_Base, PCI.Res0, Length => MMIO_GTT_Offset);
-         Dev.Map (PCI_GTT_Base, PCI.Res0, Offset => MMIO_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;
-
+         Check_Platform_PCI (Success);
          if Success then
-            Check_Platform_PCI (Success);
+            Dev.Map (PCI_MMIO_Base, PCI.Res0, Length => MMIO_GTT_Offset);
+            Dev.Map (PCI_GTT_Base, PCI.Res0, Offset => MMIO_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."));
+               Success := Config.Default_MMIO_Base_Set;
+            end if;
          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;
 
          if Success then
diff --git a/configs/broadwell b/configs/broadwell
deleted file mode 100644
index 06a6c2a..0000000
--- a/configs/broadwell
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG_GFX_GMA_GENERATION	= Haswell
-CONFIG_GFX_GMA_CPU		= Broadwell
-CONFIG_GFX_GMA_CPU_VARIANT	= Normal
-CONFIG_GFX_GMA_INTERNAL_PORT	= DP
-CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
-CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#
diff --git a/configs/broadwell_ult b/configs/broadwell_ult
deleted file mode 100644
index 105992a..0000000
--- a/configs/broadwell_ult
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG_GFX_GMA_GENERATION	= Haswell
-CONFIG_GFX_GMA_CPU		= Broadwell
-CONFIG_GFX_GMA_CPU_VARIANT	= ULT
-CONFIG_GFX_GMA_INTERNAL_PORT	= DP
-CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
-CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#
diff --git a/configs/broxton b/configs/broxton
index 35db833..5006125 100644
--- a/configs/broxton
+++ b/configs/broxton
@@ -1,3 +1,4 @@
+CONFIG_GFX_GMA_DYN_CPU		=
 CONFIG_GFX_GMA_GENERATION	= Broxton
 CONFIG_GFX_GMA_CPU		= Broxton
 CONFIG_GFX_GMA_CPU_VARIANT	= Normal	# N/A
diff --git a/configs/g45 b/configs/g45
index ef97850..9d2da64 100644
--- a/configs/g45
+++ b/configs/g45
@@ -1,6 +1,7 @@
+CONFIG_GFX_GMA_DYN_CPU		=
 CONFIG_GFX_GMA_GENERATION	= G45
 CONFIG_GFX_GMA_CPU		= G45
-CONFIG_GFX_GMA_CPU_VARIANT	= Normal
+CONFIG_GFX_GMA_CPU_VARIANT	= Normal	# N/A
 CONFIG_GFX_GMA_INTERNAL_PORT	= LVDS
 CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
 CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#
diff --git a/configs/haswell b/configs/haswell
index 8c025da..8adaafc 100644
--- a/configs/haswell
+++ b/configs/haswell
@@ -1,6 +1,5 @@
+CONFIG_GFX_GMA_DYN_CPU		= y
 CONFIG_GFX_GMA_GENERATION	= Haswell
-CONFIG_GFX_GMA_CPU		= Haswell
-CONFIG_GFX_GMA_CPU_VARIANT	= Normal
 CONFIG_GFX_GMA_INTERNAL_PORT	= DP
 CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
 CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#
diff --git a/configs/haswell_ult b/configs/haswell_ult
deleted file mode 100644
index 9559042..0000000
--- a/configs/haswell_ult
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG_GFX_GMA_GENERATION	= Haswell
-CONFIG_GFX_GMA_CPU		= Haswell
-CONFIG_GFX_GMA_CPU_VARIANT	= ULT
-CONFIG_GFX_GMA_INTERNAL_PORT	= DP
-CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
-CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#
diff --git a/configs/ironlake b/configs/ironlake
index 2c26a79..20b33a7 100644
--- a/configs/ironlake
+++ b/configs/ironlake
@@ -1,6 +1,5 @@
+CONFIG_GFX_GMA_DYN_CPU		= y
 CONFIG_GFX_GMA_GENERATION	= Ironlake
-CONFIG_GFX_GMA_CPU		= Ironlake
-CONFIG_GFX_GMA_CPU_VARIANT	= Normal
 CONFIG_GFX_GMA_INTERNAL_PORT	= LVDS
 CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
 CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#
diff --git a/configs/ivybridge_edp b/configs/ironlake_edp
similarity index 69%
rename from configs/ivybridge_edp
rename to configs/ironlake_edp
index 6ce8543..9bc56c3 100644
--- a/configs/ivybridge_edp
+++ b/configs/ironlake_edp
@@ -1,6 +1,5 @@
+CONFIG_GFX_GMA_DYN_CPU		= y
 CONFIG_GFX_GMA_GENERATION	= Ironlake
-CONFIG_GFX_GMA_CPU		= Ivybridge
-CONFIG_GFX_GMA_CPU_VARIANT	= Normal
 CONFIG_GFX_GMA_INTERNAL_PORT	= DP
 CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
 CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#
diff --git a/configs/ivybridge_lvds b/configs/ivybridge_lvds
deleted file mode 100644
index 31813f9..0000000
--- a/configs/ivybridge_lvds
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG_GFX_GMA_GENERATION	= Ironlake
-CONFIG_GFX_GMA_CPU		= Ivybridge
-CONFIG_GFX_GMA_CPU_VARIANT	= Normal
-CONFIG_GFX_GMA_INTERNAL_PORT	= LVDS
-CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
-CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#
diff --git a/configs/sandybridge b/configs/sandybridge
deleted file mode 100644
index 5cc15cd..0000000
--- a/configs/sandybridge
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG_GFX_GMA_GENERATION	= Ironlake
-CONFIG_GFX_GMA_CPU		= Sandybridge
-CONFIG_GFX_GMA_CPU_VARIANT	= Normal
-CONFIG_GFX_GMA_INTERNAL_PORT	= LVDS
-CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
-CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#
diff --git a/configs/skylake b/configs/skylake
index 26c9896..7ae760a 100644
--- a/configs/skylake
+++ b/configs/skylake
@@ -1,6 +1,5 @@
+CONFIG_GFX_GMA_DYN_CPU		= y
 CONFIG_GFX_GMA_GENERATION	= Skylake
-CONFIG_GFX_GMA_CPU		= Skylake
-CONFIG_GFX_GMA_CPU_VARIANT	= Normal
 CONFIG_GFX_GMA_INTERNAL_PORT	= DP
 CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
 CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#
diff --git a/configs/skylake_ult b/configs/skylake_ult
deleted file mode 100644
index c683251..0000000
--- a/configs/skylake_ult
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG_GFX_GMA_GENERATION	= Skylake
-CONFIG_GFX_GMA_CPU		= Skylake
-CONFIG_GFX_GMA_CPU_VARIANT	= ULT
-CONFIG_GFX_GMA_INTERNAL_PORT	= DP
-CONFIG_GFX_GMA_ANALOG_I2C_PORT	= PCH_DAC
-CONFIG_GFX_GMA_DEFAULT_MMIO	= 16\#e000_0000\#