diff --git a/src/northbridge/intel/gm45/gma.c b/src/northbridge/intel/gm45/gma.c index 00b3fa0a2b..bdad49bae8 100644 --- a/src/northbridge/intel/gm45/gma.c +++ b/src/northbridge/intel/gm45/gma.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "drivers/intel/gma/i915_reg.h" #include "chip.h" @@ -32,6 +34,7 @@ #include #include #include +#include #include #include @@ -49,6 +52,19 @@ void gtt_write(u32 reg, u32 data) write32(res2mmio(gtt_res, reg, 0), data); } +uintptr_t gma_get_gnvs_aslb(const void *gnvs) +{ + const global_nvs_t *gnvs_ptr = gnvs; + return (uintptr_t)(gnvs_ptr ? gnvs_ptr->aslb : 0); +} + +void gma_set_gnvs_aslb(void *gnvs, uintptr_t aslb) +{ + global_nvs_t *gnvs_ptr = gnvs; + if (gnvs_ptr) + gnvs_ptr->aslb = aslb; +} + static void gma_init_lvds(const struct northbridge_intel_gm45_config *info, u8 *mmio, u32 physbase, u16 piobase, u32 lfb, struct edid *edid) @@ -758,6 +774,8 @@ static void gma_func0_init(struct device *dev) if (IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT)) gma_ngi(dev, &edid_lvds); + + intel_gma_restore_opregion(); } static void gma_set_subsystem(device_t dev, unsigned vendor, unsigned device) @@ -793,6 +811,37 @@ static void gma_ssdt(device_t device) drivers_intel_gma_displays_ssdt_generate(gfx); } +static unsigned long +gma_write_acpi_tables(struct device *const dev, + unsigned long current, + struct acpi_rsdp *const rsdp) +{ + igd_opregion_t *opregion = (igd_opregion_t *)current; + global_nvs_t *gnvs; + + if (intel_gma_init_igd_opregion(opregion) != CB_SUCCESS) + return current; + + current += sizeof(igd_opregion_t); + + /* GNVS has been already set up */ + gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); + if (gnvs) { + /* IGD OpRegion Base Address */ + gma_set_gnvs_aslb(gnvs, (uintptr_t)opregion); + } else { + printk(BIOS_ERR, "Error: GNVS table not found.\n"); + } + + current = acpi_align_current(current); + return current; +} + +static const char *gma_acpi_name(const struct device *dev) +{ + return "GFX0"; +} + static struct pci_operations gma_pci_ops = { .set_subsystem = gma_set_subsystem, }; @@ -806,6 +855,8 @@ static struct device_operations gma_func0_ops = { .scan_bus = 0, .enable = 0, .ops_pci = &gma_pci_ops, + .acpi_name = gma_acpi_name, + .write_acpi_tables = gma_write_acpi_tables, }; static const unsigned short pci_device_ids[] = diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c index 37f73ed0eb..8d60bc91fc 100644 --- a/src/northbridge/intel/i945/gma.c +++ b/src/northbridge/intel/i945/gma.c @@ -23,10 +23,13 @@ #include #include #include +#include #include #include #include #include +#include +#include #include "i945.h" #include "chip.h" @@ -49,6 +52,19 @@ #define DEFAULT_BLC_PWM 180 +uintptr_t gma_get_gnvs_aslb(const void *gnvs) +{ + const global_nvs_t *gnvs_ptr = gnvs; + return (uintptr_t)(gnvs_ptr ? gnvs_ptr->aslb : 0); +} + +void gma_set_gnvs_aslb(void *gnvs, uintptr_t aslb) +{ + global_nvs_t *gnvs_ptr = gnvs; + if (gnvs_ptr) + gnvs_ptr->aslb = aslb; +} + static int gtt_setup(u8 *mmiobase) { unsigned long PGETBL_save; @@ -687,6 +703,8 @@ static void gma_func0_init(struct device *dev) /* PCI Init, will run VBIOS */ pci_dev_init(dev); } + + intel_gma_restore_opregion(); } /* This doesn't reclaim stolen UMA memory, but IGD could still @@ -767,6 +785,37 @@ static void gma_func0_read_resources(device_t dev) pci_dev_read_resources(dev); } +static unsigned long +gma_write_acpi_tables(struct device *const dev, + unsigned long current, + struct acpi_rsdp *const rsdp) +{ + igd_opregion_t *opregion = (igd_opregion_t *)current; + global_nvs_t *gnvs; + + if (intel_gma_init_igd_opregion(opregion) != CB_SUCCESS) + return current; + + current += sizeof(igd_opregion_t); + + /* GNVS has been already set up */ + gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); + if (gnvs) { + /* IGD OpRegion Base Address */ + gma_set_gnvs_aslb(gnvs, (uintptr_t)opregion); + } else { + printk(BIOS_ERR, "Error: GNVS table not found.\n"); + } + + current = acpi_align_current(current); + return current; +} + +static const char *gma_acpi_name(const struct device *dev) +{ + return "GFX0"; +} + static struct pci_operations gma_pci_ops = { .set_subsystem = gma_set_subsystem, }; @@ -781,6 +830,8 @@ static struct device_operations gma_func0_ops = { .enable = 0, .disable = gma_func0_disable, .ops_pci = &gma_pci_ops, + .acpi_name = gma_acpi_name, + .write_acpi_tables = gma_write_acpi_tables, }; diff --git a/src/northbridge/intel/x4x/gma.c b/src/northbridge/intel/x4x/gma.c index db96facbef..cf3804d50c 100644 --- a/src/northbridge/intel/x4x/gma.c +++ b/src/northbridge/intel/x4x/gma.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "drivers/intel/gma/i915_reg.h" #include "chip.h" @@ -33,11 +34,31 @@ #include #include #include +#include #include #include +#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_I82801JX) +#include +#elif IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_I82801GX) +#include +#endif + #define BASE_FREQUENCY 96000 +uintptr_t gma_get_gnvs_aslb(const void *gnvs) +{ + const global_nvs_t *gnvs_ptr = gnvs; + return (uintptr_t)(gnvs_ptr ? gnvs_ptr->aslb : 0); +} + +void gma_set_gnvs_aslb(void *gnvs, uintptr_t aslb) +{ + global_nvs_t *gnvs_ptr = gnvs; + if (gnvs_ptr) + gnvs_ptr->aslb = aslb; +} + static u8 edid_is_present(u8 *edid, u32 edid_size) { u32 i; @@ -395,6 +416,8 @@ static void gma_func0_init(struct device *dev) } else { pci_dev_init(dev); } + + intel_gma_restore_opregion(); } static void gma_func0_disable(struct device *dev) @@ -439,6 +462,37 @@ static void gma_ssdt(device_t device) drivers_intel_gma_displays_ssdt_generate(gfx); } +static unsigned long +gma_write_acpi_tables(struct device *const dev, + unsigned long current, + struct acpi_rsdp *const rsdp) +{ + igd_opregion_t *opregion = (igd_opregion_t *)current; + global_nvs_t *gnvs; + + if (intel_gma_init_igd_opregion(opregion) != CB_SUCCESS) + return current; + + current += sizeof(igd_opregion_t); + + /* GNVS has been already set up */ + gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); + if (gnvs) { + /* IGD OpRegion Base Address */ + gma_set_gnvs_aslb(gnvs, (uintptr_t)opregion); + } else { + printk(BIOS_ERR, "Error: GNVS table not found.\n"); + } + + current = acpi_align_current(current); + return current; +} + +static const char *gma_acpi_name(const struct device *dev) +{ + return "GFX0"; +} + static struct pci_operations gma_pci_ops = { .set_subsystem = gma_set_subsystem, }; @@ -451,6 +505,8 @@ static struct device_operations gma_func0_ops = { .init = gma_func0_init, .ops_pci = &gma_pci_ops, .disable = gma_func0_disable, + .acpi_name = gma_acpi_name, + .write_acpi_tables = gma_write_acpi_tables, }; static const unsigned short pci_device_ids[] = {