diff options
-rw-r--r-- | src/soc/intel/apollolake/bootblock/bootblock.c | 29 | ||||
-rw-r--r-- | src/soc/intel/apollolake/chip.h | 9 | ||||
-rw-r--r-- | src/soc/intel/apollolake/include/soc/lpc.h | 40 | ||||
-rw-r--r-- | src/soc/intel/apollolake/include/soc/pci_devs.h | 3 | ||||
-rw-r--r-- | src/soc/intel/apollolake/lpc.c | 43 |
5 files changed, 123 insertions, 1 deletions
diff --git a/src/soc/intel/apollolake/bootblock/bootblock.c b/src/soc/intel/apollolake/bootblock/bootblock.c index be07776f19..bb3b9c10e9 100644 --- a/src/soc/intel/apollolake/bootblock/bootblock.c +++ b/src/soc/intel/apollolake/bootblock/bootblock.c @@ -20,6 +20,7 @@ #include <soc/bootblock.h> #include <soc/cpu.h> #include <soc/gpio.h> +#include <soc/lpc.h> #include <soc/northbridge.h> #include <soc/pci_devs.h> #include <soc/uart.h> @@ -28,12 +29,36 @@ static const struct pad_config tpm_spi_configs[] = { PAD_CFG_NF(GPIO_106, NATIVE, DEEP, NF3), /* FST_SPI_CS2_N */ }; +static const struct pad_config lpc_gpio_configs[] = { + PAD_CFG_NF(LPC_AD0, NATIVE, DEEP, NF1), + PAD_CFG_NF(LPC_AD1, NATIVE, DEEP, NF1), + PAD_CFG_NF(LPC_AD2, NATIVE, DEEP, NF1), + PAD_CFG_NF(LPC_AD3, NATIVE, DEEP, NF1), + PAD_CFG_NF(LPC_FRAMEB, NATIVE, DEEP, NF1), + PAD_CFG_NF(LPC_CLKOUT0, UP_20K, DEEP, NF1), + PAD_CFG_NF(LPC_CLKOUT1, UP_20K, DEEP, NF1) +}; + static void tpm_enable(void) { /* Configure gpios */ gpio_configure_pads(tpm_spi_configs, ARRAY_SIZE(tpm_spi_configs)); } +static void early_lpc_enable(void) +{ + /* Enable requested fixed IO decode ranges */ + pci_write_config16(LPC_DEV, LPC_EN, LPC_EN_MC1 | LPC_EN_KB | LPC_EN_LGAME); + + /* Enable generic IO decode ranges for 0x800-0x9ff */ + /* FIXME: remove range hardcoding and/or calculate based on EC definitions */ + pci_write_config32(LPC_DEV, LPC_GEN1_DEC, ((0xff & ~3 ) << 8) | 0x800 | 1); + pci_write_config32(LPC_DEV, LPC_GEN2_DEC, ((0xff & ~3 ) << 8) | 0x900 | 1); + + /* GPIO pins need to be configured to specific native function */ + gpio_configure_pads(lpc_gpio_configs, ARRAY_SIZE(lpc_gpio_configs)); +} + void asmlinkage bootblock_c_entry(void) { device_t dev = NB_DEV_ROOT; @@ -59,4 +84,8 @@ void bootblock_soc_early_init(void) if (IS_ENABLED(CONFIG_LPC_TPM)) tpm_enable(); + + if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC_LPC)) + early_lpc_enable(); + } diff --git a/src/soc/intel/apollolake/chip.h b/src/soc/intel/apollolake/chip.h index 9d2bc46d61..32d93dee36 100644 --- a/src/soc/intel/apollolake/chip.h +++ b/src/soc/intel/apollolake/chip.h @@ -32,6 +32,15 @@ struct soc_intel_apollolake_config { uint8_t pcie_rp3_clkreq_pin; uint8_t pcie_rp4_clkreq_pin; uint8_t pcie_rp5_clkreq_pin; + + /* Generic IO decode ranges */ + uint32_t gen1_dec; + uint32_t gen2_dec; + uint32_t gen3_dec; + uint32_t gen4_dec; + + /* LPC port ranges */ + uint16_t lpc_dec; }; #endif /* _SOC_APOLLOLAKE_CHIP_H_ */ diff --git a/src/soc/intel/apollolake/include/soc/lpc.h b/src/soc/intel/apollolake/include/soc/lpc.h new file mode 100644 index 0000000000..2125f4ade1 --- /dev/null +++ b/src/soc/intel/apollolake/include/soc/lpc.h @@ -0,0 +1,40 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Intel Corp. + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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_APOLLOLAKE_LPC_H +#define _SOC_APOLLOLAKE_LPC_H + +/* PCI Configuration Space (D31:F0): LPC */ +#define SERIRQ_CNTL 0x64 /* Serial IRQ Control Register */ +#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */ +#define LPC_EN 0x82 /* LPC IF Enables Register */ +#define LPC_EN_COMA (1 << 0) /* COM port A */ +#define LPC_EN_COMB (1 << 1) /* COM port B */ +#define LPC_EN_PARP (1 << 2) /* Parallel port */ +#define LPC_EN_FLP (1 << 3) /* Floppy */ +#define LPC_EN_LGAME (1 << 8) /* Low Gameport, 0x200-0x207 */ +#define LPC_EN_HGAME (1 << 9) /* High Gameport, 0x208-0x20f */ +#define LPC_EN_KB (1 << 10) /* Keyboard, 0x60, 0x64 */ +#define LPC_EN_MC1 (1 << 11) /* Microcontroller #1, 0x62, 0x66 */ +#define LPC_EN_MC2 (1 << 13) /* Microcontroller #2, 0x4e, 0x4f */ +#define LPC_EN_SIO (1 << 12) /* Super IO, 0x2e, 0x2f */ + +#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 */ + +#endif //_SOC_APOLLOLAKE_LPC_H diff --git a/src/soc/intel/apollolake/include/soc/pci_devs.h b/src/soc/intel/apollolake/include/soc/pci_devs.h index 7b8caafd69..ae80a04f86 100644 --- a/src/soc/intel/apollolake/include/soc/pci_devs.h +++ b/src/soc/intel/apollolake/include/soc/pci_devs.h @@ -48,8 +48,11 @@ #define LPSS_DEV_UART2 _LPSS_PCI_DEV(UART, 2) #define LPSS_DEV_UART3 _LPSS_PCI_DEV(UART, 3) +#define LPC_SLOT 0x1f + #define P2SB_DEV PCI_DEV(0, 0xd, 0) #define PMC_DEV PCI_DEV(0, 0xd, 1) #define SPI_DEV PCI_DEV(0, 0xd, 2) +#define LPC_DEV PCI_DEV(0, LPC_SLOT, 0) #endif diff --git a/src/soc/intel/apollolake/lpc.c b/src/soc/intel/apollolake/lpc.c index 902ada2bba..6e366e095f 100644 --- a/src/soc/intel/apollolake/lpc.c +++ b/src/soc/intel/apollolake/lpc.c @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2016 Intel Corp. + * Copyright (C) 2015-2016 Intel Corp. * (Written by Lance Zhao <lijian.zhao@intel.com> for Intel Corp.) * * This program is free software; you can redistribute it and/or modify @@ -20,6 +20,46 @@ #include <device/pci_ids.h> #include <soc/acpi.h> #include <soc/pci_ids.h> +#include <reg_script.h> +#include <vendorcode/google/chromeos/chromeos.h> +#include <soc/lpc.h> +#include "chip.h" + +static const struct reg_script lpc_serirq_enable[] = { + /* 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 + REG_SCRIPT_END +}; + +static void enable_lpc_decode(struct device *lpc) +{ + const struct soc_intel_apollolake_config *config; + + if (!lpc || !lpc->chip_info) + return; + + config = lpc->chip_info; + + /* Enable requested fixed IO decode ranges */ + pci_write_config16(lpc, LPC_EN, config->lpc_dec); + + /* Enable generic IO decode ranges */ + pci_write_config32(lpc, LPC_GEN1_DEC, config->gen1_dec); + pci_write_config32(lpc, LPC_GEN2_DEC, config->gen2_dec); + pci_write_config32(lpc, LPC_GEN3_DEC, config->gen3_dec); + pci_write_config32(lpc, LPC_GEN4_DEC, config->gen4_dec); +} + + +static void lpc_init(struct device *dev) +{ + enable_lpc_decode(dev); + reg_script_run_on_dev(dev, lpc_serirq_enable); +} + static void soc_lpc_add_io_resources(device_t dev) { @@ -46,6 +86,7 @@ static struct device_operations device_ops = { .set_resources = &pci_dev_set_resources, .enable_resources = &pci_dev_enable_resources, .write_acpi_tables = southbridge_write_acpi_tables, + .init = &lpc_init }; static const struct pci_driver soc_lpc __pci_driver = { |