From f35804ba6f14d748568119206bdfe26046c9606b Mon Sep 17 00:00:00 2001 From: Andrey Petrov Date: Mon, 5 Jun 2017 13:22:41 -0700 Subject: soc/intel/cannonlake: Add bootblock PCH Add essential initialization needed for PCH in bootblock. Change-Id: I3694e099e78c2989f7192c550cbba098e5df2032 Signed-off-by: Andrey Petrov Reviewed-on: https://review.coreboot.org/20067 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/soc/intel/cannonlake/bootblock/pch.c | 199 +++++++++++++++++++++ src/soc/intel/cannonlake/include/soc/lpc.h | 55 ++++++ src/soc/intel/cannonlake/include/soc/p2sb.h | 27 +++ src/soc/intel/cannonlake/include/soc/pch.h | 32 ++++ src/soc/intel/cannonlake/include/soc/pcr_ids.h | 38 ++++ src/soc/intel/cannonlake/include/soc/smbus.h | 47 +++++ src/soc/intel/cannonlake/include/soc/systemagent.h | 104 +++++++++++ 7 files changed, 502 insertions(+) create mode 100644 src/soc/intel/cannonlake/bootblock/pch.c create mode 100644 src/soc/intel/cannonlake/include/soc/lpc.h create mode 100644 src/soc/intel/cannonlake/include/soc/p2sb.h create mode 100644 src/soc/intel/cannonlake/include/soc/pch.h create mode 100644 src/soc/intel/cannonlake/include/soc/pcr_ids.h create mode 100644 src/soc/intel/cannonlake/include/soc/smbus.h create mode 100644 src/soc/intel/cannonlake/include/soc/systemagent.h (limited to 'src') diff --git a/src/soc/intel/cannonlake/bootblock/pch.c b/src/soc/intel/cannonlake/bootblock/pch.c new file mode 100644 index 0000000000..9d326bb7c5 --- /dev/null +++ b/src/soc/intel/cannonlake/bootblock/pch.c @@ -0,0 +1,199 @@ +/* + * This file is part of the coreboot project. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PCR_PSF3_TO_SHDW_PMC_REG_BASE 0x1400 +#define PCR_PSFX_TO_SHDW_BAR0 0 +#define PCR_PSFX_TO_SHDW_BAR1 0x4 +#define PCR_PSFX_TO_SHDW_BAR2 0x8 +#define PCR_PSFX_TO_SHDW_BAR3 0xC +#define PCR_PSFX_TO_SHDW_BAR4 0x10 +#define PCR_PSFX_TO_SHDW_PCIEN_IOEN 0x01 +#define PCR_PSFX_T0_SHDW_PCIEN 0x1C + +#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 TCOEN (1 << 1) /* Enable TCO I/O range decode. */ + +#define PCR_DMI_LPCIOD 0x2770 +#define PCR_DMI_LPCIOE 0x2774 + +static void enable_p2sbbar(void) +{ + device_t dev = PCH_DEV_P2SB; + + /* Enable PCR Base address in PCH */ + pci_write_config32(dev, PCI_BASE_ADDRESS_0, CONFIG_PCR_BASE_ADDRESS); + + /* Enable P2SB MSE */ + pci_write_config8(dev, PCI_COMMAND, + PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + /* + * Enable decoding for HPET memory address range. + * HPTC_OFFSET(0x60) bit 7, when set the P2SB will decode + * the High Performance Timer memory address range + * selected by bits 1:0 + */ + pci_write_config8(dev, HPTC_OFFSET, HPTC_ADDR_ENABLE_BIT); +} + +static void soc_config_pwrmbase(void) +{ + uint32_t reg32; + + /* Assign Resources to PWRMBASE */ + /* Clear BIT 1-2 Command Register */ + reg32 = pci_read_config32(PCH_DEV_PMC, PCI_COMMAND); + reg32 &= ~(PCI_COMMAND_MEMORY); + pci_write_config32(PCH_DEV_PMC, PCI_COMMAND, reg32); + + /* Program PWRM Base */ + pci_write_config32(PCH_DEV_PMC, PWRMBASE, PCH_PWRM_BASE_ADDRESS); + + /* Enable Bus Master and MMIO Space */ + reg32 = pci_read_config32(PCH_DEV_PMC, PCI_COMMAND); + reg32 |= PCI_COMMAND_MEMORY; + pci_write_config32(PCH_DEV_PMC, PCI_COMMAND, reg32); + + /* Enable PWRM in PMC */ + reg32 = read32((void *)(PCH_PWRM_BASE_ADDRESS + ACTL)); + write32((void *)(PCH_PWRM_BASE_ADDRESS + ACTL), reg32 | PWRM_EN); +} + +void bootblock_pch_early_init(void) +{ + fast_spi_early_init(SPI_BASE_ADDRESS); + enable_p2sbbar(); + /* + * Enabling PWRM Base for accessing + * Global Reset Cause Register. + */ + soc_config_pwrmbase(); +} + + +static void soc_config_acpibase(void) +{ + uint32_t pmc_reg_value; + + pmc_reg_value = pcr_read32(PID_PSF3, PCR_PSF3_TO_SHDW_PMC_REG_BASE + + PCR_PSFX_TO_SHDW_BAR4); + + if (pmc_reg_value != 0xFFFFFFFF) + { + /* Disable Io Space before changing the address */ + pcr_rmw32(PID_PSF3, PCR_PSF3_TO_SHDW_PMC_REG_BASE + + PCR_PSFX_T0_SHDW_PCIEN, + ~PCR_PSFX_TO_SHDW_PCIEN_IOEN, 0); + /* Program ABASE in PSF3 PMC space BAR4*/ + pcr_write32(PID_PSF3, PCR_PSF3_TO_SHDW_PMC_REG_BASE + + PCR_PSFX_TO_SHDW_BAR4, + ACPI_BASE_ADDRESS); + /* Enable IO Space */ + pcr_rmw32(PID_PSF3, PCR_PSF3_TO_SHDW_PMC_REG_BASE + + PCR_PSFX_T0_SHDW_PCIEN, + ~0, PCR_PSFX_TO_SHDW_PCIEN_IOEN); + } +} + +static void soc_config_tco(void) +{ + uint32_t reg32; + uint16_t tcobase; + uint16_t tcocnt; + + /* Disable TCO in SMBUS Device first before changing Base Address */ + reg32 = pci_read_config32(PCH_DEV_SMBUS, TCOCTL); + reg32 &= ~TCO_EN; + pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32); + + /* Program TCO Base */ + tcobase = TCO_BASE_ADDRESS; + pci_write_config32(PCH_DEV_SMBUS, TCOBASE, tcobase); + + /* Enable TCO in SMBUS */ + pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32 | TCO_BASE_EN); + + /* + * Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] + */ + pcr_write32(PID_DMI, PCR_DMI_TCOBASE, tcobase | TCOEN); + + /* Program TCO timer halt */ + tcocnt = inw(tcobase + TCO1_CNT); + tcocnt |= TCO_TMR_HLT; + outw(tcocnt, tcobase + TCO1_CNT); +} + +void pch_early_iorange_init(void) +{ + uint16_t dec_rng, dec_en = 0; + + /* IO Decode Range */ + if (IS_ENABLED(CONFIG_DRIVERS_UART_8250IO) && + IS_ENABLED(CONFIG_UART_DEBUG)) { + dec_rng = COMA_RANGE | (COMB_RANGE << 4); + dec_en = COMA_LPC_EN | COMB_LPC_EN; + pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, dec_rng); + pcr_write16(PID_DMI, PCR_DMI_LPCIOD, dec_rng); + } + + /* IO Decode Enable */ + dec_en |= SE_LPC_EN | KBC_LPC_EN | MC1_LPC_EN; + pci_write_config16(PCH_DEV_LPC, LPC_EN, dec_en); + pcr_write16(PID_DMI, PCR_DMI_LPCIOE, dec_en); +} + +void pch_early_init(void) +{ + /* + * Enabling ABASE for accessing PM1_STS, PM1_EN, PM1_CNT, + * GPE0_STS, GPE0_EN registers. + */ + soc_config_acpibase(); + + /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */ + soc_config_tco(); + + /* Program SMBUS_BASE_ADDRESS and Enable it */ + smbus_common_init(); + + enable_rtc_upper_bank(); + + heci_init(HECI1_BASE_ADDRESS); +} diff --git a/src/soc/intel/cannonlake/include/soc/lpc.h b/src/soc/intel/cannonlake/include/soc/lpc.h new file mode 100644 index 0000000000..3488ee2b85 --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/lpc.h @@ -0,0 +1,55 @@ +/* + * This file is part of the coreboot project. + * + * 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. + */ + +#ifndef _SOC_CANNONLAKE_LPC_H_ +#define _SOC_CANNONLAKE_LPC_H_ + +/* PCI Configuration Space (D31:F0): LPC */ +#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 MC2_LPC_EN (1 << 13) /* 0x4e/0x4f */ +#define SE_LPC_EN (1 << 12) /* 0x2e/0x2f */ +#define MC1_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) /* Floppy Drive Enable */ +#define LPT_LPC_EN (1 << 2) /* Parallel Port Enable */ +#define COMB_LPC_EN (1 << 1) /* Com Port B Enable */ +#define COMA_LPC_EN (1 << 0) /* Com Port A Enable */ +#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 << 2) /* 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/cannonlake/include/soc/p2sb.h b/src/soc/intel/cannonlake/include/soc/p2sb.h new file mode 100644 index 0000000000..1f209ed862 --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/p2sb.h @@ -0,0 +1,27 @@ +/* + * This file is part of the coreboot project. + * + * 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. + */ + +#ifndef _SOC_CANNONLAKE_P2SB_H_ +#define _SOC_CANNONLAKE_P2SB_H_ + +#define HPTC_OFFSET 0x60 +#define HPTC_ADDR_ENABLE_BIT (1 << 7) + +#define PCH_P2SB_EPMASK0 0x220 +#define PCH_P2SB_EPMASK(mask_number) (PCH_P2SB_EPMASK0 + (mask_number * 4)) + +#define PCH_P2SB_E0 0xE0 + +#endif diff --git a/src/soc/intel/cannonlake/include/soc/pch.h b/src/soc/intel/cannonlake/include/soc/pch.h new file mode 100644 index 0000000000..d8b3b955b6 --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/pch.h @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#ifndef _SOC_CANNONLAKE_PCH_H_ +#define _SOC_CANNONLAKE_PCH_H_ + +#include + +#define PCH_H 1 +#define PCH_LP 2 +#define PCH_UNKNOWN_SERIES 0xFF + +u8 pch_revision(void); +u16 pch_type(void); +void pch_log_state(void); +void pch_uart_init(void); + +#endif diff --git a/src/soc/intel/cannonlake/include/soc/pcr_ids.h b/src/soc/intel/cannonlake/include/soc/pcr_ids.h new file mode 100644 index 0000000000..65576aabcb --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/pcr_ids.h @@ -0,0 +1,38 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2017 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; 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_CANNONLAKE_PCR_H +#define SOC_CANNONLAKE_PCR_H +/* + * Port ids + */ +#define PID_GPIOCOM4 0x6a +#define PID_GPIOCOM3 0x6b +#define PID_GPIOCOM2 0x6c +#define PID_GPIOCOM1 0x6d +#define PID_GPIOCOM0 0x6e +#define PID_DMI 0x88 +#define PID_PSTH 0x89 +#define PID_PSF1 0xba +#define PID_PSF2 0xbb +#define PID_PSF3 0xbc +#define PID_PSF4 0xbd +#define PID_SCS 0xc0 +#define PID_RTC 0xc3 +#define PID_ITSS 0xc2 +#define PID_LPC 0xc7 +#define PID_SERIALIO 0xcb + +#endif diff --git a/src/soc/intel/cannonlake/include/soc/smbus.h b/src/soc/intel/cannonlake/include/soc/smbus.h new file mode 100644 index 0000000000..9de6981d5a --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/smbus.h @@ -0,0 +1,47 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Yinghai Lu + * Copyright (C) 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. + */ + +#ifndef _SOC_CANNONLAKE_SMBUS_H_ +#define _SOC_CANNONLAKE_SMBUS_H_ + +/* PCI registers */ +#define TCOBASE 0x50 /* TCO base address. */ +#define TCOCTL 0x54 +#define TCO_BASE_EN (1 << 8) /* TCO base enable. */ + +/* IO and MMIO registers under primary BAR */ +/* Set address for PCH as SMBus slave role */ +#define SMB_RCV_SLVA 0x09 + +/* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */ +#define TCO1_STS 0x04 +#define TCO2_STS 0x06 +#define TCO2_STS_SECOND_TO 0x02 +#define TCO2_STS_BOOT 0x04 +#define TCO1_CNT 0x08 +#define TCO_LOCK (1 << 12) +#define TCO_TMR_HLT (1 << 11) + +/* + * Default slave address value for PCH. This value is set to match default + * value set by hardware. It is useful since PCH is able to respond even + * before CPU is up. This is reset by RSMRST# but not by PLTRST#. + */ +#define SMBUS_SLAVE_ADDR 0x44 + +#endif diff --git a/src/soc/intel/cannonlake/include/soc/systemagent.h b/src/soc/intel/cannonlake/include/soc/systemagent.h new file mode 100644 index 0000000000..b06945084e --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/systemagent.h @@ -0,0 +1,104 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2008 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. + */ + +#ifndef SOC_CANNONLAKE_SYSTEMAGENT_H +#define SOC_CANNONLAKE_SYSTEMAGENT_H + +#include +#include + +/* Device 0:0.0 PCI configuration space */ + +#define EPBAR 0x40 +#define PCIEXBAR 0x60 +#define DMIBAR 0x68 +#define GGC 0x50 /* GMCH Graphics Control */ +#define DEVEN 0x54 /* Device Enable */ +#define DEVEN_D7EN (1 << 14) +#define DEVEN_D4EN (1 << 7) +#define DEVEN_D3EN (1 << 5) +#define DEVEN_D2EN (1 << 4) +#define DEVEN_D1F0EN (1 << 3) +#define DEVEN_D1F1EN (1 << 2) +#define DEVEN_D1F2EN (1 << 1) +#define DEVEN_D0EN (1 << 0) +#define DPR 0x5c +#define DPR_EPM (1 << 2) +#define DPR_PRS (1 << 1) +#define DPR_SIZE_MASK 0xff0 + +#define PAM0 0x80 +#define PAM1 0x81 +#define PAM2 0x82 +#define PAM3 0x83 +#define PAM4 0x84 +#define PAM5 0x85 +#define PAM6 0x86 + +#define SMRAM 0x88 /* System Management RAM Control */ +#define D_OPEN (1 << 6) +#define D_CLS (1 << 5) +#define D_LCK (1 << 4) +#define G_SMRAME (1 << 3) +#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0)) + +#define MESEG_BASE 0x70 /* Management Engine Base. */ +#define MESEG_LIMIT 0x78 /* Management Engine Limit. */ +#define TOM 0xa0 /* Top of DRAM in memory controller space. */ +#define SKPAD 0xdc /* Scratchpad Data */ + +/* MCHBAR */ + +#define MCHBAR8(x) (*(volatile u8 *)(MCH_BASE_ADDRESS + x)) +#define MCHBAR16(x) (*(volatile u16 *)(MCH_BASE_ADDRESS + x)) +#define MCHBAR32(x) (*(volatile u32 *)(MCH_BASE_ADDRESS + x)) + +#define MCHBAR_PEI_VERSION 0x5034 +#define REMAPBASE 0x5090 /* Remap base. */ +#define REMAPLIMIT 0x5098 /* Remap limit. */ +#define BIOS_RESET_CPL 0x5da8 +#define EDRAMBAR 0x5408 +#define MCH_PAIR 0x5418 +#define REGBAR 0x5420 + +#define MCH_PKG_POWER_LIMIT_LO 0x59a0 +#define MCH_PKG_POWER_LIMIT_HI 0x59a4 +#define MCH_DDR_POWER_LIMIT_LO 0x58e0 +#define MCH_DDR_POWER_LIMIT_HI 0x58e4 + +/* PCODE MMIO communications live in the MCHBAR. */ +#define BIOS_MAILBOX_INTERFACE 0x5da4 +#define MAILBOX_RUN_BUSY (1 << 31) +/* Errors are returned back in bits 7:0. */ +#define MAILBOX_BIOS_ERROR_NONE 0 +#define MAILBOX_BIOS_ERROR_INVALID_COMMAND 1 +#define MAILBOX_BIOS_ERROR_TIMEOUT 2 +#define MAILBOX_BIOS_ERROR_ILLEGAL_DATA 3 +#define MAILBOX_BIOS_ERROR_RESERVED 4 +#define MAILBOX_BIOS_ERROR_ILLEGAL_VR_ID 5 +#define MAILBOX_BIOS_ERROR_VR_INTERFACE_LOCKED 6 +#define MAILBOX_BIOS_ERROR_VR_ERROR 7 +/* Data is passed through bits 31:0 of the data register. */ +#define BIOS_MAILBOX_DATA 0x5da0 + +/* System Agent identification */ +u8 systemagent_revision(void); + +/* Top of 32bit usable memory */ +u32 top_of_32bit_ram(void); + +#endif -- cgit v1.2.3