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>
This commit is contained in:
parent
a9b5a39395
commit
1483d1fcda
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue