summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/device/Kconfig19
-rw-r--r--src/drivers/intel/gma/Kconfig51
-rw-r--r--src/drivers/intel/gma/Makefile.inc23
-rw-r--r--src/drivers/intel/gma/gma.adb117
-rw-r--r--src/drivers/intel/gma/gma.ads43
-rw-r--r--src/drivers/intel/gma/i915.h3
6 files changed, 255 insertions, 1 deletions
diff --git a/src/device/Kconfig b/src/device/Kconfig
index c7dfe9cff2..dd31cba4fd 100644
--- a/src/device/Kconfig
+++ b/src/device/Kconfig
@@ -24,7 +24,7 @@ config MAINBOARD_HAS_NATIVE_VGA_INIT
# FIXME Ugly hack to allow Z9s driver native framebuffer configuration
config NATIVE_VGA_INIT_USE_EDID
bool
- default n if DRIVERS_XGI_Z9S
+ default n if DRIVERS_XGI_Z9S || MAINBOARD_USE_LIBGFXINIT
default y if !DRIVERS_XGI_Z9S
config MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG
@@ -42,6 +42,23 @@ config MAINBOARD_DO_NATIVE_VGA_INIT
If unsure, say N.
+config MAINBOARD_HAS_LIBGFXINIT
+ def_bool n
+ select MAINBOARD_HAS_NATIVE_VGA_INIT
+ help
+ Selected by mainboards that implement support for `libgfxinit`.
+ Usually this requires a list of ports to be probed for displays.
+
+config MAINBOARD_USE_LIBGFXINIT
+ bool "Use libgfxinit for native graphics initialization"
+ depends on MAINBOARD_DO_NATIVE_VGA_INIT
+ depends on MAINBOARD_HAS_LIBGFXINIT
+ select RAMSTAGE_LIBHWBASE
+ default n
+ help
+ Use the SPARK library `libgfxinit` for the native graphics
+ initialization. This requires an Ada toolchain.
+
# TODO: Explain differences (if any) for onboard cards.
config VGA_ROM_RUN
bool "Run VGA Option ROMs"
diff --git a/src/drivers/intel/gma/Kconfig b/src/drivers/intel/gma/Kconfig
index 1cfab3dd27..9c0f22783c 100644
--- a/src/drivers/intel/gma/Kconfig
+++ b/src/drivers/intel/gma/Kconfig
@@ -36,3 +36,54 @@ config INTEL_INT15
config INTEL_GMA_ACPI
bool
default n
+
+config GFX_GMA_CPU
+ string
+ default "Skylake" if SOC_INTEL_SKYLAKE
+ default "Broadwell" if SOC_INTEL_BROADWELL
+ default "Haswell" if NORTHBRIDGE_INTEL_HASWELL
+ default "Ivybridge" if NORTHBRIDGE_INTEL_IVYBRIDGE
+ default "Sandybridge" if NORTHBRIDGE_INTEL_SANDYBRIDGE
+ default "Ironlake" if NORTHBRIDGE_INTEL_NEHALEM
+
+config GFX_GMA_CPU_VARIANT
+ string
+ default "ULT" if (SOC_INTEL_SKYLAKE && !SKYLAKE_SOC_PCH_H) || SOC_INTEL_BROADWELL || NORTHBRIDGE_INTEL_HASWELL
+ default "Normal"
+
+config GFX_GMA_INTERNAL_IS_EDP
+ bool
+ default n if GFX_GMA_INTERNAL_IS_LVDS
+ default y
+
+config GFX_GMA_INTERNAL_IS_LVDS
+ bool
+ default n
+
+config GFX_GMA_INTERNAL_PORT
+ string
+ default "DP" if GFX_GMA_INTERNAL_IS_EDP
+ default "LVDS"
+
+config GFX_GMA_ANALOG_I2C_HDMI_B
+ bool
+ default n
+
+config GFX_GMA_ANALOG_I2C_HDMI_C
+ bool
+ default n
+
+config GFX_GMA_ANALOG_I2C_HDMI_D
+ bool
+ default n
+
+config GFX_GMA_ANALOG_I2C_PORT
+ string
+ default "PCH_HDMI_B" if GFX_GMA_ANALOG_I2C_HDMI_B
+ default "PCH_HDMI_C" if GFX_GMA_ANALOG_I2C_HDMI_C
+ default "PCH_HDMI_D" if GFX_GMA_ANALOG_I2C_HDMI_D
+ default "PCH_DAC"
+ help
+ Boards with a DVI-I connector share the I2C pins for both analog and
+ digital displays. In that case, the EDID for a VGA display has to be
+ read over the I2C interface of the coupled digital port.
diff --git a/src/drivers/intel/gma/Makefile.inc b/src/drivers/intel/gma/Makefile.inc
index 88b91f6a20..a4e007c373 100644
--- a/src/drivers/intel/gma/Makefile.inc
+++ b/src/drivers/intel/gma/Makefile.inc
@@ -20,3 +20,26 @@ ifeq ($(CONFIG_VGA_ROM_RUN),y)
ramstage-$(CONFIG_INTEL_INT15) += int15.c
endif
ramstage-$(CONFIG_INTEL_GMA_ACPI) += acpi.c
+
+
+ifeq ($(CONFIG_MAINBOARD_USE_LIBGFXINIT),y)
+
+$(call add-special-class,gfxinit)
+gfxinit-handler = $(eval ramstage-srcs += $(1)$(2))
+
+$(call add-special-class,gfxinit-gen)
+gfxinit-gen-handler = \
+ $(eval additional-dirs += $(dir $(2))) \
+ $(eval ramstage-srcs += $(2)) \
+ $(eval ramstage-ads-deps += $(2)) \
+ $(eval ramstage-adb-deps += $(2)) \
+ $(eval $(2): $(obj)/config.h)
+
+CONFIG_GFX_GMA_DEFAULT_MMIO := 0 # dummy, will be overwritten at runtime
+
+subdirs-y += ../../../../3rdparty/libgfxinit
+
+ramstage-y += gma.ads
+ramstage-y += gma.adb
+
+endif # CONFIG_MAINBOARD_USE_LIBGFXINIT
diff --git a/src/drivers/intel/gma/gma.adb b/src/drivers/intel/gma/gma.adb
new file mode 100644
index 0000000000..7ebc4f88bc
--- /dev/null
+++ b/src/drivers/intel/gma/gma.adb
@@ -0,0 +1,117 @@
+with HW.GFX;
+with HW.GFX.Framebuffer_Filler;
+with HW.GFX.GMA;
+
+use HW.GFX;
+use HW.GFX.GMA;
+
+with GMA.Mainboard;
+
+package body GMA
+is
+
+ vbe_valid : boolean := false;
+
+ linear_fb_addr : word64;
+
+ fb : Framebuffer_Type;
+
+ function vbe_mode_info_valid return Interfaces.C.int
+ is
+ begin
+ return (if vbe_valid then 1 else 0);
+ end vbe_mode_info_valid;
+
+ procedure fill_lb_framebuffer (framebuffer : out lb_framebuffer)
+ is
+ use type word32;
+ begin
+ framebuffer :=
+ (tag => 0,
+ size => 0,
+ physical_address => linear_fb_addr,
+ x_resolution => word32 (fb.Width),
+ y_resolution => word32 (fb.Height),
+ bytes_per_line => 4 * word32 (fb.Stride),
+ bits_per_pixel => 32,
+ reserved_mask_pos => 24,
+ reserved_mask_size => 8,
+ red_mask_pos => 16,
+ red_mask_size => 8,
+ green_mask_pos => 8,
+ green_mask_size => 8,
+ blue_mask_pos => 0,
+ blue_mask_size => 8);
+ 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
+ use type pos32;
+
+ ports : Port_List;
+ configs : Configs_Type;
+
+ success : boolean;
+
+ stride : Width_Type;
+ max_h : pos16 := 1;
+ max_v : pos16 := 1;
+ 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, ports);
+
+ if configs (Primary).Port /= Disabled then
+ for i in Config_Index loop
+ exit when configs (i).Port = Disabled;
+
+ max_h := pos16'max (max_h, configs (i).Mode.H_Visible);
+ max_v := pos16'max (max_v, configs (i).Mode.V_Visible);
+ end loop;
+
+ stride := ((Width_Type (max_h) + 63) / 64) * 64;
+ for i in Config_Index loop
+ exit when configs (i).Port = Disabled;
+
+ configs (i).Framebuffer :=
+ (Width => Width_Type (configs (i).Mode.H_Visible),
+ Height => Height_Type (configs (i).Mode.V_Visible),
+ BPC => 8,
+ Stride => stride,
+ Offset => 0);
+ end loop;
+
+ HW.GFX.GMA.Dump_Configs (configs);
+
+ fb :=
+ (Width => Width_Type (max_h),
+ Height => Height_Type (max_v),
+ BPC => 8,
+ Stride => stride,
+ Offset => 0);
+ HW.GFX.GMA.Setup_Default_GTT (fb, phys_fb);
+ HW.GFX.Framebuffer_Filler.Fill (linear_fb, fb);
+
+ HW.GFX.GMA.Update_Outputs (configs);
+
+ linear_fb_addr := linear_fb;
+ vbe_valid := true;
+
+ lightup_ok := 1;
+ end if;
+ end if;
+ end gfxinit;
+
+end GMA;
diff --git a/src/drivers/intel/gma/gma.ads b/src/drivers/intel/gma/gma.ads
new file mode 100644
index 0000000000..d912df1635
--- /dev/null
+++ b/src/drivers/intel/gma/gma.ads
@@ -0,0 +1,43 @@
+with Interfaces.C;
+
+with HW;
+use HW;
+
+package GMA
+is
+
+ procedure gfxinit
+ (mmio_base : in word64;
+ linear_fb : in word64;
+ phys_fb : in word32;
+ lightup_ok : out Interfaces.C.int);
+ pragma Export (C, gfxinit, "gma_gfxinit");
+
+ ----------------------------------------------------------------------------
+
+ function vbe_mode_info_valid return Interfaces.C.int;
+ pragma Export (C, vbe_mode_info_valid, "vbe_mode_info_valid");
+
+ type lb_framebuffer is record
+ tag : word32;
+ size : word32;
+
+ physical_address : word64;
+ x_resolution : word32;
+ y_resolution : word32;
+ bytes_per_line : word32;
+ bits_per_pixel : word8;
+ red_mask_pos : word8;
+ red_mask_size : word8;
+ green_mask_pos : word8;
+ green_mask_size : word8;
+ blue_mask_pos : word8;
+ blue_mask_size : word8;
+ reserved_mask_pos : word8;
+ reserved_mask_size : word8;
+ end record;
+
+ procedure fill_lb_framebuffer (framebuffer : out lb_framebuffer);
+ pragma Export (C, fill_lb_framebuffer, "fill_lb_framebuffer");
+
+end GMA;
diff --git a/src/drivers/intel/gma/i915.h b/src/drivers/intel/gma/i915.h
index e0d665bca9..d9bb940fa4 100644
--- a/src/drivers/intel/gma/i915.h
+++ b/src/drivers/intel/gma/i915.h
@@ -309,4 +309,7 @@ void
generate_fake_intel_oprom(const struct i915_gpu_controller_info *conf,
struct device *dev, const char *idstr);
+/* interface to libgfxinit (gma.adb) */
+void gma_gfxinit(u64 mmio_base, u64 linear_fb, u32 phys_fb, int *success);
+
#endif