blob: 7812eeb3ca4df95cef70af9d44beb49a55c55c76 [file] [log] [blame]
Lijian Zhaoac87a982017-08-28 17:46:55 -07001/*
2 * This file is part of the coreboot project.
3 *
Lijian Zhaoac87a982017-08-28 17:46:55 -07004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
Subrata Banik0baad612017-11-23 13:58:34 +053015#include <bootstate.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070016#include <console/console.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020017#include <device/mmio.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070018#include <device/device.h>
Subrata Banik0baad612017-11-23 13:58:34 +053019#include <intelblocks/pmc.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070020#include <intelblocks/pmclib.h>
21#include <intelblocks/rtc.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070022#include <soc/pci_devs.h>
23#include <soc/pm.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070024
Elyes HAOUASc3385072019-03-21 15:38:06 +010025#include "chip.h"
26
Subrata Banik33cd28e2017-12-19 12:33:59 +053027/*
28 * Set which power state system will be after reapplying
29 * the power (from G3 State)
30 */
Nico Huber733c28f2019-08-05 19:33:09 +020031void pmc_soc_set_afterg3_en(const bool on)
Subrata Banik33cd28e2017-12-19 12:33:59 +053032{
33 uint8_t reg8;
Nico Huber733c28f2019-08-05 19:33:09 +020034 uint8_t *const pmcbase = pmc_mmio_regs();
Subrata Banik33cd28e2017-12-19 12:33:59 +053035
Lijian Zhaoc3e75b42019-01-15 17:37:50 -080036 reg8 = read8(pmcbase + GEN_PMCON_A);
Nico Huber733c28f2019-08-05 19:33:09 +020037 if (on)
38 reg8 &= ~SLEEP_AFTER_POWER_FAIL;
39 else
40 reg8 |= SLEEP_AFTER_POWER_FAIL;
Lijian Zhaoc3e75b42019-01-15 17:37:50 -080041 write8(pmcbase + GEN_PMCON_A, reg8);
Subrata Banik33cd28e2017-12-19 12:33:59 +053042}
43
Krzysztof Sywula42a66fb2019-03-13 16:48:56 -070044static void pm1_enable_pwrbtn_smi(void *unused)
45{
46 /*
47 * Enable power button SMI only before jumping to payload. This ensures
48 * that:
49 * 1. Power button SMI is enabled only after coreboot is done.
50 * 2. On resume path, power button SMI is not enabled and thus avoids
51 * any shutdowns because of power button presses due to power button
52 * press in resume path.
53 */
54 pmc_update_pm1_enable(PWRBTN_EN);
55}
56
57BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, pm1_enable_pwrbtn_smi, NULL);
58
Lijian Zhaoac87a982017-08-28 17:46:55 -070059static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
60{
61 uint32_t reg;
62 uint8_t *pmcbase = pmc_mmio_regs();
63
64 printk(BIOS_DEBUG, "%sabling Deep S%c\n",
65 enable ? "En" : "Dis", sx + '0');
66 reg = read32(pmcbase + offset);
67 if (enable)
68 reg |= mask;
69 else
70 reg &= ~mask;
71 write32(pmcbase + offset, reg);
72}
73
74static void config_deep_s5(int on_ac, int on_dc)
75{
76 /* Treat S4 the same as S5. */
77 config_deep_sX(S4_PWRGATE_POL, S4AC_GATE_SUS, 4, on_ac);
78 config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS, 4, on_dc);
79 config_deep_sX(S5_PWRGATE_POL, S5AC_GATE_SUS, 5, on_ac);
80 config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS, 5, on_dc);
81}
82
83static void config_deep_s3(int on_ac, int on_dc)
84{
85 config_deep_sX(S3_PWRGATE_POL, S3AC_GATE_SUS, 3, on_ac);
86 config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS, 3, on_dc);
87}
88
89static void config_deep_sx(uint32_t deepsx_config)
90{
91 uint32_t reg;
92 uint8_t *pmcbase = pmc_mmio_regs();
93
94 reg = read32(pmcbase + DSX_CFG);
95 reg &= ~DSX_CFG_MASK;
96 reg |= deepsx_config;
97 write32(pmcbase + DSX_CFG, reg);
98}
99
Subrata Banik0baad612017-11-23 13:58:34 +0530100static void pmc_init(void *unused)
Lijian Zhaoac87a982017-08-28 17:46:55 -0700101{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300102 const config_t *config = config_of_soc();
Lijian Zhaoac87a982017-08-28 17:46:55 -0700103
104 rtc_init();
105
Nico Huber733c28f2019-08-05 19:33:09 +0200106 pmc_set_power_failure_state(true);
107 pmc_gpe_init();
Lijian Zhaoac87a982017-08-28 17:46:55 -0700108
Lijian Zhaoac87a982017-08-28 17:46:55 -0700109 config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc);
110 config_deep_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc);
111 config_deep_sx(config->deep_sx_config);
112}
113
Subrata Banik0baad612017-11-23 13:58:34 +0530114/*
115* Initialize PMC controller.
116*
117* PMC controller gets hidden from PCI bus during FSP-Silicon init call.
118* Hence PCI enumeration can't be used to initialize bus device and
119* allocate resources.
120*/
121BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, pmc_init, NULL);
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800122
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800123static void soc_acpi_mode_init(void *unused)
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800124{
125 /*
126 * PMC initialization happens earlier for this SoC because FSP-Silicon
127 * init hides PMC from PCI bus. However, pmc_set_acpi_mode, which
128 * disables ACPI mode doesn't need to happen that early and can be
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800129 * delayed till typical BS_DEV_INIT. This ensures that ACPI mode
130 * disabling happens the same way for all SoCs and hence the ordering of
131 * events is the same.
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800132 *
133 * This is important to ensure that the ordering does not break the
134 * assumptions of any other drivers (e.g. ChromeEC) which could be
135 * taking different actions based on disabling of ACPI (e.g. flushing of
136 * all EC hostevent bits).
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800137 *
138 * P.S.: This cannot be done as part of pmc_soc_init as PMC device is
139 * hidden and hence the PMC driver never gets enumerated and so init is
140 * not called for it.
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800141 */
142 pmc_set_acpi_mode();
143}
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800144
145BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, soc_acpi_mode_init, NULL);