soc/intel/cannonlake: Initialize PMC controller
PMC controller gets hidden during FSP-Silicon initialization using sideband interface on CannonLake platform. Hence accessing PWRMBASE using PCI config space will return invalid BAR value as 0xFFFFF000. Also PMC PCI driver will not be able to initialize PMC controller as its not showing over PCI bus. coreboot PCI enumeration log shows: PCI: Static device PCI: 00:1f.2 not found, disabling it. This patch ensures PMC controller is getting initialized using boot state machine right after FSP Silicon Init returns (BS_DEV_INIT_CHIPS/ BS_ON_EXIT). TEST=Ensures PWRMBASE address is 0xFE000000 and PMC controller is getting initialized during BS_DEV_INIT_CHIPES/BS_ON_EXIT. Change-Id: Ife7389f0f035b66837aace89d6e6b866e494cbe4 Signed-off-by: Subrata Banik <subrata.banik@intel.com> Reviewed-on: https://review.coreboot.org/22566 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
parent
2153ea5b83
commit
0baad61a4e
|
@ -15,77 +15,15 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <bootstate.h>
|
||||||
#include <chip.h>
|
#include <chip.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
#include <device/pci.h>
|
#include <intelblocks/pmc.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 <intelblocks/pmclib.h>
|
||||||
#include <intelblocks/rtc.h>
|
#include <intelblocks/rtc.h>
|
||||||
#include <pc80/mc146818rtc.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <soc/gpio.h>
|
|
||||||
#include <soc/iomap.h>
|
|
||||||
#include <soc/pci_devs.h>
|
#include <soc/pci_devs.h>
|
||||||
#include <soc/pm.h>
|
#include <soc/pm.h>
|
||||||
#include <cpu/x86/smm.h>
|
|
||||||
#include <soc/pcr_ids.h>
|
|
||||||
#include <soc/ramstage.h>
|
|
||||||
#include <security/vboot/vbnv.h>
|
|
||||||
#include <security/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 config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
|
static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
|
||||||
{
|
{
|
||||||
|
@ -128,8 +66,9 @@ static void config_deep_sx(uint32_t deepsx_config)
|
||||||
write32(pmcbase + DSX_CFG, reg);
|
write32(pmcbase + DSX_CFG, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmc_init(struct device *dev)
|
static void pmc_init(void *unused)
|
||||||
{
|
{
|
||||||
|
device_t dev = PCH_DEV_PMC;
|
||||||
config_t *config = dev->chip_info;
|
config_t *config = dev->chip_info;
|
||||||
|
|
||||||
rtc_init();
|
rtc_init();
|
||||||
|
@ -137,28 +76,18 @@ static void pmc_init(struct device *dev)
|
||||||
/* Initialize power management */
|
/* Initialize power management */
|
||||||
pmc_gpe_init();
|
pmc_gpe_init();
|
||||||
|
|
||||||
pch_set_acpi_mode();
|
pmc_set_acpi_mode();
|
||||||
|
|
||||||
config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc);
|
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_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc);
|
||||||
config_deep_sx(config->deep_sx_config);
|
config_deep_sx(config->deep_sx_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device_operations device_ops = {
|
/*
|
||||||
.read_resources = &pch_pmc_read_resources,
|
* Initialize PMC controller.
|
||||||
.set_resources = &pci_dev_set_resources,
|
*
|
||||||
.enable_resources = &pci_dev_enable_resources,
|
* PMC controller gets hidden from PCI bus during FSP-Silicon init call.
|
||||||
.init = &pmc_init,
|
* Hence PCI enumeration can't be used to initialize bus device and
|
||||||
.scan_bus = &scan_lpc_bus,
|
* allocate resources.
|
||||||
};
|
*/
|
||||||
|
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, pmc_init, NULL);
|
||||||
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,
|
|
||||||
};
|
|
||||||
|
|
|
@ -128,13 +128,15 @@ const char *const *soc_std_gpe_sts_array(size_t *a)
|
||||||
return gpe_sts_bits;
|
return gpe_sts_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PMC controller gets hidden from PCI bus
|
||||||
|
* during FSP-Silicon init call. Hence PWRMBASE
|
||||||
|
* can't be accessible using PCI configuration space
|
||||||
|
* read/write.
|
||||||
|
*/
|
||||||
uint8_t *pmc_mmio_regs(void)
|
uint8_t *pmc_mmio_regs(void)
|
||||||
{
|
{
|
||||||
uint32_t reg32;
|
return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS;
|
||||||
|
|
||||||
reg32 = pci_read_config32(PCH_DEV_PMC, PWRMBASE);
|
|
||||||
|
|
||||||
return (void *)(uintptr_t)ALIGN_DOWN(reg32, 4 * KiB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t smbus_tco_regs(void)
|
uint16_t smbus_tco_regs(void)
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
|
#include <device/pci.h>
|
||||||
#include <intelblocks/systemagent.h>
|
#include <intelblocks/systemagent.h>
|
||||||
#include <soc/iomap.h>
|
#include <soc/iomap.h>
|
||||||
#include <soc/systemagent.h>
|
#include <soc/systemagent.h>
|
||||||
|
@ -37,6 +38,17 @@ void soc_add_fixed_mmio_resources(struct device *dev, int *index)
|
||||||
{ EPBAR, EP_BASE_ADDRESS, EP_BASE_SIZE, "EPBAR" },
|
{ EPBAR, EP_BASE_ADDRESS, EP_BASE_SIZE, "EPBAR" },
|
||||||
{ REGBAR, REG_BASE_ADDRESS, REG_BASE_SIZE, "REGBAR" },
|
{ REGBAR, REG_BASE_ADDRESS, REG_BASE_SIZE, "REGBAR" },
|
||||||
{ EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" },
|
{ EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" },
|
||||||
|
/*
|
||||||
|
* PMC pci device gets hidden from PCI bus due to Silicon
|
||||||
|
* policy hence binding PMCBAR aka PWRMBASE (offset 0x10) with
|
||||||
|
* SA resources to ensure that PMCBAR falls under PCI reserved
|
||||||
|
* memory range.
|
||||||
|
*
|
||||||
|
* Note: Don't add any more resource with same offset 0x10
|
||||||
|
* under this device space.
|
||||||
|
*/
|
||||||
|
{ PCI_BASE_ADDRESS_0, PCH_PWRM_BASE_ADDRESS, PCH_PWRM_BASE_SIZE,
|
||||||
|
"PMCBAR" },
|
||||||
};
|
};
|
||||||
|
|
||||||
sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources,
|
sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources,
|
||||||
|
|
Loading…
Reference in New Issue