blob: 59f4be5564c511c70de94f8df373fc7c4a3684a0 [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
Tim Wawrzynczakbd5b4aa2021-07-01 08:41:48 -060071static void soc_pmc_read_resources(struct device *dev)
72{
73 struct resource *res;
74
75 /* Add the fixed MMIO resource */
76 mmio_resource(dev, 0, PCH_PWRM_BASE_ADDRESS / KiB, PCH_PWRM_BASE_SIZE / KiB);
77
78 /* Add the fixed I/O resource */
79 res = new_resource(dev, 1);
80 res->base = (resource_t)ACPI_BASE_ADDRESS;
81 res->size = (resource_t)ACPI_BASE_SIZE;
82 res->limit = res->base + res->size - 1;
83 res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
84}
85
86static void pmc_init(struct device *dev)
Lijian Zhaoac87a982017-08-28 17:46:55 -070087{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +030088 const config_t *config = config_of_soc();
Lijian Zhaoac87a982017-08-28 17:46:55 -070089
90 rtc_init();
91
Nico Huber733c28f2019-08-05 19:33:09 +020092 pmc_set_power_failure_state(true);
93 pmc_gpe_init();
Lijian Zhaoac87a982017-08-28 17:46:55 -070094
Lijian Zhaoac87a982017-08-28 17:46:55 -070095 config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc);
96 config_deep_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc);
97 config_deep_sx(config->deep_sx_config);
98}
99
Tim Wawrzynczakbd5b4aa2021-07-01 08:41:48 -0600100static void soc_acpi_mode_init(struct device *dev)
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800101{
102 /*
103 * PMC initialization happens earlier for this SoC because FSP-Silicon
104 * init hides PMC from PCI bus. However, pmc_set_acpi_mode, which
105 * disables ACPI mode doesn't need to happen that early and can be
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800106 * delayed till typical BS_DEV_INIT. This ensures that ACPI mode
107 * disabling happens the same way for all SoCs and hence the ordering of
108 * events is the same.
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800109 *
110 * This is important to ensure that the ordering does not break the
111 * assumptions of any other drivers (e.g. ChromeEC) which could be
112 * taking different actions based on disabling of ACPI (e.g. flushing of
113 * all EC hostevent bits).
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800114 *
Tim Wawrzynczakbd5b4aa2021-07-01 08:41:48 -0600115 * Because the device is set as `hidden` in the devicetree, enumeration
116 * is skipped, but the device callbacks are still called as if it were
117 * found.
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800118 */
119 pmc_set_acpi_mode();
120}
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800121
Tim Wawrzynczakbd5b4aa2021-07-01 08:41:48 -0600122struct device_operations pmc_ops = {
123 .read_resources = soc_pmc_read_resources,
124 .set_resources = noop_set_resources,
125 .init = soc_acpi_mode_init,
126 .enable = pmc_init,
127 .scan_bus = scan_static_bus,
128};