tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / soc / intel / skylake / pmc.c
blobfb095896aa8745b50b7bc43572ebe181863484db
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2008-2009 coresystems GmbH
5 * Copyright (C) 2014 Google Inc.
6 * Copyright (C) 2015 Intel Corporation.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <chip.h>
19 #include <console/console.h>
20 #include <device/device.h>
21 #include <device/pci.h>
22 #include <device/pci_ids.h>
23 #include <arch/io.h>
24 #include <arch/ioapic.h>
25 #include <arch/acpi.h>
26 #include <cpu/cpu.h>
27 #include <pc80/mc146818rtc.h>
28 #include <reg_script.h>
29 #include <string.h>
30 #include <soc/gpio.h>
31 #include <soc/iomap.h>
32 #include <soc/pci_devs.h>
33 #include <soc/pmc.h>
34 #include <soc/pm.h>
35 #include <cpu/x86/smm.h>
36 #include <soc/pcr.h>
37 #include <soc/ramstage.h>
38 #if IS_ENABLED(CONFIG_CHROMEOS)
39 #include <vendorcode/google/chromeos/chromeos.h>
40 #endif
42 static const struct reg_script pch_pmc_misc_init_script[] = {
43 /* SLP_S4=4s, SLP_S3=50ms, disable SLP_X stretching after SUS loss. */
44 REG_PCI_RMW16(GEN_PMCON_B,
45 ~(S4MAW_MASK | SLP_S3_MIN_ASST_WDTH_MASK),
46 S4MAW_4S | SLP_S3_MIN_ASST_WDTH_50MS |
47 DIS_SLP_X_STRCH_SUS_UP),
48 /* Enable SCI and clear SLP requests. */
49 REG_IO_RMW32(ACPI_BASE_ADDRESS + PM1_CNT, ~SLP_TYP, SCI_EN),
50 REG_SCRIPT_END
53 static const struct reg_script pmc_write1_to_clear_script[] = {
54 REG_PCI_OR32(GEN_PMCON_A, 0),
55 REG_PCI_OR32(GEN_PMCON_B, 0),
56 REG_PCI_OR32(GEN_PMCON_B, 0),
57 REG_RES_OR32(PWRMBASE, GBLRST_CAUSE0, 0),
58 REG_RES_OR32(PWRMBASE, GBLRST_CAUSE1, 0),
59 REG_SCRIPT_END
62 static void pch_pmc_add_mmio_resources(device_t dev)
64 struct resource *res;
66 /* Memory-mmapped I/O registers. */
67 res = new_resource(dev, PWRMBASE);
68 res->base = PCH_PWRM_BASE_ADDRESS;
69 res->size = PCH_PWRM_BASE_SIZE;
70 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
71 IORESOURCE_FIXED | IORESOURCE_RESERVE;
74 static void pch_pmc_add_io_resource(device_t dev, u16 base, u16 size, int index)
76 struct resource *res;
77 res = new_resource(dev, index);
78 res->base = base;
79 res->size = size;
80 res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
83 static void pch_pmc_add_io_resources(device_t dev)
85 /* PMBASE */
86 pch_pmc_add_io_resource(dev, ACPI_BASE_ADDRESS, ACPI_BASE_SIZE, ABASE);
89 static void pch_pmc_read_resources(device_t dev)
91 /* Get the normal PCI resources of this device. */
92 pci_dev_read_resources(dev);
94 /* Add non-standard MMIO resources. */
95 pch_pmc_add_mmio_resources(dev);
97 /* Add IO resources. */
98 pch_pmc_add_io_resources(dev);
101 static void pch_set_acpi_mode(void)
103 if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) && acpi_slp_type != 3) {
104 printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n");
105 outb(APM_CNT_ACPI_DISABLE, APM_CNT);
106 printk(BIOS_DEBUG, "done.\n");
110 #if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS)
112 * Preserve Vboot NV data when clearing CMOS as it will
113 * have been re-initialized already by Vboot firmware init.
115 static void pch_cmos_init_preserve(int reset)
117 uint8_t vbnv[CONFIG_VBNV_SIZE];
118 if (reset)
119 read_vbnv(vbnv);
121 cmos_init(reset);
123 if (reset)
124 save_vbnv(vbnv);
126 #endif
128 static void pch_rtc_init(void)
130 u8 reg8;
131 int rtc_failed;
132 /*PMC Controller Device 0x1F, Func 02*/
133 device_t dev = PCH_DEV_PMC;
134 reg8 = pci_read_config8(dev, GEN_PMCON_B);
135 rtc_failed = reg8 & RTC_BATTERY_DEAD;
136 if (rtc_failed) {
137 reg8 &= ~RTC_BATTERY_DEAD;
138 pci_write_config8(dev, GEN_PMCON_B, reg8);
139 printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
142 #if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS)
143 pch_cmos_init_preserve(rtc_failed);
144 #else
145 cmos_init(rtc_failed);
146 #endif
149 static void pmc_gpe_init(config_t *config)
151 uint8_t *pmc_regs;
152 uint32_t gpio_cfg;
153 uint32_t gpio_cfg_reg;
154 const uint32_t gpio_cfg_mask =
155 (GPE0_DWX_MASK << GPE0_DW0_SHIFT) |
156 (GPE0_DWX_MASK << GPE0_DW1_SHIFT) |
157 (GPE0_DWX_MASK << GPE0_DW2_SHIFT);
159 pmc_regs = pmc_mmio_regs();
160 gpio_cfg = 0;
162 /* Route the GPIOs to the GPE0 block. Determine that all values
163 * are different, and if they aren't use the reset values. */
164 if (config->gpe0_dw0 == config->gpe0_dw1 ||
165 config->gpe0_dw1 == config->gpe0_dw2) {
166 printk(BIOS_INFO, "PMC: Using default GPE route.\n");
167 gpio_cfg = read32(pmc_regs + GPIO_CFG);
168 } else {
169 gpio_cfg |= (uint32_t)config->gpe0_dw0 << GPE0_DW0_SHIFT;
170 gpio_cfg |= (uint32_t)config->gpe0_dw1 << GPE0_DW1_SHIFT;
171 gpio_cfg |= (uint32_t)config->gpe0_dw2 << GPE0_DW2_SHIFT;
173 gpio_cfg_reg = read32(pmc_regs + GPIO_CFG) & ~gpio_cfg_mask;
174 gpio_cfg_reg |= gpio_cfg & gpio_cfg_mask;
175 write32(pmc_regs + GPIO_CFG, gpio_cfg_reg);
177 /* Set the routes in the GPIO communities as well. */
178 gpio_route_gpe(gpio_cfg_reg >> GPE0_DW0_SHIFT);
180 /* Set GPE enables based on devictree. */
181 enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2,
182 config->gpe0_en_3, config->gpe0_en_4);
185 static void pch_power_options(void)
187 u16 reg16;
188 const char *state;
189 /*PMC Controller Device 0x1F, Func 02*/
190 device_t dev = PCH_DEV_PMC;
191 /* Get the chip configuration */
192 config_t *config = dev->chip_info;
193 int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
196 * Which state do we want to goto after g3 (power restored)?
197 * 0 == S0 Full On
198 * 1 == S5 Soft Off
200 * If the option is not existent (Laptops), use Kconfig setting.
202 /*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/
203 //get_option(&pwr_on, "power_on_after_fail");
204 pwr_on = MAINBOARD_POWER_ON;
205 reg16 = pci_read_config16(dev, GEN_PMCON_B);
206 reg16 &= 0xfffe;
207 switch (pwr_on) {
208 case MAINBOARD_POWER_OFF:
209 reg16 |= 1;
210 state = "off";
211 break;
212 case MAINBOARD_POWER_ON:
213 reg16 &= ~1;
214 state = "on";
215 break;
216 case MAINBOARD_POWER_KEEP:
217 reg16 &= ~1;
218 state = "state keep";
219 break;
220 default:
221 state = "undefined";
223 pci_write_config16(dev, GEN_PMCON_B, reg16);
224 printk(BIOS_INFO, "Set power %s after power failure.\n", state);
226 /* Set up GPE configuration. */
227 pmc_gpe_init(config);
230 static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
232 uint32_t reg;
233 uint8_t *pmcbase = pmc_mmio_regs();
235 printk(BIOS_DEBUG, "%sabling Deep S%c\n",
236 enable ? "En" : "Dis", sx + '0');
237 reg = read32(pmcbase + offset);
238 if (enable)
239 reg |= mask;
240 else
241 reg &= ~mask;
242 write32(pmcbase + offset, reg);
245 static void config_deep_s5(int on)
247 /* Treat S4 the same as S5. */
248 config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS | S4AC_GATE_SUS, 4, on);
249 config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS | S5AC_GATE_SUS, 5, on);
252 static void config_deep_s3(int on)
254 config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS | S3AC_GATE_SUS, 3, on);
257 static void config_deep_sx(uint32_t deepsx_config)
259 uint32_t reg;
260 uint8_t *pmcbase = pmc_mmio_regs();
262 reg = read32(pmcbase + DSX_CFG);
263 reg &= ~DSX_CFG_MASK;
264 reg |= deepsx_config;
265 write32(pmcbase + DSX_CFG, reg);
268 static void pmc_init(struct device *dev)
270 config_t *config = dev->chip_info;
272 pch_rtc_init();
274 /* Initialize power management */
275 pch_power_options();
277 /* Note that certain bits may be cleared from running script as
278 * certain bit fields are write 1 to clear. */
279 reg_script_run_on_dev(dev, pch_pmc_misc_init_script);
280 pch_set_acpi_mode();
282 config_deep_s3(config->deep_s3_enable);
283 config_deep_s5(config->deep_s5_enable);
284 config_deep_sx(config->deep_sx_config);
286 /* Clear registers that contain write-1-to-clear bits. */
287 reg_script_run_on_dev(dev, pmc_write1_to_clear_script);
290 static struct device_operations device_ops = {
291 .read_resources = &pch_pmc_read_resources,
292 .set_resources = &pci_dev_set_resources,
293 .enable_resources = &pci_dev_enable_resources,
294 .init = &pmc_init,
295 .scan_bus = &scan_lpc_bus,
296 .ops_pci = &soc_pci_ops,
299 static const unsigned short pci_device_ids[] = {
300 0x9d21,
304 static const struct pci_driver pch_lpc __pci_driver = {
305 .ops = &device_ops,
306 .vendor = PCI_VENDOR_ID_INTEL,
307 .devices = pci_device_ids,