Andrey Petrov (andrey.petrov@intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14519
-gerrit
commit 81658425a7867cd9d7c43fdb0c58675d02666dd4 Author: Abhay Kumar abhay.kumar@intel.com Date: Tue Mar 15 16:16:44 2016 -0700
soc/intel/apollolake: Add opregion code to pass vbt in kernel.
Change-Id: I47d01a56d242f0d3fcdb0fc5146500210ea6f48c Signed-off-by: Abhay Kumar abhay.kumar@intel.com Signed-off-by: Andrey Petrov andrey.petrov@intel.com --- src/drivers/intel/fsp2_0/graphics.c | 40 ++++++ src/drivers/intel/fsp2_0/include/fsp/util.h | 3 + src/soc/intel/apollolake/acpi.c | 105 ++++++++++++-- src/soc/intel/apollolake/include/soc/acpi.h | 1 + src/soc/intel/apollolake/include/soc/pci_ids.h | 10 ++ src/soc/intel/common/gma.h | 182 +++++++++++++++++++++++++ 6 files changed, 332 insertions(+), 9 deletions(-)
diff --git a/src/drivers/intel/fsp2_0/graphics.c b/src/drivers/intel/fsp2_0/graphics.c index 1480179..e52a5f4 100644 --- a/src/drivers/intel/fsp2_0/graphics.c +++ b/src/drivers/intel/fsp2_0/graphics.c @@ -54,6 +54,46 @@ static const struct fsp_framebuffer { [pixel_bgrx_8bpc] = { {16, 8}, {8, 8}, {0, 8}, {24, 8} }, };
+/* Reading VBT table from flash */ +const optionrom_vbt_t *fsp_get_vbt(uint32_t *vbt_len) +{ + size_t vbt_size; + union { + const optionrom_vbt_t *data; + uint32_t *signature; + } vbt; + + /* Locate the vbt file in cbfs */ + vbt.data = cbfs_boot_map_with_leak("vbt.bin", CBFS_TYPE_RAW, + &vbt_size); + if (!vbt.data) { + printk(BIOS_INFO, + "FSP_INFO: VBT data file (vbt.bin) not found in CBFS"); + return NULL; + } + + /* Validate the vbt file */ + if (*vbt.signature != VBT_SIGNATURE) { + printk(BIOS_WARNING, + "FSP_WARNING: Invalid signature in VBT data file (vbt.bin)!\n"); + return NULL; + } + *vbt_len = vbt_size; + printk(BIOS_DEBUG, "FSP_INFO: VBT found at %p, 0x%08x bytes\n", + vbt.data, *vbt_len); + +#if IS_ENABLED(CONFIG_DISPLAY_VBT) + /* Display the vbt file contents */ + printk(BIOS_DEBUG, "VBT Data:\n"); + hexdump(vbt.data, *vbt_len); + printk(BIOS_DEBUG, "\n"); +#endif + + /* Return the pointer to the vbt file data */ + return vbt.data; +} + + enum cb_err fsp_fill_lb_framebuffer(struct lb_framebuffer *framebuffer) { size_t size; diff --git a/src/drivers/intel/fsp2_0/include/fsp/util.h b/src/drivers/intel/fsp2_0/include/fsp/util.h index d9d9539..fe0e359 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/util.h +++ b/src/drivers/intel/fsp2_0/include/fsp/util.h @@ -16,6 +16,9 @@ #include <boot/coreboot_tables.h> #include <fsp/info_header.h> #include <memrange.h> +#include <soc/intel/common/gma.h> + +const optionrom_vbt_t *fsp_get_vbt(uint32_t *vbt_len);
/* * Hand-off-block handling functions that depend on CBMEM, and thus can only diff --git a/src/soc/intel/apollolake/acpi.c b/src/soc/intel/apollolake/acpi.c index a300417..cd7937b 100644 --- a/src/soc/intel/apollolake/acpi.c +++ b/src/soc/intel/apollolake/acpi.c @@ -25,6 +25,22 @@ #include <soc/iomap.h> #include <soc/pm.h> #include <soc/nvs.h> +#include <vendorcode/google/chromeos/gnvs.h> +#include <fsp/util.h> +#include <soc/pci_ids.h> +#include <string.h> +#include <fsp/util.h> +#include <device/pci.h> + + +static void acpi_create_gnvs(struct global_nvs_t *gnvs) +{ + if(IS_ENABLED(CONFIG_CHROMEOS)) { + /* Initialize Verified Boot data */ + chromeos_init_vboot(&(gnvs->chromeos)); + gnvs->chromeos.vbt2 = ACTIVE_ECFW_RO; + } +}
unsigned long acpi_fill_mcfg(unsigned long current) { @@ -35,6 +51,78 @@ unsigned long acpi_fill_mcfg(unsigned long current) return current; }
+ +/* Reading VBT table from flash */ +static void get_fsp_vbt(igd_opregion_t *opregion) +{ + const optionrom_vbt_t *vbt; + uint32_t vbt_len; + + vbt = fsp_get_vbt(&vbt_len); + if (!vbt) + die("vbt data not found"); + memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild, 4); + memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size < + sizeof(opregion->vbt.gvd1) ? vbt->hdr_vbt_size : + sizeof(opregion->vbt.gvd1)); +} + + +static int init_igd_opregion(igd_opregion_t *opregion) +{ + device_t igd; + u16 reg16; + + memset(opregion, 0, sizeof(igd_opregion_t)); + + /* FIXME if IGD is disabled, we should exit here. */ + + memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE, + sizeof(IGD_OPREGION_SIGNATURE)); + + /* 8kb */ + opregion->header.size = sizeof(igd_opregion_t) / 1024; + opregion->header.version = IGD_OPREGION_VERSION; + + /* FIXME We just assume we're mobile for now */ + opregion->header.mailboxes = MAILBOXES_MOBILE; + + /* TODO Initialize Mailbox 1 */ + + /* TODO Initialize Mailbox 3 */ + opregion->mailbox3.bclp = IGD_BACKLIGHT_BRIGHTNESS; + opregion->mailbox3.pfit = IGD_FIELD_VALID | IGD_PFIT_STRETCH; + opregion->mailbox3.pcft = 0; /* should be (IMON << 1) & 0x3e */ + opregion->mailbox3.cblv = IGD_FIELD_VALID | IGD_INITIAL_BRIGHTNESS; + opregion->mailbox3.bclm[0] = IGD_WORD_FIELD_VALID + 0x0000; + opregion->mailbox3.bclm[1] = IGD_WORD_FIELD_VALID + 0x0a19; + opregion->mailbox3.bclm[2] = IGD_WORD_FIELD_VALID + 0x1433; + opregion->mailbox3.bclm[3] = IGD_WORD_FIELD_VALID + 0x1e4c; + opregion->mailbox3.bclm[4] = IGD_WORD_FIELD_VALID + 0x2866; + opregion->mailbox3.bclm[5] = IGD_WORD_FIELD_VALID + 0x327f; + opregion->mailbox3.bclm[6] = IGD_WORD_FIELD_VALID + 0x3c99; + opregion->mailbox3.bclm[7] = IGD_WORD_FIELD_VALID + 0x46b2; + opregion->mailbox3.bclm[8] = IGD_WORD_FIELD_VALID + 0x50cc; + opregion->mailbox3.bclm[9] = IGD_WORD_FIELD_VALID + 0x5ae5; + opregion->mailbox3.bclm[10] = IGD_WORD_FIELD_VALID + 0x64ff; + + get_fsp_vbt(opregion); + + /* + * TODO This needs to happen in S3 resume, too. + * Maybe it should move to the finalize handler + */ + igd = dev_find_slot(0, PCI_DEVFN(GFX_DEV, GFX_FUNC)); + + pci_write_config32(igd, ASLS, (u32)opregion); + reg16 = pci_read_config16(igd, SWSCI); + reg16 &= ~(1 << 0); + reg16 |= (1 << 15); + pci_write_config16(igd, SWSCI, reg16); + + return 0; +} + static int acpi_sci_irq(void) { int sci_irq = 9; @@ -126,16 +214,15 @@ unsigned long southbridge_write_acpi_tables(device_t device, unsigned long current, struct acpi_rsdp *rsdp) { - return acpi_write_hpet(device, current, rsdp); -} + current = acpi_write_hpet(device, current, rsdp);
-static void acpi_create_gnvs(struct global_nvs_t *gnvs) -{ - if(IS_ENABLED(CONFIG_CHROMEOS)) { - /* Initialize Verified Boot data */ - chromeos_init_vboot(&(gnvs->chromeos)); - gnvs->chromeos.vbt2 = ACTIVE_ECFW_RO; - } + igd_opregion_t *opregion; + printk(BIOS_DEBUG, "ACPI: * IGD OpRegion\n"); + opregion = (igd_opregion_t *)current; + init_igd_opregion(opregion); + current += sizeof(igd_opregion_t); + + return acpi_align_current(current); }
void southbridge_inject_dsdt(device_t device) diff --git a/src/soc/intel/apollolake/include/soc/acpi.h b/src/soc/intel/apollolake/include/soc/acpi.h index 3605cc3..1f5663f 100644 --- a/src/soc/intel/apollolake/include/soc/acpi.h +++ b/src/soc/intel/apollolake/include/soc/acpi.h @@ -19,6 +19,7 @@ #define _SOC_APOLLOLAKE_ACPI_H_
#include <arch/acpi.h> +#include <soc/nvs.h>
void soc_fill_common_fadt(acpi_fadt_t * fadt);
diff --git a/src/soc/intel/apollolake/include/soc/pci_ids.h b/src/soc/intel/apollolake/include/soc/pci_ids.h index 148640f..458c24e 100644 --- a/src/soc/intel/apollolake/include/soc/pci_ids.h +++ b/src/soc/intel/apollolake/include/soc/pci_ids.h @@ -41,4 +41,14 @@ #define PCI_DEVICE_ID_APOLLOLAKE_SPI2 0x5ac6 /* 00:19.2 */ #define PCI_DEVICE_ID_APOLLOLAKE_LPC 0x5ae8 /* 00:1f.0 */
+/* Graphics and Display */ +#define GFX_DEV 0x2 +#define GFX_FUNC 0 +#define GFX_DEVID 0x5a84 + +/* System Agent Devices */ +#define SA_DEV_SLOT_IGD 0x02 +#define SA_DEVFN_IGD _SA_DEVFN(IGD) +#define SA_DEV_IGD _SA_DEV(IGD) + #endif /* _SOC_APOLLOLAKE_PCI_IDS_H_ */ diff --git a/src/soc/intel/common/gma.h b/src/soc/intel/common/gma.h new file mode 100644 index 0000000..1079bc8 --- /dev/null +++ b/src/soc/intel/common/gma.h @@ -0,0 +1,182 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 Chromium OS Authors + * Copyright (C) 2015 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#ifndef _GMA_H_ +#define _GMA_H_ + +#include <types.h> + +/* IGD PCI Configuration register */ +#define ASLS 0xfc /* OpRegion Base */ +#define SWSCI 0xe8 /* SWSCI Register */ +#define GSSCIE (1 << 0) /* SCI Event trigger */ +#define SMISCISEL (1 << 15) /* Select SMI or SCI event source */ + +/* mailbox 0: header */ +typedef struct { + u8 signature[16]; + u32 size; + u32 version; + u8 sbios_version[32]; + u8 vbios_version[16]; + u8 driver_version[16]; + u32 mailboxes; + u8 reserved[164]; +} __attribute__((packed)) opregion_header_t; + +#define IGD_OPREGION_SIGNATURE "IntelGraphicsMem" +#define IGD_OPREGION_VERSION 2 + +#define IGD_MBOX1 (1 << 0) +#define IGD_MBOX2 (1 << 1) +#define IGD_MBOX3 (1 << 2) +#define IGD_MBOX4 (1 << 3) +#define IGD_MBOX5 (1 << 4) + +#define MAILBOXES_MOBILE (IGD_MBOX1 | IGD_MBOX2 | IGD_MBOX3 | \ + IGD_MBOX4 | IGD_MBOX5) +#define MAILBOXES_DESKTOP (IGD_MBOX2 | IGD_MBOX4) + +#define SBIOS_VERSION_SIZE 32 + +/* mailbox 1: public acpi methods */ +typedef struct { + u32 drdy; + u32 csts; + u32 cevt; + u8 reserved1[20]; + u32 didl[8]; + u32 cpdl[8]; + u32 cadl[8]; + u32 nadl[8]; + u32 aslp; + u32 tidx; + u32 chpd; + u32 clid; + u32 cdck; + u32 sxsw; + u32 evts; + u32 cnot; + u32 nrdy; + u8 reserved2[60]; +} __attribute__((packed)) opregion_mailbox1_t; + +/* mailbox 2: software sci interface */ +typedef struct { + u32 scic; + u32 parm; + u32 dslp; + u8 reserved[244]; +} __attribute__((packed)) opregion_mailbox2_t; + +/* mailbox 3: power conservation */ +typedef struct { + u32 ardy; + u32 aslc; + u32 tche; + u32 alsi; + u32 bclp; + u32 pfit; + u32 cblv; + u16 bclm[20]; + u32 cpfm; + u32 epfm; + u8 plut[74]; + u32 pfmb; + u32 ccdv; + u32 pcft; + u8 reserved[94]; +} __attribute__((packed)) opregion_mailbox3_t; + +#define IGD_BACKLIGHT_BRIGHTNESS 0xff +#define IGD_INITIAL_BRIGHTNESS 0x64 + +#define IGD_FIELD_VALID (1 << 31) +#define IGD_WORD_FIELD_VALID (1 << 15) +#define IGD_PFIT_STRETCH 6 + +/* mailbox 4: vbt */ +typedef struct { + u8 gvd1[7168]; +} __attribute__((packed)) opregion_vbt_t; + +/* IGD OpRegion */ +typedef struct { + opregion_header_t header; + opregion_mailbox1_t mailbox1; + opregion_mailbox2_t mailbox2; + opregion_mailbox3_t mailbox3; + opregion_vbt_t vbt; +} __attribute__((packed)) igd_opregion_t; + +/* Intel Video BIOS (Option ROM) */ +typedef struct { + u16 signature; + u8 size; + u8 reserved[21]; + u16 pcir_offset; + u16 vbt_offset; +} __attribute__((packed)) optionrom_header_t; + +#define OPROM_SIGNATURE 0xaa55 + +typedef struct { + u32 signature; + u16 vendor; + u16 device; + u16 reserved1; + u16 length; + u8 revision; + u8 classcode[3]; + u16 imagelength; + u16 coderevision; + u8 codetype; + u8 indicator; + u16 reserved2; +} __attribute__((packed)) optionrom_pcir_t; + +typedef struct { + u8 hdr_signature[20]; + u16 hdr_version; + u16 hdr_size; + u16 hdr_vbt_size; + u8 hdr_vbt_checksum; + u8 hdr_reserved; + u32 hdr_vbt_datablock; + u32 hdr_aim[4]; + u8 datahdr_signature[16]; + u16 datahdr_version; + u16 datahdr_size; + u16 datahdr_datablocksize; + u8 coreblock_id; + u16 coreblock_size; + u16 coreblock_biossize; + u8 coreblock_biostype; + u8 coreblock_releasestatus; + u8 coreblock_hwsupported; + u8 coreblock_integratedhw; + u8 coreblock_biosbuild[4]; + u8 coreblock_biossignon[155]; +} __attribute__((packed)) optionrom_vbt_t; + +#define VBT_SIGNATURE 0x54425624 + +#endif /* _GMA_H_ */ +