diff options
author | Ravi Sarawadi <ravishankar.sarawadi@intel.com> | 2017-09-28 17:06:01 -0700 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2017-10-03 20:23:21 +0000 |
commit | 1483d1fcda092283c303fd1d4f4aeca75dcd0bf1 (patch) | |
tree | 8d7fd3948634e5a8b46aaa2655a759c00843ff9c /src | |
parent | a9b5a393955d2731eb20e3312b95859a55d6230d (diff) | |
download | coreboot-1483d1fcda092283c303fd1d4f4aeca75dcd0bf1.tar.xz |
soc/intel/skylake: Enable common LPC IP
Enable Skylake to use the new common LPC code. This
will help to reduce code duplication and streamline code bring up.
Change-Id: I042e459fb7c07f024a7f6a5fe7da13eb5f0dd688
Signed-off-by: Ravi Sarawadi <ravishankar.sarawadi@intel.com>
Reviewed-on: https://review.coreboot.org/20120
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/intel/skylake/Kconfig | 1 | ||||
-rw-r--r-- | src/soc/intel/skylake/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/skylake/acpi.c | 6 | ||||
-rw-r--r-- | src/soc/intel/skylake/bootblock/pch.c | 76 | ||||
-rw-r--r-- | src/soc/intel/skylake/finalize.c | 2 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/acpi.h | 4 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/iomap.h | 3 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/lpc.h | 58 | ||||
-rw-r--r-- | src/soc/intel/skylake/irq.c | 71 | ||||
-rw-r--r-- | src/soc/intel/skylake/lockdown.c | 17 | ||||
-rw-r--r-- | src/soc/intel/skylake/lpc.c | 291 | ||||
-rw-r--r-- | src/soc/intel/skylake/pmutil.c | 2 |
12 files changed, 134 insertions, 398 deletions
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index 6deadd86a3..3c676d8dc2 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -62,6 +62,7 @@ config CPU_SPECIFIC_OPTIONS select SOC_INTEL_COMMON_BLOCK_GSPI select SOC_INTEL_COMMON_BLOCK_ITSS select SOC_INTEL_COMMON_BLOCK_I2C + select SOC_INTEL_COMMON_BLOCK_LPC select SOC_INTEL_COMMON_BLOCK_LPSS select SOC_INTEL_COMMON_BLOCK_PCIE select SOC_INTEL_COMMON_BLOCK_PCR diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc index 7046b8106c..d12ba0878a 100644 --- a/src/soc/intel/skylake/Makefile.inc +++ b/src/soc/intel/skylake/Makefile.inc @@ -21,6 +21,7 @@ bootblock-y += gspi.c bootblock-y += pch.c bootblock-y += pmutil.c bootblock-y += spi.c +bootblock-y += lpc.c verstage-y += gspi.c verstage-y += pch.c diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c index cfb98cd627..387cb6da74 100644 --- a/src/soc/intel/skylake/acpi.c +++ b/src/soc/intel/skylake/acpi.c @@ -31,11 +31,11 @@ #include <cpu/intel/turbo.h> #include <ec/google/chromeec/ec.h> #include <intelblocks/cpulib.h> +#include <intelblocks/lpc_lib.h> #include <soc/intel/common/acpi.h> #include <soc/acpi.h> #include <soc/cpu.h> #include <soc/iomap.h> -#include <soc/lpc.h> #include <soc/msr.h> #include <soc/pci_devs.h> #include <soc/pm.h> @@ -556,7 +556,7 @@ unsigned long acpi_madt_irq_overrides(unsigned long current) return current; } -unsigned long southcluster_write_acpi_tables(device_t device, +unsigned long southbridge_write_acpi_tables(device_t device, unsigned long current, struct acpi_rsdp *rsdp) { @@ -564,7 +564,7 @@ unsigned long southcluster_write_acpi_tables(device_t device, return acpi_align_current(current); } -void southcluster_inject_dsdt(device_t device) +void southbridge_inject_dsdt(device_t device) { global_nvs_t *gnvs; diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c index 2502563a30..67951f6a5f 100644 --- a/src/soc/intel/skylake/bootblock/pch.c +++ b/src/soc/intel/skylake/bootblock/pch.c @@ -20,12 +20,12 @@ #include <device/pci_def.h> #include <intelblocks/fast_spi.h> #include <intelblocks/itss.h> +#include <intelblocks/lpc_lib.h> #include <intelblocks/pcr.h> #include <intelblocks/rtc.h> #include <intelblocks/smbus.h> #include <soc/bootblock.h> #include <soc/iomap.h> -#include <soc/lpc.h> #include <soc/p2sb.h> #include <soc/pch.h> #include <soc/pci_devs.h> @@ -34,20 +34,12 @@ #include <soc/pmc.h> #include <soc/smbus.h> -#define PCR_DMI_LPCLGIR1 0x2730 -#define PCR_DMI_LPCLGIR2 0x2734 -#define PCR_DMI_LPCLGIR3 0x2738 -#define PCR_DMI_LPCLGIR4 0x273c - #define PCR_DMI_ACPIBA 0x27B4 #define PCR_DMI_ACPIBDID 0x27B8 #define PCR_DMI_PMBASEA 0x27AC #define PCR_DMI_PMBASEC 0x27B0 #define PCR_DMI_TCOBASE 0x2778 -#define PCR_DMI_LPCIOD 0x2770 -#define PCR_DMI_LPCIOE 0x2774 - static void enable_p2sbbar(void) { device_t dev = PCH_DEV_P2SB; @@ -73,54 +65,6 @@ void bootblock_pch_early_init(void) enable_p2sbbar(); } -static void pch_enable_lpc(void) -{ - /* Lookup device tree in romstage */ - const struct device *dev; - const config_t *config; - - dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0)); - if (!dev || !dev->chip_info) - return; - config = dev->chip_info; - - /* Set in PCI generic decode range registers */ - pci_write_config32(PCH_DEV_LPC, LPC_GEN1_DEC, config->gen1_dec); - pci_write_config32(PCH_DEV_LPC, LPC_GEN2_DEC, config->gen2_dec); - pci_write_config32(PCH_DEV_LPC, LPC_GEN3_DEC, config->gen3_dec); - pci_write_config32(PCH_DEV_LPC, LPC_GEN4_DEC, config->gen4_dec); - - /* Mirror these same settings in DMI PCR */ - pcr_write32(PID_DMI, PCR_DMI_LPCLGIR1, config->gen1_dec); - pcr_write32(PID_DMI, PCR_DMI_LPCLGIR2, config->gen2_dec); - pcr_write32(PID_DMI, PCR_DMI_LPCLGIR3, config->gen3_dec); - pcr_write32(PID_DMI, PCR_DMI_LPCLGIR4, config->gen4_dec); -} - -static void pch_interrupt_init(void) -{ - const struct device *dev; - const config_t *config; - uint8_t pch_interrupt_routing[MAX_PXRC_CONFIG]; - - dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0)); - if (!dev || !dev->chip_info) - return; - config = dev->chip_info; - - pch_interrupt_routing[0] = config->pirqa_routing; - pch_interrupt_routing[1] = config->pirqb_routing; - pch_interrupt_routing[2] = config->pirqc_routing; - pch_interrupt_routing[3] = config->pirqd_routing; - pch_interrupt_routing[4] = config->pirqe_routing; - pch_interrupt_routing[5] = config->pirqf_routing; - pch_interrupt_routing[6] = config->pirqg_routing; - pch_interrupt_routing[7] = config->pirqh_routing; - - itss_irq_init(pch_interrupt_routing); -} - - static void soc_config_acpibase(void) { uint32_t reg32; @@ -235,18 +179,12 @@ static void enable_heci(void) void pch_early_iorange_init(void) { - /* Lookup device tree in romstage */ - u16 lpc_en; - /* IO Decode Range */ - lpc_en = COMA_RANGE | (COMB_RANGE << 4); - pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, lpc_en); - pcr_write16(PID_DMI, PCR_DMI_LPCIOD, lpc_en); + lpc_io_setup_comm_a_b(); /* IO Decode Enable */ - lpc_en = CNF1_LPC_EN | COMA_LPC_EN | KBC_LPC_EN | MC_LPC_EN; - pci_write_config16(PCH_DEV_LPC, LPC_EN, lpc_en); - pcr_write16(PID_DMI, PCR_DMI_LPCIOE, lpc_en); + lpc_enable_fixed_io_ranges(LPC_IOE_SUPERIO_2E_2F | LPC_IOE_KBC_60_64 | + LPC_IOE_EC_62_66); /* Program generic IO Decode Range */ pch_enable_lpc(); @@ -269,12 +207,6 @@ void pch_early_init(void) /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */ soc_config_tco(); - /* - * Interrupt Configuration Register Programming - * PIRQx to IRQ Programming - */ - pch_interrupt_init(); - /* Program SMBUS_BASE_ADDRESS and Enable it */ smbus_common_init(); diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c index 770cc1bf77..bcaa283598 100644 --- a/src/soc/intel/skylake/finalize.c +++ b/src/soc/intel/skylake/finalize.c @@ -21,10 +21,10 @@ #include <console/post_codes.h> #include <cpu/x86/smm.h> #include <device/pci.h> +#include <intelblocks/lpc_lib.h> #include <intelblocks/pcr.h> #include <reg_script.h> #include <spi-generic.h> -#include <soc/lpc.h> #include <soc/me.h> #include <soc/p2sb.h> #include <soc/pci_devs.h> diff --git a/src/soc/intel/skylake/include/soc/acpi.h b/src/soc/intel/skylake/include/soc/acpi.h index 94c7c2ff94..b0d2194612 100644 --- a/src/soc/intel/skylake/include/soc/acpi.h +++ b/src/soc/intel/skylake/include/soc/acpi.h @@ -29,8 +29,8 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt); unsigned long acpi_madt_irq_overrides(unsigned long current); void acpi_mainboard_gnvs(global_nvs_t *gnvs); -void southcluster_inject_dsdt(device_t device); -unsigned long southcluster_write_acpi_tables(device_t device, +void southbridge_inject_dsdt(device_t device); +unsigned long southbridge_write_acpi_tables(device_t device, unsigned long current, struct acpi_rsdp *rsdp); #endif /* _SOC_ACPI_H_ */ diff --git a/src/soc/intel/skylake/include/soc/iomap.h b/src/soc/intel/skylake/include/soc/iomap.h index de9ef97744..7e99d9984c 100644 --- a/src/soc/intel/skylake/include/soc/iomap.h +++ b/src/soc/intel/skylake/include/soc/iomap.h @@ -25,6 +25,9 @@ #define MCFG_BASE_ADDRESS CONFIG_MMCONF_BASE_ADDRESS #define MCFG_BASE_SIZE 0x4000000 +#define PCH_PRESERVED_BASE_ADDRESS 0xfc800000 +#define PCH_PRESERVED_BASE_SIZE 0x02000000 + #define UART_DEBUG_BASE_0_SIZE 0x1000 #define UART_BASE_0_ADDRESS 0xfe030000 /* Both UART BAR 0 and 1 are 4KB in size */ diff --git a/src/soc/intel/skylake/include/soc/lpc.h b/src/soc/intel/skylake/include/soc/lpc.h deleted file mode 100644 index f3541a07c6..0000000000 --- a/src/soc/intel/skylake/include/soc/lpc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * 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. - */ - -#ifndef _SOC_LPC_H_ -#define _SOC_LPC_H_ - -/* PCI Configuration Space (D31:F0): LPC */ -#define ABASE 0x40 -#define ACNTL 0x44 -#define ACPI_EN (1 << 7) -#define SCI_IRQ_SEL (7 << 0) -#define SCIS_IRQ9 0 -#define SCIS_IRQ10 1 -#define SCIS_IRQ11 2 -#define SCIS_IRQ20 4 -#define SCIS_IRQ21 5 -#define SCIS_IRQ22 6 -#define SCIS_IRQ23 7 -#define SERIRQ_CNTL 0x64 -#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */ -#define COMA_RANGE 0x0 /* 0x3F8 - 0x3FF COM1*/ -#define COMB_RANGE 0x1 /* 0x2F8 - 0x2FF COM2*/ -#define LPC_EN 0x82 /* LPC IF Enables Register */ -#define CNF2_LPC_EN (1 << 13) /* 0x4e/0x4f */ -#define CNF1_LPC_EN (1 << 12) /* 0x2e/0x2f */ -#define MC_LPC_EN (1 << 11) /* 0x62/0x66 */ -#define KBC_LPC_EN (1 << 10) /* 0x60/0x64 */ -#define GAMEH_LPC_EN (1 << 9) /* 0x208/0x20f */ -#define GAMEL_LPC_EN (1 << 8) /* 0x200/0x207 */ -#define FDD_LPC_EN (1 << 3) /* LPC_IO_DEC[12] */ -#define LPT_LPC_EN (1 << 2) /* LPC_IO_DEC[9:8] */ -#define COMB_LPC_EN (1 << 1) /* LPC_IO_DEC[6:4] */ -#define COMA_LPC_EN (1 << 0) /* LPC_IO_DEC[2:0] */ -#define LPC_GEN1_DEC 0x84 /* LPC IF Generic Decode Range 1 */ -#define LPC_GEN2_DEC 0x88 /* LPC IF Generic Decode Range 2 */ -#define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */ -#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */ -#define LGMR 0x98 /* LPC Generic Memory Range */ -#define BIOS_CNTL 0xdc -#define LPC_BC_BILD (1 << 7) /* BILD */ -#define LPC_BC_LE (1 << 1) /* LE */ -#define LPC_BC_EISS (1 << 5) /* EISS */ -#define PCCTL 0xE0 /* PCI Clock Control */ -#define CLKRUN_EN (1 << 0) -#endif diff --git a/src/soc/intel/skylake/irq.c b/src/soc/intel/skylake/irq.c index 649f1375cb..d5778960c0 100644 --- a/src/soc/intel/skylake/irq.c +++ b/src/soc/intel/skylake/irq.c @@ -15,6 +15,8 @@ #include <device/device.h> #include <device/pci.h> +#include <intelblocks/lpc_lib.h> +#include <intelblocks/itss.h> #include <soc/ramstage.h> #include <soc/interrupt.h> #include <soc/irq.h> @@ -267,3 +269,72 @@ void soc_irq_settings(FSP_SIL_UPD *params) /* TCO Irq enable/disable */ params->TcoIrqEnable = config->TcoIrqEnable; } + +/* + * PIRQ[n]_ROUT[3:0] - PIRQ Routing Control + * 0x00 - 0000 = Reserved + * 0x01 - 0001 = Reserved + * 0x02 - 0010 = Reserved + * 0x03 - 0011 = IRQ3 + * 0x04 - 0100 = IRQ4 + * 0x05 - 0101 = IRQ5 + * 0x06 - 0110 = IRQ6 + * 0x07 - 0111 = IRQ7 + * 0x08 - 1000 = Reserved + * 0x09 - 1001 = IRQ9 + * 0x0A - 1010 = IRQ10 + * 0x0B - 1011 = IRQ11 + * 0x0C - 1100 = IRQ12 + * 0x0D - 1101 = Reserved + * 0x0E - 1110 = IRQ14 + * 0x0F - 1111 = IRQ15 + * PIRQ[n]_ROUT[7] - PIRQ Routing Control + * 0x80 - The PIRQ is not routed. + */ + +void soc_pch_pirq_init(const struct device *dev) +{ + const config_t *config = dev->chip_info; + uint8_t pch_interrupt_routing[MAX_PXRC_CONFIG]; + device_t irq_dev; + + pch_interrupt_routing[0] = config->pirqa_routing; + pch_interrupt_routing[1] = config->pirqb_routing; + pch_interrupt_routing[2] = config->pirqc_routing; + pch_interrupt_routing[3] = config->pirqd_routing; + pch_interrupt_routing[4] = config->pirqe_routing; + pch_interrupt_routing[5] = config->pirqf_routing; + pch_interrupt_routing[6] = config->pirqg_routing; + pch_interrupt_routing[7] = config->pirqh_routing; + + itss_irq_init(pch_interrupt_routing); + + for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) { + u8 int_pin = 0, int_line = 0; + + if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI) + continue; + + int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN); + + switch (int_pin) { + case 1: /* INTA# */ + int_line = config->pirqa_routing; + break; + case 2: /* INTB# */ + int_line = config->pirqb_routing; + break; + case 3: /* INTC# */ + int_line = config->pirqc_routing; + break; + case 4: /* INTD# */ + int_line = config->pirqd_routing; + break; + } + + if (!int_line) + continue; + + pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line); + } +} diff --git a/src/soc/intel/skylake/lockdown.c b/src/soc/intel/skylake/lockdown.c index 8c34fa73ed..79f6f70987 100644 --- a/src/soc/intel/skylake/lockdown.c +++ b/src/soc/intel/skylake/lockdown.c @@ -17,8 +17,8 @@ #include <bootstate.h> #include <chip.h> #include <intelblocks/fast_spi.h> +#include <intelblocks/lpc_lib.h> #include <intelblocks/pcr.h> -#include <soc/lpc.h> #include <soc/pci_devs.h> #include <soc/pcr_ids.h> #include <soc/pm.h> @@ -29,18 +29,11 @@ static void lpc_lockdown_config(const struct soc_intel_skylake_config *config) { - struct device *dev; - uint8_t reg_mask = 0; - - dev = PCH_DEV_LPC; - /* Set Bios Interface Lock, Bios Lock */ - if (config->chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) - reg_mask |= LPC_BC_BILD | LPC_BC_LE; - - pci_or_config8(dev, BIOS_CNTL, reg_mask); - /* Ensure an additional read back after performing lock down */ - pci_read_config8(dev, BIOS_CNTL); + if (config->chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { + lpc_set_bios_interface_lock_down(); + lpc_set_lock_enable(); + } } static void pmc_lockdown_config(void) diff --git a/src/soc/intel/skylake/lpc.c b/src/soc/intel/skylake/lpc.c index 295dace34f..bd6fbc4542 100644 --- a/src/soc/intel/skylake/lpc.c +++ b/src/soc/intel/skylake/lpc.c @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ -#include <arch/acpigen.h> #include "chip.h" #include <console/console.h> #include <delay.h> @@ -26,28 +25,26 @@ #include <pc80/i8259.h> #include <arch/io.h> #include <arch/ioapic.h> -#include <arch/acpi.h> -#include <cpu/cpu.h> -#include <cpu/x86/smm.h> -#include <cbmem.h> #include <intelblocks/itss.h> +#include <intelblocks/lpc_lib.h> #include <intelblocks/pcr.h> #include <reg_script.h> -#include <string.h> -#include <soc/acpi.h> -#include <soc/gpio.h> #include <soc/iomap.h> -#include <soc/lpc.h> -#include <soc/nvs.h> -#include <soc/pch.h> -#include <soc/pci_devs.h> -#include <soc/pm.h> -#include <soc/pmc.h> -#include <soc/ramstage.h> #include <soc/pcr_ids.h> -#if IS_ENABLED(CONFIG_CHROMEOS) -#include <vendorcode/google/chromeos/chromeos.h> -#endif + +/** + PCH preserved MMIO range, 24 MB, from 0xFD000000 to 0xFE7FFFFF +**/ + +static const struct lpc_mmio_range skl_lpc_fixed_mmio_ranges[] = { + { PCH_PRESERVED_BASE_ADDRESS, PCH_PRESERVED_BASE_SIZE }, + { 0, 0 } +}; + +const struct lpc_mmio_range *soc_get_fixed_mmio_ranges(void) +{ + return skl_lpc_fixed_mmio_ranges; +} static void pch_enable_ioapic(struct device *dev) { @@ -72,75 +69,24 @@ static void pch_enable_ioapic(struct device *dev) io_apic_write((void *)IO_APIC_ADDR, 0x03, 0x01); } -/* - * PIRQ[n]_ROUT[3:0] - PIRQ Routing Control - * 0x00 - 0000 = Reserved - * 0x01 - 0001 = Reserved - * 0x02 - 0010 = Reserved - * 0x03 - 0011 = IRQ3 - * 0x04 - 0100 = IRQ4 - * 0x05 - 0101 = IRQ5 - * 0x06 - 0110 = IRQ6 - * 0x07 - 0111 = IRQ7 - * 0x08 - 1000 = Reserved - * 0x09 - 1001 = IRQ9 - * 0x0A - 1010 = IRQ10 - * 0x0B - 1011 = IRQ11 - * 0x0C - 1100 = IRQ12 - * 0x0D - 1101 = Reserved - * 0x0E - 1110 = IRQ14 - * 0x0F - 1111 = IRQ15 - * PIRQ[n]_ROUT[7] - PIRQ Routing Control - * 0x80 - The PIRQ is not routed. - */ - -static void pch_pirq_init(device_t dev) +void soc_get_gen_io_dec_range(const struct device *dev, uint32_t *gen_io_dec) { - device_t irq_dev; - config_t *config = dev->chip_info; - uint8_t pch_interrupt_routing[MAX_PXRC_CONFIG]; + const config_t *config = dev->chip_info; - pch_interrupt_routing[0] = config->pirqa_routing; - pch_interrupt_routing[1] = config->pirqb_routing; - pch_interrupt_routing[2] = config->pirqc_routing; - pch_interrupt_routing[3] = config->pirqd_routing; - pch_interrupt_routing[4] = config->pirqe_routing; - pch_interrupt_routing[5] = config->pirqf_routing; - pch_interrupt_routing[6] = config->pirqg_routing; - pch_interrupt_routing[7] = config->pirqh_routing; - - itss_irq_init(pch_interrupt_routing); - - for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) { - u8 int_pin = 0, int_line = 0; - - if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI) - continue; - - int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN); - - switch (int_pin) { - case 1: /* INTA# */ - int_line = config->pirqa_routing; - break; - case 2: /* INTB# */ - int_line = config->pirqb_routing; - break; - case 3: /* INTC# */ - int_line = config->pirqc_routing; - break; - case 4: /* INTD# */ - int_line = config->pirqd_routing; - break; - } - - if (!int_line) - continue; - - pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line); - } + gen_io_dec[0] = config->gen1_dec; + gen_io_dec[1] = config->gen2_dec; + gen_io_dec[2] = config->gen3_dec; + gen_io_dec[3] = config->gen4_dec; } +void soc_setup_dmi_pcr_io_dec(uint32_t *gen_io_dec) +{ + /* Mirror these same settings in DMI PCR */ + pcr_write32(PID_DMI, PCR_DMI_LPCLGIR1, gen_io_dec[0]); + pcr_write32(PID_DMI, PCR_DMI_LPCLGIR2, gen_io_dec[1]); + pcr_write32(PID_DMI, PCR_DMI_LPCLGIR3, gen_io_dec[2]); + pcr_write32(PID_DMI, PCR_DMI_LPCLGIR4, gen_io_dec[3]); +} static const struct reg_script pch_misc_init_script[] = { /* Setup NMI on errors, disable SERR */ @@ -149,19 +95,12 @@ static const struct reg_script pch_misc_init_script[] = { REG_IO_OR8(0x70, (1 << 7)), /* Enable BIOS updates outside of SMM */ REG_PCI_RMW8(0xdc, ~(1 << 5), 0), - /* Setup SERIRQ, enable continuous mode */ - REG_PCI_OR8(SERIRQ_CNTL, (1 << 7) | (1 << 6)), -#if !IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE) - REG_PCI_RMW8(SERIRQ_CNTL, ~(1 << 6), 0), -#endif - /* Enable CLKRUN_EN for power gating LPC */ - REG_PCI_OR8(PCCTL, (CLKRUN_EN)), REG_SCRIPT_END }; static void clock_gate_8254(struct device *dev) { - config_t *config = dev->chip_info; + const config_t *config = dev->chip_info; if (!config->clock_gate_8254) return; @@ -169,171 +108,25 @@ static void clock_gate_8254(struct device *dev) itss_clock_gate_8254(); } -static void lpc_init(struct device *dev) +void lpc_init(struct device *dev) { /* Legacy initialization */ isa_dma_init(); - reg_script_run_on_dev(dev, pch_misc_init_script); + reg_script_run_on_dev(PCH_DEV_LPC, pch_misc_init_script); + + /* Enable CLKRUN_EN for power gating LPC */ + lpc_enable_pci_clk_cntl(); + + /* Set LPC Serial IRQ mode */ + if (IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE)) + lpc_set_serirq_mode(SERIRQ_CONTINUOUS); + else + lpc_set_serirq_mode(SERIRQ_QUIET); /* Interrupt configuration */ pch_enable_ioapic(dev); - pch_pirq_init(dev); + soc_pch_pirq_init(dev); setup_i8259(); i8259_configure_irq_trigger(9, 1); clock_gate_8254(dev); } - -static void pch_lpc_add_mmio_resources(device_t dev) -{ - u32 reg; - struct resource *res; - /* - * As per the BWG, Chapter 5.9.1. "PCH BIOS component will reserve - * certain memory range as reserved range for BIOS usage. - * For this SOC, the range will be from 0FD000000h till FE7FFFFFh" - * Hence, use FD000000h as PCR_BASE - */ - const u32 default_decode_base = CONFIG_PCR_BASE_ADDRESS; - - res = new_resource(dev, PCI_BASE_ADDRESS_0); - res->base = default_decode_base; - res->size = 0 - default_decode_base; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | - IORESOURCE_FIXED | IORESOURCE_RESERVE; - - /* Check LPC Memory Decode register. */ - reg = pci_read_config32(dev, LGMR); - if (reg & 1) { - reg &= ~0xffff; - if (reg < default_decode_base) { - res = new_resource(dev, LGMR); - res->base = reg; - res->size = 16 * 1024; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | - IORESOURCE_FIXED | IORESOURCE_RESERVE; - } - } -} - -/* Default IO range claimed by the LPC device. The upper bound is exclusive. */ -#define LPC_DEFAULT_IO_RANGE_LOWER 0 -#define LPC_DEFAULT_IO_RANGE_UPPER 0x1000 - -static inline int pch_io_range_in_default(u16 base, u16 size) -{ - /* Does it start above the range? */ - if (base >= LPC_DEFAULT_IO_RANGE_UPPER) - return 0; - - /* - * Is it entirely contained? - * Since LPC_DEFAULT_IO_RANGE_LOWER is Zero, - * it need not be checked against lower base. - */ - if ((base + size) < LPC_DEFAULT_IO_RANGE_UPPER) - return 1; - - /* This will return not in range for partial overlaps. */ - return 0; -} - -/* - * Note: this function assumes there is no overlap with the default LPC device's - * claimed range: LPC_DEFAULT_IO_RANGE_LOWER -> LPC_DEFAULT_IO_RANGE_UPPER. - */ -static void pch_lpc_add_io_resource(device_t dev, u16 base, u16 size, int index) -{ - struct resource *res; - - if (pch_io_range_in_default(base, size)) - return; - - res = new_resource(dev, index); - res->base = base; - res->size = size; - res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; -} - -static void pch_lpc_add_gen_io_resources(device_t dev, int reg_value, int index) -{ - /* - * Check if the register is enabled. If so and the base exceeds the - * device's deafult claim range add the resoure. - */ - if (reg_value & 1) { - u16 base = reg_value & 0xfffc; - u16 size = (0x3 | ((reg_value >> 16) & 0xfc)) + 1; - pch_lpc_add_io_resource(dev, base, size, index); - } -} - -static void pch_lpc_add_io_resources(device_t dev) -{ - struct resource *res; - config_t *config = dev->chip_info; - - /* Add the default claimed IO range for the LPC device. */ - res = new_resource(dev, 0); - res->base = LPC_DEFAULT_IO_RANGE_LOWER; - res->size = LPC_DEFAULT_IO_RANGE_UPPER - LPC_DEFAULT_IO_RANGE_LOWER; - res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; - - /* LPC Generic IO Decode range. */ - pch_lpc_add_gen_io_resources(dev, config->gen1_dec, LPC_GEN1_DEC); - pch_lpc_add_gen_io_resources(dev, config->gen2_dec, LPC_GEN2_DEC); - pch_lpc_add_gen_io_resources(dev, config->gen3_dec, LPC_GEN3_DEC); - pch_lpc_add_gen_io_resources(dev, config->gen4_dec, LPC_GEN4_DEC); -} - -static void pch_lpc_read_resources(device_t dev) -{ - global_nvs_t *gnvs; - - /* Get the normal PCI resources of this device. */ - pci_dev_read_resources(dev); - - /* Add non-standard MMIO resources. */ - pch_lpc_add_mmio_resources(dev); - - /* Add IO resources. */ - pch_lpc_add_io_resources(dev); - - /* Allocate ACPI NVS in CBMEM */ - gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(global_nvs_t)); - if (!acpi_is_wakeup_s3() && gnvs) - memset(gnvs, 0, sizeof(global_nvs_t)); -} - -static struct device_operations device_ops = { - .read_resources = &pch_lpc_read_resources, - .set_resources = &pci_dev_set_resources, - .enable_resources = &pci_dev_enable_resources, - .acpi_inject_dsdt_generator = southcluster_inject_dsdt, - .write_acpi_tables = southcluster_write_acpi_tables, - .init = &lpc_init, - .scan_bus = &scan_lpc_bus, - .ops_pci = &soc_pci_ops, -}; - -static const unsigned short pci_device_ids[] = { - PCI_DEVICE_ID_INTEL_SPT_LP_SAMPLE, - PCI_DEVICE_ID_INTEL_SPT_LP_U_BASE, - PCI_DEVICE_ID_INTEL_SPT_LP_U_PREMIUM, - PCI_DEVICE_ID_INTEL_SPT_LP_Y_PREMIUM, - PCI_DEVICE_ID_INTEL_KBP_H_QM170, - PCI_DEVICE_ID_INTEL_KBP_H_PREMIUM, - PCI_DEVICE_ID_INTEL_KBP_H_C236, - PCI_DEVICE_ID_INTEL_KBP_LP_SUPER_SKU, - PCI_DEVICE_ID_INTEL_KBP_LP_U_PREMIUM, - PCI_DEVICE_ID_INTEL_KBP_LP_Y_PREMIUM, - PCI_DEVICE_ID_INTEL_SPT_LP_Y_PREMIUM_HDCP22, - PCI_DEVICE_ID_INTEL_SPT_LP_U_PREMIUM_HDCP22, - PCI_DEVICE_ID_INTEL_SPT_LP_U_BASE_HDCP22, - 0 -}; - -static const struct pci_driver pch_lpc __pci_driver = { - .ops = &device_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .devices = pci_device_ids, -}; diff --git a/src/soc/intel/skylake/pmutil.c b/src/soc/intel/skylake/pmutil.c index 36e4784a10..7af138f170 100644 --- a/src/soc/intel/skylake/pmutil.c +++ b/src/soc/intel/skylake/pmutil.c @@ -27,12 +27,12 @@ #include <device/pci_def.h> #include <console/console.h> #include <halt.h> +#include <intelblocks/lpc_lib.h> #include <rules.h> #include <stdlib.h> #include <soc/gpe.h> #include <soc/gpio.h> #include <soc/iomap.h> -#include <soc/lpc.h> #include <soc/pci_devs.h> #include <soc/pm.h> #include <soc/pmc.h> |