From 2b074d90ae0d20f2d3171f2ddc5d0b6c0d3b78b0 Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Thu, 17 Aug 2017 14:25:24 -0700 Subject: soc/intel/cannonlake: Add common ACPI support for CNL Basic ACPI support for CNL on top of common ACPI, which will establish a root of FADT table, fill MADT entry, create gnvs field, record wake status and convert device names into DSDT dev definitions. Change-Id: Ibc16d2afdd3cb9bad2ecb85cf320c88504409707 Signed-off-by: Lijian Zhao Reviewed-on: https://review.coreboot.org/21076 Reviewed-by: Aaron Durbin Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/Kconfig | 3 + src/soc/intel/cannonlake/Makefile.inc | 1 + src/soc/intel/cannonlake/acpi.c | 117 +++++++++++++++++++++ src/soc/intel/cannonlake/acpi/globalnvs.asl | 57 ++++++++++ src/soc/intel/cannonlake/chip.c | 65 ++++++++++++ src/soc/intel/cannonlake/chip.h | 6 ++ .../intel/cannonlake/include/soc/gpio_soc_defs.h | 1 + src/soc/intel/cannonlake/include/soc/nvs.h | 50 +++++++++ src/soc/intel/cannonlake/include/soc/pm.h | 8 +- src/soc/intel/cannonlake/include/soc/pmc.h | 2 + src/soc/intel/cannonlake/pmutil.c | 28 ----- 11 files changed, 307 insertions(+), 31 deletions(-) create mode 100644 src/soc/intel/cannonlake/acpi.c create mode 100644 src/soc/intel/cannonlake/acpi/globalnvs.asl create mode 100644 src/soc/intel/cannonlake/include/soc/nvs.h (limited to 'src/soc') diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index 9525ab488d..fe80a20d67 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -15,6 +15,7 @@ config CPU_SPECIFIC_OPTIONS select BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY if BOOT_DEVICE_SPI_FLASH select BOOT_DEVICE_SUPPORTS_WRITES select C_ENVIRONMENT_BOOTBLOCK + select COMMON_FADT select CPU_INTEL_FIRMWARE_INTERFACE_TABLE select GENERIC_GPIO_LIB select HAVE_HARD_RESET @@ -30,7 +31,9 @@ config CPU_SPECIFIC_OPTIONS select RELOCATABLE_RAMSTAGE select SMP select SOC_INTEL_COMMON + select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE select SOC_INTEL_COMMON_BLOCK + select SOC_INTEL_COMMON_BLOCK_ACPI select SOC_INTEL_COMMON_BLOCK_CAR select SOC_INTEL_COMMON_BLOCK_CPU select SOC_INTEL_COMMON_BLOCK_CPU_MPINIT diff --git a/src/soc/intel/cannonlake/Makefile.inc b/src/soc/intel/cannonlake/Makefile.inc index f75a669266..0490bf927b 100644 --- a/src/soc/intel/cannonlake/Makefile.inc +++ b/src/soc/intel/cannonlake/Makefile.inc @@ -26,6 +26,7 @@ romstage-y += reset.c romstage-y += spi.c romstage-$(CONFIG_UART_DEBUG) += uart.c +ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c ramstage-y += gpio.c diff --git a/src/soc/intel/cannonlake/acpi.c b/src/soc/intel/cannonlake/acpi.c new file mode 100644 index 0000000000..4e2a02787f --- /dev/null +++ b/src/soc/intel/cannonlake/acpi.c @@ -0,0 +1,117 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 coresystems GmbH + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2017 Intel Corporation. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void soc_fill_fadt(acpi_fadt_t *fadt) +{ + const uint16_t pmbase = ACPI_BASE_ADDRESS; + const struct device *dev = PCH_DEV_LPC; + const struct soc_intel_cannonlake_config *config = dev->chip_info; + + if (config->PmTimerDisabled != 0) + return; + + fadt->pm_tmr_blk = pmbase + PM1_TMR; + fadt->pm_tmr_len = 4; + fadt->x_pm_tmr_blk.space_id = 1; + fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8; + fadt->x_pm_tmr_blk.bit_offset = 0; + fadt->x_pm_tmr_blk.resv = 0; + fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR; + fadt->x_pm_tmr_blk.addrh = 0x0; +} +uint32_t soc_read_sci_irq_select(void) +{ + uintptr_t pmc_bar = soc_read_pmc_base(); + return read32((void *)pmc_bar + IRQ_REG); +} + +void acpi_create_gnvs(struct global_nvs_t *gnvs) +{ + const struct device *dev = PCH_DEV_LPC; + const struct soc_intel_cannonlake_config *config = dev->chip_info; + + /* Set unknown wake source */ + gnvs->pm1i = -1; + + /* CPU core count */ + gnvs->pcnt = dev_count_cpu(); + + if (IS_ENABLED(CONFIG_CONSOLE_CBMEM)) + /* Update the mem console pointer. */ + gnvs->cbmc = (uintptr_t)cbmem_find(CBMEM_ID_CONSOLE); + + if (IS_ENABLED(CONFIG_CHROMEOS)) { + /* Initialize Verified Boot data */ + chromeos_init_vboot(&(gnvs->chromeos)); + if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)) { + gnvs->chromeos.vbt2 = google_ec_running_ro() ? + ACTIVE_ECFW_RO : ACTIVE_ECFW_RW; + } else + gnvs->chromeos.vbt2 = ACTIVE_ECFW_RO; + } + + /* Enable DPTF based on mainboard configuration */ + gnvs->dpte = config->dptf_enable; + + /* Fill in the Wifi Region id */ + gnvs->cid1 = wifi_regulatory_domain(); + + /* Set USB2/USB3 wake enable bitmaps. */ + gnvs->u2we = config->usb2_wake_enable_bitmap; + gnvs->u3we = config->usb3_wake_enable_bitmap; +} + +uint32_t acpi_fill_soc_wake(uint32_t generic_pm1_en, + const struct chipset_power_state *ps) +{ + /* + * WAK_STS bit is set when the system is in one of the sleep states + * (via the SLP_EN bit) and an enabled wake event occurs. Upon setting + * this bit, the PMC will transition the system to the ON state and + * can only be set by hardware and can only be cleared by writing a one + * to this bit position. + */ + + generic_pm1_en |= WAK_STS | RTC_EN | PWRBTN_EN; + return generic_pm1_en; +} + +int soc_madt_sci_irq_polarity(int sci) +{ + return MP_IRQ_POLARITY_HIGH; +} diff --git a/src/soc/intel/cannonlake/acpi/globalnvs.asl b/src/soc/intel/cannonlake/acpi/globalnvs.asl new file mode 100644 index 0000000000..ac60b36d51 --- /dev/null +++ b/src/soc/intel/cannonlake/acpi/globalnvs.asl @@ -0,0 +1,57 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. + * + * 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. + */ + +/* Global Variables */ + +Name (\PICM, 0) // IOAPIC/8259 + +/* + * Global ACPI memory region. This region is used for passing information + * between coreboot (aka "the system bios"), ACPI, and the SMI handler. + * Since we don't know where this will end up in memory at ACPI compile time, + * we have to fix it up in coreboot's ACPI creation phase. + */ + +External (NVSA) + +OperationRegion (GNVS, SystemMemory, NVSA, 0x2000) +Field (GNVS, ByteAcc, NoLock, Preserve) +{ + /* Miscellaneous */ + Offset (0x00), + OSYS, 16, // 0x00 - Operating System + SMIF, 8, // 0x02 - SMI function + PCNT, 8, // 0x03 - Processor Count + PPCM, 8, // 0x04 - Max PPC State + TLVL, 8, // 0x05 - Throttle Level Limit + LIDS, 8, // 0x06 - LID State + PWRS, 8, // 0x07 - AC Power State + CBMC, 32, // 0x08 - 0x0b AC Power State + PM1I, 64, // 0x0c - 0x13 PM1 wake status bit + GPEI, 64, // 0x14 - 0x17 GPE wake status bit + DPTE, 8, // 0x1c - Enable DPTF + NHLA, 64, // 0x1d - 0x24 NHLT Address + NHLL, 32, // 0x25 - 0x28 NHLT Length + CID1, 16, // 0x29 - 0x2a Wifi Country Identifier + U2WE, 16, // 0x2b - 0x2c USB2 Wake Enable Bitmap + U3WE, 16, // 0x2d - 0x2e USB3 Wake Enable Bitmap + UIOR, 8, // 0x2f - UART debug controller init on S3 resume + + /* ChromeOS specific */ + Offset (0x100), + #include +} diff --git a/src/soc/intel/cannonlake/chip.c b/src/soc/intel/cannonlake/chip.c index bee2517e73..ab546337e4 100644 --- a/src/soc/intel/cannonlake/chip.c +++ b/src/soc/intel/cannonlake/chip.c @@ -24,6 +24,68 @@ #include #include +#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) +static const char *soc_acpi_name(struct device *dev) +{ + if (dev->path.type == DEVICE_PATH_DOMAIN) + return "PCI0"; + + if (dev->path.type != DEVICE_PATH_PCI) + return NULL; + + switch (dev->path.pci.devfn) { + case SA_DEVFN_ROOT: return "MCHC"; + case SA_DEVFN_IGD: return "GFX0"; + case PCH_DEVFN_ISH: return "ISHB"; + case PCH_DEVFN_XHCI: return "XHCI"; + case PCH_DEVFN_USBOTG: return "XDCI"; + case PCH_DEVFN_THERMAL: return "THRM"; + case PCH_DEVFN_I2C0: return "I2C0"; + case PCH_DEVFN_I2C1: return "I2C1"; + case PCH_DEVFN_I2C2: return "I2C2"; + case PCH_DEVFN_I2C3: return "I2C3"; + case PCH_DEVFN_CSE: return "CSE1"; + case PCH_DEVFN_CSE_2: return "CSE2"; + case PCH_DEVFN_CSE_IDER: return "CSED"; + case PCH_DEVFN_CSE_KT: return "CSKT"; + case PCH_DEVFN_CSE_3: return "CSE3"; + case PCH_DEVFN_SATA: return "SATA"; + case PCH_DEVFN_UART2: return "UAR2"; + case PCH_DEVFN_I2C4: return "I2C4"; + case PCH_DEVFN_I2C5: return "I2C5"; + case PCH_DEVFN_PCIE1: return "RP01"; + case PCH_DEVFN_PCIE2: return "RP02"; + case PCH_DEVFN_PCIE3: return "RP03"; + case PCH_DEVFN_PCIE4: return "RP04"; + case PCH_DEVFN_PCIE5: return "RP05"; + case PCH_DEVFN_PCIE6: return "RP06"; + case PCH_DEVFN_PCIE7: return "RP07"; + case PCH_DEVFN_PCIE8: return "RP08"; + case PCH_DEVFN_PCIE9: return "RP09"; + case PCH_DEVFN_PCIE10: return "RP10"; + case PCH_DEVFN_PCIE11: return "RP11"; + case PCH_DEVFN_PCIE12: return "RP12"; + case PCH_DEVFN_UART0: return "UAR0"; + case PCH_DEVFN_UART1: return "UAR1"; + case PCH_DEVFN_GSPI0: return "SPI0"; + case PCH_DEVFN_GSPI1: return "SPI1"; + case PCH_DEVFN_GSPI2: return "SPI2"; + case PCH_DEVFN_EMMC: return "EMMC"; + case PCH_DEVFN_SDCARD: return "SDXC"; + case PCH_DEVFN_LPC: return "LPCB"; + case PCH_DEVFN_P2SB: return "P2SB"; + case PCH_DEVFN_PMC: return "PMC_"; + case PCH_DEVFN_HDA: return "HDAS"; + case PCH_DEVFN_SMBUS: return "SBUS"; + case PCH_DEVFN_SPI: return "FSPI"; + case PCH_DEVFN_GBE: return "IGBE"; + case PCH_DEVFN_TRACEHUB:return "THUB"; + } + + return NULL; +} +#endif + void soc_init_pre_device(void *chip_info) { /* Perform silicon specific init. */ @@ -40,6 +102,9 @@ static struct device_operations pci_domain_ops = { .set_resources = &pci_domain_set_resources, .scan_bus = &pci_domain_scan_bus, .ops_pci_bus = &pci_bus_default_ops, + #if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + .acpi_name = &soc_acpi_name, + #endif }; static struct device_operations cpu_bus_ops = { diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h index 0ed41fc824..52a5fc13a3 100644 --- a/src/soc/intel/cannonlake/chip.h +++ b/src/soc/intel/cannonlake/chip.h @@ -108,6 +108,11 @@ struct soc_intel_cannonlake_config { struct usb3_port_config usb3_ports[10]; uint8_t XdciEnable; uint8_t SsicPortEnable; + /* Wake Enable Bitmap for USB2 ports */ + uint16_t usb2_wake_enable_bitmap; + /* Wake Enable Bitmap for USB3 ports */ + uint16_t usb3_wake_enable_bitmap; + /* SATA related */ uint8_t SataEnable; @@ -194,6 +199,7 @@ struct soc_intel_cannonlake_config { * 0x02000000 - 32MiB and beyond */ uint32_t PrmrrSize; + uint8_t PmTimerDisabled; }; typedef struct soc_intel_cannonlake_config config_t; diff --git a/src/soc/intel/cannonlake/include/soc/gpio_soc_defs.h b/src/soc/intel/cannonlake/include/soc/gpio_soc_defs.h index e9a5b89491..d4994e74e4 100644 --- a/src/soc/intel/cannonlake/include/soc/gpio_soc_defs.h +++ b/src/soc/intel/cannonlake/include/soc/gpio_soc_defs.h @@ -248,4 +248,5 @@ #define NUM_GPIO_COM2_PADS (GPD11 - GPD0 + 1) +#define TOTAL_PADS 188 #endif diff --git a/src/soc/intel/cannonlake/include/soc/nvs.h b/src/soc/intel/cannonlake/include/soc/nvs.h new file mode 100644 index 0000000000..aa5093d4ef --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/nvs.h @@ -0,0 +1,50 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2017 Intel Corporation. + * + * 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. + */ + +#ifndef _SOC_NVS_H_ +#define _SOC_NVS_H_ + +#include +#include + +typedef struct global_nvs_t { + /* Miscellaneous */ + u16 osys; /* 0x00 - 0x01 Operating System */ + u8 smif; /* 0x02 - SMI function call ("TRAP") */ + u8 pcnt; /* 0x03 - Processor Count */ + u8 ppcm; /* 0x04 - Max PPC State */ + u8 tlvl; /* 0x05 - Throttle Level Limit */ + u8 lids; /* 0x06 - LID State */ + u8 pwrs; /* 0x07 - AC Power State */ + u32 cbmc; /* 0x08 - 0xb AC Power State */ + u64 pm1i; /* 0x0c - 0x13 PM1 wake status bit */ + u64 gpei; /* 0x14 - 0x1b GPE wake status bit */ + u8 dpte; /* 0x1c - Enable DPTF */ + u64 nhla; /* 0x1d - 0x24 NHLT Address */ + u32 nhll; /* 0x25 - 0x28 NHLT Length */ + u16 cid1; /* 0x29 - 0x2a Wifi Country Identifier */ + u16 u2we; /* 0x2b - 0x2c USB2 Wake Enable Bitmap */ + u16 u3we; /* 0x2d - 0x2e USB3 Wake Enable Bitmap */ + u8 uior; /* 0x2f - UART debug controller init on S3 resume */ + u8 unused[208]; + + /* ChromeOS specific (0x100 - 0xfff) */ + chromeos_acpi_t chromeos; +} __packed global_nvs_t; + + +#endif diff --git a/src/soc/intel/cannonlake/include/soc/pm.h b/src/soc/intel/cannonlake/include/soc/pm.h index 58037bd488..378fac9139 100644 --- a/src/soc/intel/cannonlake/include/soc/pm.h +++ b/src/soc/intel/cannonlake/include/soc/pm.h @@ -140,6 +140,11 @@ #define ENABLE_SMI_PARAMS \ (APMC_EN | SLP_SMI_EN | GBL_SMI_EN | ESPI_SMI_EN | EOS) +#define PSS_RATIO_STEP 2 +#define PSS_MAX_ENTRIES 8 +#define PSS_LATENCY_TRANSITION 10 +#define PSS_LATENCY_BUSMASTER 10 + struct chipset_power_state { uint16_t pm1_sts; uint16_t pm1_en; @@ -154,9 +159,6 @@ struct chipset_power_state { uint32_t prev_sleep_state; } __packed; -/* Return the selected ACPI SCI IRQ */ -int acpi_sci_irq(void); - /* Get base address PMC memory mapped registers. */ uint8_t *pmc_mmio_regs(void); diff --git a/src/soc/intel/cannonlake/include/soc/pmc.h b/src/soc/intel/cannonlake/include/soc/pmc.h index b8e49c2286..69954db6ce 100644 --- a/src/soc/intel/cannonlake/include/soc/pmc.h +++ b/src/soc/intel/cannonlake/include/soc/pmc.h @@ -119,6 +119,8 @@ #define GBLRST_CAUSE0_THERMTRIP (1 << 5) #define GBLRST_CAUSE1 0x1928 +#define IRQ_REG ACTL +#define SCI_IRQ_ADJUST 0 #define ACTL 0x1BD8 #define PWRM_EN (1 << 8) #define ACPI_EN (1 << 7) diff --git a/src/soc/intel/cannonlake/pmutil.c b/src/soc/intel/cannonlake/pmutil.c index 322fe514e9..6708781fa5 100644 --- a/src/soc/intel/cannonlake/pmutil.c +++ b/src/soc/intel/cannonlake/pmutil.c @@ -125,34 +125,6 @@ const char *const *soc_gpe_sts_array(size_t *a) return gpe_sts_bits; } -int acpi_sci_irq(void) -{ - int scis = pci_read_config32(PCH_DEV_PMC, ACTL) & SCI_IRQ_SEL; - int sci_irq = 9; - - /* Determine how SCI is routed. */ - switch (scis) { - case SCIS_IRQ9: - case SCIS_IRQ10: - case SCIS_IRQ11: - sci_irq = scis - SCIS_IRQ9 + 9; - break; - case SCIS_IRQ20: - case SCIS_IRQ21: - case SCIS_IRQ22: - case SCIS_IRQ23: - sci_irq = scis - SCIS_IRQ20 + 20; - break; - default: - printk(BIOS_DEBUG, "Invalid SCI route! Defaulting to IRQ9.\n"); - sci_irq = 9; - break; - } - - printk(BIOS_DEBUG, "SCI is IRQ%d\n", sci_irq); - return sci_irq; -} - uint8_t *pmc_mmio_regs(void) { uint32_t reg32; -- cgit v1.2.3