diff --git a/3rdparty/libgfxinit b/3rdparty/libgfxinit index 83693c8d7d..6a3566773f 160000 --- a/3rdparty/libgfxinit +++ b/3rdparty/libgfxinit @@ -1 +1 @@ -Subproject commit 83693c8d7d87f5cebe120abdf25951c9e212b319 +Subproject commit 6a3566773f3b52550ebf0d042154958a2403bb40 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