2 * This file is part of the coreboot project.
4 * Copyright (C) 2014 Google Inc.
5 * Copyright (C) 2015 Intel Corporation.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
18 #include <bootstate.h>
20 #include <console/console.h>
21 #include <console/post_codes.h>
22 #include <cpu/x86/smm.h>
23 #include <device/pci.h>
24 #include <intelblocks/fast_spi.h>
25 #include <intelblocks/pcr.h>
26 #include <reg_script.h>
27 #include <spi-generic.h>
31 #include <soc/pci_devs.h>
32 #include <soc/pcr_ids.h>
34 #include <soc/smbus.h>
35 #include <soc/systemagent.h>
38 #define PCR_DMI_GCS 0x274C
39 #define PCR_DMI_GCS_BILD (1 << 0)
40 #define PSF_BASE_ADDRESS 0xA00
41 #define PCR_PSFX_T0_SHDW_PCIEN 0x1C
42 #define PCR_PSFX_T0_SHDW_PCIEN_FUNDIS (1 << 8)
44 static void pch_configure_endpoints(device_t dev
, int epmask_id
, uint32_t mask
)
48 reg32
= pci_read_config32(dev
, PCH_P2SB_EPMASK(epmask_id
));
49 pci_write_config32(dev
, PCH_P2SB_EPMASK(epmask_id
), reg32
| mask
);
52 static void disable_sideband_access(void)
61 * Set p2sb PCI offset EPMASK5 C4h [29, 28, 27, 26] to disable Sideband
62 * access for PCI Root Bridge.
63 * Set p2sb PCI offset EPMASK5 C4h [17, 16,10, 1] to disable Sideband
64 * access for MIPI controller.
66 mask
= (1 << 29) | (1 << 28) | (1 << 27) | (1 << 26) | (1 << 17) |
67 (1 << 16) | (1 << 10) | (1 << 1);
68 pch_configure_endpoints(dev
, 5, mask
);
71 * Set p2sb PCI offset EPMASK7 CCh ports E6, E5 (bits 6, 5)
72 * to disable Sideband access for XHCI controller.
74 mask
= (1 << 6) | (1 << 5);
75 pch_configure_endpoints(dev
, 7, mask
);
77 /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */
78 reg8
= pci_read_config8(dev
, PCH_P2SB_E0
+ 2);
79 pci_write_config8(dev
, PCH_P2SB_E0
+ 2, reg8
| (1 << 1));
81 /* hide p2sb device */
82 pci_write_config8(dev
, PCH_P2SB_E0
+ 1, 1);
85 static void pch_disable_heci(void)
87 device_t dev
= PCH_DEV_P2SB
;
90 * if p2sb device 1f.1 is not present or hidden in devicetree
91 * p2sb device becomes NULL
96 /* unhide p2sb device */
97 pci_write_config8(dev
, PCH_P2SB_E0
+ 1, 0);
100 pcr_or32(PID_PSF1
, PSF_BASE_ADDRESS
+ PCR_PSFX_T0_SHDW_PCIEN
,
101 PCR_PSFX_T0_SHDW_PCIEN_FUNDIS
);
103 disable_sideband_access();
106 static void pch_finalize_script(void)
117 /* Set FAST_SPI opcode menu */
118 fast_spi_set_opcode_menu();
120 /* Lock FAST_SPIBAR */
124 tcobase
= smbus_tco_regs();
125 tcocnt
= inw(tcobase
+ TCO1_CNT
);
127 outw(tcocnt
, tcobase
+ TCO1_CNT
);
129 /* Lock down ABASE and sleep stretching policy */
131 reg32
= pci_read_config32(dev
, GEN_PMCON_B
);
132 reg32
|= (SLP_STR_POL_LOCK
| ACPI_BASE_LOCK
);
133 pci_write_config32(dev
, GEN_PMCON_B
, reg32
);
136 pmcbase
= pmc_mmio_regs();
137 pmsyncreg
= read32(pmcbase
+ PMSYNC_TPR_CFG
);
138 pmsyncreg
|= PMSYNC_LOCK
;
139 write32(pmcbase
+ PMSYNC_TPR_CFG
, pmsyncreg
);
141 /* Display me status before we hide it */
144 /* we should disable Heci1 based on the devicetree policy */
145 config
= dev
->chip_info
;
148 * Disable ACPI PM timer based on dt policy
150 * Disabling ACPI PM timer is necessary for XTAL OSC shutdown.
151 * Disabling ACPI PM timer also switches off TCO
154 if (config
->PmTimerDisabled
) {
155 reg8
= read8(pmcbase
+ PCH_PWRM_ACPI_TMR_CTL
);
157 write8(pmcbase
+ PCH_PWRM_ACPI_TMR_CTL
, reg8
);
160 /* Disable XTAL shutdown qualification for low power idle. */
161 if (config
->s0ix_enable
) {
162 reg32
= read32(pmcbase
+ CIR31C
);
164 write32(pmcbase
+ CIR31C
, reg32
);
167 /* we should disable Heci1 based on the devicetree policy */
168 if (config
->HeciEnabled
== 0)
172 static void soc_lockdown(void)
176 const struct device
*dev1
= dev_find_slot(0, PCH_DEVFN_LPC
);
177 const struct soc_intel_skylake_config
*config
= dev1
->chip_info
;
179 /* Global SMI Lock */
180 if (config
->LockDownConfigGlobalSmi
== 0) {
182 reg8
= pci_read_config8(dev
, GEN_PMCON_A
);
184 pci_write_config8(dev
, GEN_PMCON_A
, reg8
);
187 if (config
->chipset_lockdown
== CHIPSET_LOCKDOWN_COREBOOT
) {
188 /* Bios Interface Lock */
189 fast_spi_set_bios_interface_lock_down();
192 pcr_or8(PID_DMI
, PCR_DMI_GCS
, PCR_DMI_GCS_BILD
);
195 fast_spi_set_lock_enable();
199 static void soc_finalize(void *unused
)
201 printk(BIOS_DEBUG
, "Finalizing chipset.\n");
203 pch_finalize_script();
207 printk(BIOS_DEBUG
, "Finalizing SMM.\n");
208 outb(APM_CNT_FINALIZE
, APM_CNT
);
210 /* Indicate finalize step with post code */
211 post_code(POST_OS_BOOT
);
214 BOOT_STATE_INIT_ENTRY(BS_OS_RESUME
, BS_ON_ENTRY
, soc_finalize
, NULL
);
215 BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD
, BS_ON_EXIT
, soc_finalize
, NULL
);