blob: 9cb246ca404da753960d035f8ffae76afd6ee7e5 [file] [log] [blame]
Lee Leahyb0005132015-05-12 18:19:47 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Google Inc.
Lee Leahy1d14b3e2015-05-12 18:23:27 -07005 * Copyright (C) 2015 Intel Corporation.
Lee Leahyb0005132015-05-12 18:19:47 -07006 *
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.
10 *
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.
Lee Leahyb0005132015-05-12 18:19:47 -070015 */
16
17#include <arch/io.h>
18#include <bootstate.h>
Rizwan Qureshie64f7942015-11-19 16:01:54 +053019#include <chip.h>
Lee Leahyb0005132015-05-12 18:19:47 -070020#include <console/console.h>
21#include <console/post_codes.h>
22#include <cpu/x86/smm.h>
Subrata Banike7ceae72017-03-08 17:59:40 +053023#include <device/pci.h>
24#include <intelblocks/pcr.h>
Lee Leahyb0005132015-05-12 18:19:47 -070025#include <reg_script.h>
26#include <spi-generic.h>
27#include <stdlib.h>
Rizwan Qureshie64f7942015-11-19 16:01:54 +053028#include <soc/lpc.h>
Dhaval Sharma9dca83c2016-01-18 17:28:20 +053029#include <soc/me.h>
Rizwan Qureshicf73c132016-08-04 20:01:12 +053030#include <soc/p2sb.h>
Lee Leahyb0005132015-05-12 18:19:47 -070031#include <soc/pci_devs.h>
Subrata Banike7ceae72017-03-08 17:59:40 +053032#include <soc/pcr_ids.h>
Lee Leahy1d14b3e2015-05-12 18:23:27 -070033#include <soc/pm.h>
Barnali Sarkar0dddcd72016-08-02 17:49:56 +053034#include <soc/smbus.h>
Lee Leahyb0005132015-05-12 18:19:47 -070035#include <soc/spi.h>
36#include <soc/systemagent.h>
Subrata Banike7ceae72017-03-08 17:59:40 +053037
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)
Archana Patni7846e342015-11-11 01:29:23 +053043
Archana Patni7846e342015-11-11 01:29:23 +053044static void pch_configure_endpoints(device_t dev, int epmask_id, uint32_t mask)
45{
46 uint32_t reg32;
47
48 reg32 = pci_read_config32(dev, PCH_P2SB_EPMASK(epmask_id));
49 pci_write_config32(dev, PCH_P2SB_EPMASK(epmask_id), reg32 | mask);
50}
51
52static void pch_disable_heci(void)
53{
54 device_t dev;
55 u8 reg8;
56 uint32_t mask;
57
58 dev = PCH_DEV_P2SB;
59
60 /*
61 * if p2sb device 1f.1 is not present or hidden in devicetree
62 * p2sb device becomes NULL
63 */
64 if (!dev)
65 return;
66
67 /* unhide p2sb device */
68 pci_write_config8(dev, PCH_P2SB_E0 + 1, 0);
69
70 /* disable heci */
Subrata Banike7ceae72017-03-08 17:59:40 +053071 pcr_or32(PID_PSF1, PSF_BASE_ADDRESS + PCR_PSFX_T0_SHDW_PCIEN,
72 PCR_PSFX_T0_SHDW_PCIEN_FUNDIS);
Archana Patni7846e342015-11-11 01:29:23 +053073
74 /* Remove the host accessing right to PSF register range. */
75 /* Set p2sb PCI offset EPMASK5 C4h [29, 28, 27, 26] to [1, 1, 1, 1] */
76 mask = (1 << 29) | (1 << 28) | (1 << 27) | (1 << 26);
77 pch_configure_endpoints(dev, 5, mask);
78
79 /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */
80 reg8 = pci_read_config8(dev, PCH_P2SB_E0 + 2);
81 pci_write_config8(dev, PCH_P2SB_E0 + 2, reg8 | (1 << 1));
82
83 /* hide p2sb device */
84 pci_write_config8(dev, PCH_P2SB_E0 + 1, 1);
85}
Lee Leahyb0005132015-05-12 18:19:47 -070086
Lee Leahy1d14b3e2015-05-12 18:23:27 -070087static void pch_finalize_script(void)
88{
89 device_t dev;
90 uint32_t reg32, hsfs;
91 void *spibar = get_spi_bar();
Lee Leahy1d14b3e2015-05-12 18:23:27 -070092 u16 tcobase;
93 u16 tcocnt;
94 uint8_t *pmcbase;
Archana Patni7846e342015-11-11 01:29:23 +053095 config_t *config;
Lee Leahy1d14b3e2015-05-12 18:23:27 -070096 u32 pmsyncreg;
Archana Patni6c1bf272015-12-18 23:38:21 +053097 u8 reg8;
Lee Leahyb0005132015-05-12 18:19:47 -070098
Lee Leahyb0005132015-05-12 18:19:47 -070099 /* Set SPI opcode menu */
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700100 write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX);
101 write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE);
102 write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER);
103 write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER);
Lee Leahyb0005132015-05-12 18:19:47 -0700104 /* Lock SPIBAR */
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700105 hsfs = read32(spibar + SPIBAR_HSFS);
106 hsfs |= SPIBAR_HSFS_FLOCKDN;
107 write32(spibar + SPIBAR_HSFS, hsfs);
Lee Leahyb0005132015-05-12 18:19:47 -0700108
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530109 /*TCO Lock down */
Barnali Sarkar49eca132016-08-12 00:05:27 +0530110 tcobase = smbus_tco_regs();
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700111 tcocnt = inw(tcobase + TCO1_CNT);
112 tcocnt |= TCO_LOCK;
113 outw(tcocnt, tcobase + TCO1_CNT);
Lee Leahyb0005132015-05-12 18:19:47 -0700114
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700115 /* Lock down ABASE and sleep stretching policy */
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530116 dev = PCH_DEV_PMC;
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700117 reg32 = pci_read_config32(dev, GEN_PMCON_B);
118 reg32 |= (SLP_STR_POL_LOCK | ACPI_BASE_LOCK);
119 pci_write_config32(dev, GEN_PMCON_B, reg32);
Lee Leahyb0005132015-05-12 18:19:47 -0700120
121 /* PMSYNC */
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700122 pmcbase = pmc_mmio_regs();
123 pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG);
124 pmsyncreg |= PMSYNC_LOCK;
125 write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg);
Archana Patni7846e342015-11-11 01:29:23 +0530126
Dhaval Sharma9dca83c2016-01-18 17:28:20 +0530127 /* Display me status before we hide it */
128 intel_me_status();
129
Archana Patni7846e342015-11-11 01:29:23 +0530130 /* we should disable Heci1 based on the devicetree policy */
131 config = dev->chip_info;
Archana Patni6c1bf272015-12-18 23:38:21 +0530132
133 /*
134 * Disable ACPI PM timer based on dt policy
135 *
136 * Disabling ACPI PM timer is necessary for XTAL OSC shutdown.
137 * Disabling ACPI PM timer also switches off TCO
138 */
139
140 if (config->PmTimerDisabled) {
141 reg8 = read8(pmcbase + PCH_PWRM_ACPI_TMR_CTL);
142 reg8 |= (1 << 1);
143 write8(pmcbase + PCH_PWRM_ACPI_TMR_CTL, reg8);
144 }
145
Naresh G Solankic261c4b2017-04-25 12:09:07 +0530146 /* Disable XTAL shutdown qualification for low power idle. */
147 if (config->s0ix_enable) {
148 reg32 = read32(pmcbase + CIR31C);
149 reg32 |= XTALSDQDIS;
150 write32(pmcbase + CIR31C, reg32);
151 }
152
Archana Patni6c1bf272015-12-18 23:38:21 +0530153 /* we should disable Heci1 based on the devicetree policy */
Archana Patni7846e342015-11-11 01:29:23 +0530154 if (config->HeciEnabled == 0)
155 pch_disable_heci();
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700156}
Lee Leahyb0005132015-05-12 18:19:47 -0700157
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530158static void soc_lockdown(void)
159{
160 u8 reg8;
161 device_t dev;
162 const struct device *dev1 = dev_find_slot(0, PCH_DEVFN_LPC);
163 const struct soc_intel_skylake_config *config = dev1->chip_info;
164
165 /* Global SMI Lock */
166 if (config->LockDownConfigGlobalSmi == 0) {
167 dev = PCH_DEV_PMC;
168 reg8 = pci_read_config8(dev, GEN_PMCON_A);
169 reg8 |= SMI_LOCK;
170 pci_write_config8(dev, GEN_PMCON_A, reg8);
171 }
172
173 /* Bios Interface Lock */
174 if (config->LockDownConfigBiosInterface == 0) {
175 pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
176 pci_read_config8(PCH_DEV_LPC,
177 BIOS_CNTL) | LPC_BC_BILD);
178 /* Reads back for posted write to take effect */
179 pci_read_config8(PCH_DEV_LPC, BIOS_CNTL);
180 pci_write_config32(PCH_DEV_SPI, SPIBAR_BIOS_CNTL,
181 pci_read_config32(PCH_DEV_SPI,
182 SPIBAR_BIOS_CNTL) |
183 SPIBAR_BC_BILD);
184 /* Reads back for posted write to take effect */
185 pci_read_config32(PCH_DEV_SPI, SPIBAR_BIOS_CNTL);
186 /* GCS reg of DMI */
Subrata Banike7ceae72017-03-08 17:59:40 +0530187 pcr_or8(PID_DMI, PCR_DMI_GCS, PCR_DMI_GCS_BILD);
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530188 }
189
190 /* Bios Lock */
191 if (config->LockDownConfigBiosLock == 0) {
192 pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
193 pci_read_config8(PCH_DEV_LPC,
194 BIOS_CNTL) | LPC_BC_LE);
195 pci_write_config8(PCH_DEV_SPI, BIOS_CNTL,
196 pci_read_config8(PCH_DEV_SPI,
197 BIOS_CNTL) | SPIBAR_BC_LE);
198 }
199
200 /* SPIEiss */
201 if (config->LockDownConfigSpiEiss == 0) {
202 pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
203 pci_read_config8(PCH_DEV_LPC,
204 BIOS_CNTL) | LPC_BC_EISS);
205 pci_write_config8(PCH_DEV_SPI, BIOS_CNTL,
206 pci_read_config8(PCH_DEV_SPI,
207 SPIBAR_BIOS_CNTL) |
208 SPIBAR_BC_EISS);
209 }
210}
211
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700212static void soc_finalize(void *unused)
Lee Leahyb0005132015-05-12 18:19:47 -0700213{
214 printk(BIOS_DEBUG, "Finalizing chipset.\n");
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530215
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700216 pch_finalize_script();
Lee Leahyb0005132015-05-12 18:19:47 -0700217
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530218 soc_lockdown();
219
Duncan Laurie6f0e6fa2016-02-09 09:40:39 -0800220 printk(BIOS_DEBUG, "Finalizing SMM.\n");
221 outb(APM_CNT_FINALIZE, APM_CNT);
222
Lee Leahyb0005132015-05-12 18:19:47 -0700223 /* Indicate finalize step with post code */
224 post_code(POST_OS_BOOT);
225}
226
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700227BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL);
228BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, soc_finalize, NULL);