From 542e9488bd3f084c373e89e869aeca84aaa8c66c Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Wed, 5 Oct 2016 17:47:32 +0200 Subject: drivers/intel/gma: Hook up libgfxinit Add `libgfxinit` as another option for native graphics initialization. For that, the function gma_gfxinit() (see drivers/intel/gma/i915.h) has to be called by the respective northbridge/soc code. A mainboard port needs to select `CONFIG_MAINBOARD_HAS_LIBGFXINIT` and implement the Ada package `GMA.Mainboard` with a single function `ports` that returns a list of ports to be probed for displays. v2: Update 3rdparty/libgfxinit to its latest master commit to make things buildable within coreboot. v3: Another update to 3rdparty/libgfxinit. Including support to select the I2C port for VGA. Change-Id: I4c7be3745f32853797d3f3689396dde07d4ca950 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/16952 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Ronald G. Minnich --- src/drivers/intel/gma/Kconfig | 51 ++++++++++++++++ src/drivers/intel/gma/Makefile.inc | 23 ++++++++ src/drivers/intel/gma/gma.adb | 117 +++++++++++++++++++++++++++++++++++++ src/drivers/intel/gma/gma.ads | 43 ++++++++++++++ src/drivers/intel/gma/i915.h | 3 + 5 files changed, 237 insertions(+) create mode 100644 src/drivers/intel/gma/gma.adb create mode 100644 src/drivers/intel/gma/gma.ads (limited to 'src/drivers/intel/gma') 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 -- cgit v1.2.3