drivers/intel/gma: Add textmode support with libgfxinit

Add an alternative gfxinit implementation for textmode. The legacy VGA
plane and textmode is configured through coreboot provided functions.
libgfxinit uses this plane as alternative to the usual high resolution
plane.

Change-Id: Iad0754c50fc6faec35f49583fe1c7cb50ac6c0c5
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/17279
Tested-by: build bot (Jenkins)
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/src/device/Kconfig b/src/device/Kconfig
index d238547..c90da89 100644
--- a/src/device/Kconfig
+++ b/src/device/Kconfig
@@ -53,6 +53,7 @@
 	bool "Use libgfxinit for native graphics initialization"
 	depends on MAINBOARD_DO_NATIVE_VGA_INIT
 	depends on MAINBOARD_HAS_LIBGFXINIT
+	select MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG
 	select RAMSTAGE_LIBHWBASE
 	default n
 	help
diff --git a/src/drivers/intel/gma/Makefile.inc b/src/drivers/intel/gma/Makefile.inc
index a4e007c..d4d6c08 100644
--- a/src/drivers/intel/gma/Makefile.inc
+++ b/src/drivers/intel/gma/Makefile.inc
@@ -40,6 +40,10 @@
 subdirs-y += ../../../../3rdparty/libgfxinit
 
 ramstage-y += gma.ads
-ramstage-y += gma.adb
+ifeq ($(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE),y)
+ramstage-y += hires_fb/gma.adb
+else
+ramstage-y += text_fb/gma.adb
+endif
 
 endif # CONFIG_MAINBOARD_USE_LIBGFXINIT
diff --git a/src/drivers/intel/gma/gma.adb b/src/drivers/intel/gma/hires_fb/gma.adb
similarity index 100%
rename from src/drivers/intel/gma/gma.adb
rename to src/drivers/intel/gma/hires_fb/gma.adb
diff --git a/src/drivers/intel/gma/text_fb/gma.adb b/src/drivers/intel/gma/text_fb/gma.adb
new file mode 100644
index 0000000..bbb6d74
--- /dev/null
+++ b/src/drivers/intel/gma/text_fb/gma.adb
@@ -0,0 +1,75 @@
+with HW.GFX;
+with HW.GFX.GMA;
+
+use HW.GFX;
+use HW.GFX.GMA;
+
+with GMA.Mainboard;
+
+package body GMA
+is
+
+   function vbe_mode_info_valid return Interfaces.C.int
+   is
+   begin
+      return 0;
+   end vbe_mode_info_valid;
+
+   procedure fill_lb_framebuffer (framebuffer : out lb_framebuffer)
+   is
+   begin
+      null;
+   end fill_lb_framebuffer;
+
+   ----------------------------------------------------------------------------
+
+   procedure gfxinit
+     (mmio_base   : in     word64;
+      linear_fb   : in     word64;
+      phys_fb     : in     word32;
+      lightup_ok  :    out Interfaces.C.int)
+   is
+      ports : Port_List;
+      configs : Configs_Type;
+
+      success : boolean;
+
+      -- from pc80/vga driver
+      procedure vga_io_init;
+      pragma Import (C, vga_io_init, "vga_io_init");
+      procedure vga_textmode_init;
+      pragma Import (C, vga_textmode_init, "vga_textmode_init");
+   begin
+      lightup_ok := 0;
+
+      HW.GFX.GMA.Initialize
+        (MMIO_Base   => mmio_base,
+         Success     => success);
+
+      if success then
+         ports := Mainboard.ports;
+         HW.GFX.GMA.Scan_Ports
+           (Configs  => configs,
+            Ports    => ports,
+            Max_Pipe => Primary);
+
+         if configs (Primary).Port /= Disabled then
+            vga_io_init;
+            vga_textmode_init;
+
+            configs (Primary).Framebuffer :=
+              (Width    => 640,
+               Height   => 400,
+               BPC      => Auto_BPC,   -- ignored for VGA plane
+               Stride   => 320,        -- ignored
+               Offset   => VGA_PLANE_FRAMEBUFFER_OFFSET);
+
+            HW.GFX.GMA.Dump_Configs (configs);
+            HW.GFX.GMA.Update_Outputs (configs);
+
+            lightup_ok := 1;
+         end if;
+      end if;
+   end gfxinit;
+
+end GMA;