Lijian Zhao has uploaded this change for review. ( https://review.coreboot.org/21251
Change subject: soc/intel/cannonlake: Add PMC pci drivers ......................................................................
soc/intel/cannonlake: Add PMC pci drivers
Add PMC pci driver on top of PMC common code, also include pmc init code reference from skylake.
Change-Id: I95895a3e26cdebd98a4e54720bd4730542707d7e Signed-off-by: Lijian Zhao lijian.zhao@intel.com --- M src/soc/intel/cannonlake/Makefile.inc M src/soc/intel/cannonlake/chip.h M src/soc/intel/cannonlake/gpio.c M src/soc/intel/cannonlake/include/soc/pmc.h A src/soc/intel/cannonlake/pmc.c 5 files changed, 212 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/51/21251/3
diff --git a/src/soc/intel/cannonlake/Makefile.inc b/src/soc/intel/cannonlake/Makefile.inc index 0c05057..68995a0 100644 --- a/src/soc/intel/cannonlake/Makefile.inc +++ b/src/soc/intel/cannonlake/Makefile.inc @@ -19,6 +19,7 @@ bootblock-y += spi.c bootblock-$(CONFIG_UART_DEBUG) += uart.c
+romstage-y += gpio.c romstage-y += gspi.c romstage-y += memmap.c romstage-y += pmutil.c @@ -29,7 +30,9 @@ ramstage-y += chip.c ramstage-y += cpu.c ramstage-y += gspi.c +ramstage-y += gpio.c ramstage-y += memmap.c +ramstage-y += pmc.c ramstage-y += pmutil.c ramstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c ramstage-y += spi.c diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h index 48305fe..de910b7 100644 --- a/src/soc/intel/cannonlake/chip.h +++ b/src/soc/intel/cannonlake/chip.h @@ -62,8 +62,10 @@ int dptf_enable;
/* Deep SX enable for both AC and DC */ - int deep_s3_enable; - int deep_s5_enable; + int deep_s3_enable_ac; + int deep_s3_enable_dc; + int deep_s5_enable_ac; + int deep_s5_enable_dc;
/* Deep Sx Configuration * DSX_EN_WAKE_PIN - Enable WAKE# pin diff --git a/src/soc/intel/cannonlake/gpio.c b/src/soc/intel/cannonlake/gpio.c index 68b137d..a3d7863 100644 --- a/src/soc/intel/cannonlake/gpio.c +++ b/src/soc/intel/cannonlake/gpio.c @@ -96,3 +96,20 @@ *num_communities = ARRAY_SIZE(cnl_communities); return cnl_communities; } + +const struct pmc_to_gpio_route *soc_pmc_gpio_routes(size_t *num) +{ + static const struct pmc_to_gpio_route routes[] = { + { GPP_A, GPP_A}, + { GPP_B, GPP_B}, + { GPP_C, GPP_C}, + { GPP_D, GPP_D}, + { GPP_E, GPP_E}, + { GPP_F, GPP_F}, + { GPP_G, GPP_G}, + { GPP_H, GPP_H}, + { GPD, GPD}, + }; + *num = ARRAY_SIZE(routes); + return routes; +} diff --git a/src/soc/intel/cannonlake/include/soc/pmc.h b/src/soc/intel/cannonlake/include/soc/pmc.h index b8e49c2..655ffce 100644 --- a/src/soc/intel/cannonlake/include/soc/pmc.h +++ b/src/soc/intel/cannonlake/include/soc/pmc.h @@ -105,6 +105,7 @@ #define DSX_EN_WAKE_PIN (1 << 2) #define DSX_EN_AC_PRESENT_PIN (1 << 1) #define DSX_EN_LAN_WAKE_PIN (1 << 0) +#define DSX_CFG_MASK (0x1f << 0)
#define PMSYNC_TPR_CFG 0x18C4 #define PCH2CPU_TPR_CFG_LOCK (1 << 31) diff --git a/src/soc/intel/cannonlake/pmc.c b/src/soc/intel/cannonlake/pmc.c new file mode 100644 index 0000000..dc0f069 --- /dev/null +++ b/src/soc/intel/cannonlake/pmc.c @@ -0,0 +1,187 @@ +/* + * 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. + */ + +#include <chip.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/ioapic.h> +#include <arch/acpi.h> +#include <cpu/cpu.h> +#include <intelblocks/pcr.h> +#include <intelblocks/pmclib.h> +#include <pc80/mc146818rtc.h> +#include <reg_script.h> +#include <string.h> +#include <soc/gpio.h> +#include <soc/iomap.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <cpu/x86/smm.h> +#include <soc/pcr_ids.h> +#include <soc/ramstage.h> +#include <vboot/vbnv.h> +#include <vboot/vbnv_layout.h> + +static void pch_pmc_add_mmio_resources(device_t dev) +{ + struct resource *res; + + /* Memory-mmapped I/O registers. */ + res = new_resource(dev, PWRMBASE); + res->base = PCH_PWRM_BASE_ADDRESS; + res->size = PCH_PWRM_BASE_SIZE; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED | IORESOURCE_RESERVE; +} + +static void pch_pmc_add_io_resource(device_t dev, u16 base, u16 size, int index) +{ + struct resource *res; + res = new_resource(dev, index); + res->base = base; + res->size = size; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; +} + +static void pch_pmc_add_io_resources(device_t dev) +{ + /* PMBASE */ + pch_pmc_add_io_resource(dev, ACPI_BASE_ADDRESS, ACPI_BASE_SIZE, ABASE); +} + +static void pch_pmc_read_resources(device_t dev) +{ + /* Get the normal PCI resources of this device. */ + pci_dev_read_resources(dev); + + /* Add non-standard MMIO resources. */ + pch_pmc_add_mmio_resources(dev); + + /* Add IO resources. */ + pch_pmc_add_io_resources(dev); +} + +static void pch_set_acpi_mode(void) +{ + if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) && !acpi_is_wakeup_s3()) { + printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n"); + outb(APM_CNT_ACPI_DISABLE, APM_CNT); + printk(BIOS_DEBUG, "done.\n"); + } +} + +static void pch_rtc_init(void) +{ + uint8_t reg8; + int rtc_failed; + uint8_t *pmcbase = pmc_mmio_regs(); + + reg8 = read8(pmcbase + GEN_PMCON_B); + rtc_failed = reg8 & RTC_BATTERY_DEAD; + if (rtc_failed) { + reg8 &= ~RTC_BATTERY_DEAD; + write8(pmcbase + GEN_PMCON_B, reg8); + printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed); + } + + /* Ensure the date is set including century byte. */ + cmos_check_update_date(); + + if (IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS)) + init_vbnv_cmos(rtc_failed); + else + cmos_init(rtc_failed); +} + +static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable) +{ + uint32_t reg; + uint8_t *pmcbase = pmc_mmio_regs(); + + printk(BIOS_DEBUG, "%sabling Deep S%c\n", + enable ? "En" : "Dis", sx + '0'); + reg = read32(pmcbase + offset); + if (enable) + reg |= mask; + else + reg &= ~mask; + write32(pmcbase + offset, reg); +} + +static void config_deep_s5(int on_ac, int on_dc) +{ + /* Treat S4 the same as S5. */ + config_deep_sX(S4_PWRGATE_POL, S4AC_GATE_SUS, 4, on_ac); + config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS, 4, on_dc); + config_deep_sX(S5_PWRGATE_POL, S5AC_GATE_SUS, 5, on_ac); + config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS, 5, on_dc); +} + +static void config_deep_s3(int on_ac, int on_dc) +{ + config_deep_sX(S3_PWRGATE_POL, S3AC_GATE_SUS, 3, on_ac); + config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS, 3, on_dc); +} + +static void config_deep_sx(uint32_t deepsx_config) +{ + uint32_t reg; + uint8_t *pmcbase = pmc_mmio_regs(); + + reg = read32(pmcbase + DSX_CFG); + reg &= ~DSX_CFG_MASK; + reg |= deepsx_config; + write32(pmcbase + DSX_CFG, reg); +} + +static void pmc_init(struct device *dev) +{ + config_t *config = dev->chip_info; + + pch_rtc_init(); + + /* Initialize power management */ + pmc_gpe_init(); + + pch_set_acpi_mode(); + + config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc); + config_deep_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc); + config_deep_sx(config->deep_sx_config); +} + +static struct device_operations device_ops = { + .read_resources = &pch_pmc_read_resources, + .set_resources = &pci_dev_set_resources, + .enable_resources = &pci_dev_enable_resources, + .init = &pmc_init, + .scan_bus = &scan_lpc_bus, +}; + +static const unsigned short pci_device_ids[] = { + PCI_DEVICE_ID_INTEL_CNL_PMC, + 0 +}; + +static const struct pci_driver pch_lpc __pci_driver = { + .ops = &device_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = pci_device_ids, +};