blob: fa2411ddd2a609402edf8ea986087ae30495b630 [file] [log] [blame]
Aamir Bohra3ee54bb2018-10-17 11:55:01 +05301/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2018 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16/*
17 * Helper functions for dealing with power management registers
18 * and the differences between PCH variants.
19 */
20
21#define __SIMPLE_DEVICE__
22
Kyösti Mälkki13f66502019-03-03 08:01:05 +020023#include <device/mmio.h>
Aamir Bohra3ee54bb2018-10-17 11:55:01 +053024#include <cbmem.h>
25#include <device/device.h>
26#include <device/pci.h>
27#include <device/pci_def.h>
28#include <console/console.h>
29#include <intelblocks/pmclib.h>
30#include <intelblocks/rtc.h>
Subrata Banik7bc4dc52018-05-17 18:40:32 +053031#include <intelblocks/tco.h>
Aamir Bohra3ee54bb2018-10-17 11:55:01 +053032#include <stdlib.h>
33#include <soc/gpe.h>
34#include <soc/gpio.h>
35#include <soc/iomap.h>
36#include <soc/lpc.h>
37#include <soc/pci_devs.h>
38#include <soc/pm.h>
39#include <soc/smbus.h>
40#include <timer.h>
41#include <security/vboot/vbnv.h>
42#include "chip.h"
43
44/*
45 * SMI
46 */
47
48const char *const *soc_smi_sts_array(size_t *a)
49{
50 static const char *const smi_sts_bits[] = {
51 [BIOS_STS_BIT] = "BIOS",
52 [LEGACY_USB_STS_BIT] = "LEGACY_USB",
53 [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI",
54 [APM_STS_BIT] = "APM",
55 [SWSMI_TMR_STS_BIT] = "SWSMI_TMR",
56 [PM1_STS_BIT] = "PM1",
57 [GPE0_STS_BIT] = "GPE0",
58 [GPIO_STS_BIT] = "GPI",
59 [MCSMI_STS_BIT] = "MCSMI",
60 [DEVMON_STS_BIT] = "DEVMON",
61 [TCO_STS_BIT] = "TCO",
62 [PERIODIC_STS_BIT] = "PERIODIC",
63 [SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI",
64 [SMBUS_SMI_STS_BIT] = "SMBUS_SMI",
65 [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI",
66 [MONITOR_STS_BIT] = "MONITOR",
67 [SPI_SMI_STS_BIT] = "SPI",
68 [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK",
69 [ESPI_SMI_STS_BIT] = "ESPI_SMI",
70 };
71
72 *a = ARRAY_SIZE(smi_sts_bits);
73 return smi_sts_bits;
74}
75
76/*
77 * TCO
78 */
79
80const char *const *soc_tco_sts_array(size_t *a)
81{
82 static const char *const tco_sts_bits[] = {
83 [0] = "NMI2SMI",
84 [1] = "SW_TCO",
85 [2] = "TCO_INT",
86 [3] = "TIMEOUT",
87 [7] = "NEWCENTURY",
88 [8] = "BIOSWR",
89 [9] = "DMISCI",
90 [10] = "DMISMI",
91 [12] = "DMISERR",
92 [13] = "SLVSEL",
93 [16] = "INTRD_DET",
94 [17] = "SECOND_TO",
95 [18] = "BOOT",
96 [20] = "SMLINK_SLV"
97 };
98
99 *a = ARRAY_SIZE(tco_sts_bits);
100 return tco_sts_bits;
101}
102
103/*
104 * GPE0
105 */
106
107const char *const *soc_std_gpe_sts_array(size_t *a)
108{
109 static const char *const gpe_sts_bits[] = {
110 [1] = "HOTPLUG",
111 [2] = "SWGPE",
112 [6] = "TCO_SCI",
113 [7] = "SMB_WAK",
114 [9] = "PCI_EXP",
115 [10] = "BATLOW",
116 [11] = "PME",
117 [12] = "ME",
118 [13] = "PME_B0",
119 [14] = "eSPI",
120 [15] = "GPIO Tier-2",
121 [16] = "LAN_WAKE",
122 [18] = "WADT"
123 };
124
125 *a = ARRAY_SIZE(gpe_sts_bits);
126 return gpe_sts_bits;
127}
128
129void pmc_set_disb(void)
130{
131 /* Set the DISB after DRAM init */
132 uint8_t disb_val;
133 /* Only care about bits [23:16] of register GEN_PMCON_A */
134 uint8_t *addr = (void *)(pmc_mmio_regs() + GEN_PMCON_A + 2);
135
136 disb_val = read8(addr);
137 disb_val |= (DISB >> 16);
138
139 /* Don't clear bits that are write-1-to-clear */
140 disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16);
141 write8(addr, disb_val);
142}
143
144/*
145 * PMC controller gets hidden from PCI bus
146 * during FSP-Silicon init call. Hence PWRMBASE
147 * can't be accessible using PCI configuration space
148 * read/write.
149 */
150uint8_t *pmc_mmio_regs(void)
151{
152 return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS;
153}
154
Aamir Bohra3ee54bb2018-10-17 11:55:01 +0530155uintptr_t soc_read_pmc_base(void)
156{
157 return (uintptr_t)pmc_mmio_regs();
158}
159
160void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
161{
162 DEVTREE_CONST struct soc_intel_icelake_config *config;
163
164 /* Look up the device in devicetree */
165 DEVTREE_CONST struct device *dev = dev_find_slot(0, PCH_DEVFN_PMC);
166 if (!dev || !dev->chip_info) {
167 printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n");
168 return;
169 }
170 config = dev->chip_info;
171
172 /* Assign to out variable */
173 *dw0 = config->gpe0_dw0;
174 *dw1 = config->gpe0_dw1;
175 *dw2 = config->gpe0_dw2;
176}
177
178static int rtc_failed(uint32_t gen_pmcon_b)
179{
180 return !!(gen_pmcon_b & RTC_BATTERY_DEAD);
181}
182
183int soc_get_rtc_failed(void)
184{
185 const struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE);
186
187 if (!ps) {
188 printk(BIOS_ERR, "Could not find power state in cbmem, RTC init aborted\n");
189 return 1;
190 }
191
192 return rtc_failed(ps->gen_pmcon_b);
193}
194
195int vbnv_cmos_failed(void)
196{
197 return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B));
198}