blob: d6c30a8b9e87ef1f7fe83d26a6cb4e0e4e8312f1 [file] [log] [blame]
Angel Ponsf5627e82020-04-05 15:46:52 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lijian Zhaoac87a982017-08-28 17:46:55 -07002
Subrata Banik0baad612017-11-23 13:58:34 +05303#include <bootstate.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -07004#include <console/console.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02005#include <device/mmio.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -07006#include <device/device.h>
Subrata Banik0baad612017-11-23 13:58:34 +05307#include <intelblocks/pmc.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -07008#include <intelblocks/pmclib.h>
9#include <intelblocks/rtc.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070010#include <soc/pci_devs.h>
11#include <soc/pm.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070012
Elyes HAOUASc3385072019-03-21 15:38:06 +010013#include "chip.h"
14
Krzysztof Sywula42a66fb2019-03-13 16:48:56 -070015static void pm1_enable_pwrbtn_smi(void *unused)
16{
17 /*
18 * Enable power button SMI only before jumping to payload. This ensures
19 * that:
20 * 1. Power button SMI is enabled only after coreboot is done.
21 * 2. On resume path, power button SMI is not enabled and thus avoids
22 * any shutdowns because of power button presses due to power button
23 * press in resume path.
24 */
25 pmc_update_pm1_enable(PWRBTN_EN);
26}
27
28BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, pm1_enable_pwrbtn_smi, NULL);
29
Lijian Zhaoac87a982017-08-28 17:46:55 -070030static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
31{
32 uint32_t reg;
33 uint8_t *pmcbase = pmc_mmio_regs();
34
35 printk(BIOS_DEBUG, "%sabling Deep S%c\n",
36 enable ? "En" : "Dis", sx + '0');
37 reg = read32(pmcbase + offset);
38 if (enable)
39 reg |= mask;
40 else
41 reg &= ~mask;
42 write32(pmcbase + offset, reg);
43}
44
45static void config_deep_s5(int on_ac, int on_dc)
46{
47 /* Treat S4 the same as S5. */
48 config_deep_sX(S4_PWRGATE_POL, S4AC_GATE_SUS, 4, on_ac);
49 config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS, 4, on_dc);
50 config_deep_sX(S5_PWRGATE_POL, S5AC_GATE_SUS, 5, on_ac);
51 config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS, 5, on_dc);
52}
53
54static void config_deep_s3(int on_ac, int on_dc)
55{
56 config_deep_sX(S3_PWRGATE_POL, S3AC_GATE_SUS, 3, on_ac);
57 config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS, 3, on_dc);
58}
59
60static void config_deep_sx(uint32_t deepsx_config)
61{
62 uint32_t reg;
63 uint8_t *pmcbase = pmc_mmio_regs();
64
65 reg = read32(pmcbase + DSX_CFG);
66 reg &= ~DSX_CFG_MASK;
67 reg |= deepsx_config;
68 write32(pmcbase + DSX_CFG, reg);
69}
70
Subrata Banik0baad612017-11-23 13:58:34 +053071static void pmc_init(void *unused)
Lijian Zhaoac87a982017-08-28 17:46:55 -070072{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +030073 const config_t *config = config_of_soc();
Lijian Zhaoac87a982017-08-28 17:46:55 -070074
75 rtc_init();
76
Nico Huber733c28f2019-08-05 19:33:09 +020077 pmc_set_power_failure_state(true);
78 pmc_gpe_init();
Lijian Zhaoac87a982017-08-28 17:46:55 -070079
Lijian Zhaoac87a982017-08-28 17:46:55 -070080 config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc);
81 config_deep_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc);
82 config_deep_sx(config->deep_sx_config);
83}
84
Subrata Banik0baad612017-11-23 13:58:34 +053085/*
86* Initialize PMC controller.
87*
88* PMC controller gets hidden from PCI bus during FSP-Silicon init call.
89* Hence PCI enumeration can't be used to initialize bus device and
90* allocate resources.
91*/
92BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, pmc_init, NULL);
Furquan Shaikhac8c60e2019-02-25 16:01:25 -080093
Furquan Shaikh67a489f2019-02-27 00:59:06 -080094static void soc_acpi_mode_init(void *unused)
Furquan Shaikhac8c60e2019-02-25 16:01:25 -080095{
96 /*
97 * PMC initialization happens earlier for this SoC because FSP-Silicon
98 * init hides PMC from PCI bus. However, pmc_set_acpi_mode, which
99 * disables ACPI mode doesn't need to happen that early and can be
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800100 * delayed till typical BS_DEV_INIT. This ensures that ACPI mode
101 * disabling happens the same way for all SoCs and hence the ordering of
102 * events is the same.
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800103 *
104 * This is important to ensure that the ordering does not break the
105 * assumptions of any other drivers (e.g. ChromeEC) which could be
106 * taking different actions based on disabling of ACPI (e.g. flushing of
107 * all EC hostevent bits).
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800108 *
109 * P.S.: This cannot be done as part of pmc_soc_init as PMC device is
110 * hidden and hence the PMC driver never gets enumerated and so init is
111 * not called for it.
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800112 */
113 pmc_set_acpi_mode();
114}
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800115
116BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, soc_acpi_mode_init, NULL);