blob: c0bb9ae2961bca877594b1add045269dc482d901 [file] [log] [blame]
Lijian Zhaoac87a982017-08-28 17:46:55 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2009 coresystems GmbH
5 * Copyright (C) 2014 Google Inc.
Lijian Zhaoc3e75b42019-01-15 17:37:50 -08006 * Copyright (C) 2017-2019 Intel Corporation.
Lijian Zhaoac87a982017-08-28 17:46:55 -07007 *
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.
11 *
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.
16 */
17
Subrata Banik0baad612017-11-23 13:58:34 +053018#include <bootstate.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070019#include <console/console.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020020#include <device/mmio.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070021#include <device/device.h>
Subrata Banik0baad612017-11-23 13:58:34 +053022#include <intelblocks/pmc.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070023#include <intelblocks/pmclib.h>
24#include <intelblocks/rtc.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070025#include <soc/pci_devs.h>
26#include <soc/pm.h>
Lijian Zhaoac87a982017-08-28 17:46:55 -070027
Elyes HAOUASc3385072019-03-21 15:38:06 +010028#include "chip.h"
29
Subrata Banik33cd28e2017-12-19 12:33:59 +053030/*
31 * Set which power state system will be after reapplying
32 * the power (from G3 State)
33 */
Nico Huber733c28f2019-08-05 19:33:09 +020034void pmc_soc_set_afterg3_en(const bool on)
Subrata Banik33cd28e2017-12-19 12:33:59 +053035{
36 uint8_t reg8;
Nico Huber733c28f2019-08-05 19:33:09 +020037 uint8_t *const pmcbase = pmc_mmio_regs();
Subrata Banik33cd28e2017-12-19 12:33:59 +053038
Lijian Zhaoc3e75b42019-01-15 17:37:50 -080039 reg8 = read8(pmcbase + GEN_PMCON_A);
Nico Huber733c28f2019-08-05 19:33:09 +020040 if (on)
41 reg8 &= ~SLEEP_AFTER_POWER_FAIL;
42 else
43 reg8 |= SLEEP_AFTER_POWER_FAIL;
Lijian Zhaoc3e75b42019-01-15 17:37:50 -080044 write8(pmcbase + GEN_PMCON_A, reg8);
Subrata Banik33cd28e2017-12-19 12:33:59 +053045}
46
Krzysztof Sywula42a66fb2019-03-13 16:48:56 -070047static void pm1_enable_pwrbtn_smi(void *unused)
48{
49 /*
50 * Enable power button SMI only before jumping to payload. This ensures
51 * that:
52 * 1. Power button SMI is enabled only after coreboot is done.
53 * 2. On resume path, power button SMI is not enabled and thus avoids
54 * any shutdowns because of power button presses due to power button
55 * press in resume path.
56 */
57 pmc_update_pm1_enable(PWRBTN_EN);
58}
59
60BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, pm1_enable_pwrbtn_smi, NULL);
61
Lijian Zhaoac87a982017-08-28 17:46:55 -070062static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
63{
64 uint32_t reg;
65 uint8_t *pmcbase = pmc_mmio_regs();
66
67 printk(BIOS_DEBUG, "%sabling Deep S%c\n",
68 enable ? "En" : "Dis", sx + '0');
69 reg = read32(pmcbase + offset);
70 if (enable)
71 reg |= mask;
72 else
73 reg &= ~mask;
74 write32(pmcbase + offset, reg);
75}
76
77static void config_deep_s5(int on_ac, int on_dc)
78{
79 /* Treat S4 the same as S5. */
80 config_deep_sX(S4_PWRGATE_POL, S4AC_GATE_SUS, 4, on_ac);
81 config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS, 4, on_dc);
82 config_deep_sX(S5_PWRGATE_POL, S5AC_GATE_SUS, 5, on_ac);
83 config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS, 5, on_dc);
84}
85
86static void config_deep_s3(int on_ac, int on_dc)
87{
88 config_deep_sX(S3_PWRGATE_POL, S3AC_GATE_SUS, 3, on_ac);
89 config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS, 3, on_dc);
90}
91
92static void config_deep_sx(uint32_t deepsx_config)
93{
94 uint32_t reg;
95 uint8_t *pmcbase = pmc_mmio_regs();
96
97 reg = read32(pmcbase + DSX_CFG);
98 reg &= ~DSX_CFG_MASK;
99 reg |= deepsx_config;
100 write32(pmcbase + DSX_CFG, reg);
101}
102
Subrata Banik0baad612017-11-23 13:58:34 +0530103static void pmc_init(void *unused)
Lijian Zhaoac87a982017-08-28 17:46:55 -0700104{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300105 const config_t *config = config_of_soc();
Lijian Zhaoac87a982017-08-28 17:46:55 -0700106
107 rtc_init();
108
Nico Huber733c28f2019-08-05 19:33:09 +0200109 pmc_set_power_failure_state(true);
110 pmc_gpe_init();
Lijian Zhaoac87a982017-08-28 17:46:55 -0700111
Lijian Zhaoac87a982017-08-28 17:46:55 -0700112 config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc);
113 config_deep_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc);
114 config_deep_sx(config->deep_sx_config);
115}
116
Subrata Banik0baad612017-11-23 13:58:34 +0530117/*
118* Initialize PMC controller.
119*
120* PMC controller gets hidden from PCI bus during FSP-Silicon init call.
121* Hence PCI enumeration can't be used to initialize bus device and
122* allocate resources.
123*/
124BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, pmc_init, NULL);
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800125
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800126static void soc_acpi_mode_init(void *unused)
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800127{
128 /*
129 * PMC initialization happens earlier for this SoC because FSP-Silicon
130 * init hides PMC from PCI bus. However, pmc_set_acpi_mode, which
131 * disables ACPI mode doesn't need to happen that early and can be
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800132 * delayed till typical BS_DEV_INIT. This ensures that ACPI mode
133 * disabling happens the same way for all SoCs and hence the ordering of
134 * events is the same.
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800135 *
136 * This is important to ensure that the ordering does not break the
137 * assumptions of any other drivers (e.g. ChromeEC) which could be
138 * taking different actions based on disabling of ACPI (e.g. flushing of
139 * all EC hostevent bits).
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800140 *
141 * P.S.: This cannot be done as part of pmc_soc_init as PMC device is
142 * hidden and hence the PMC driver never gets enumerated and so init is
143 * not called for it.
Furquan Shaikhac8c60e2019-02-25 16:01:25 -0800144 */
145 pmc_set_acpi_mode();
146}
Furquan Shaikh67a489f2019-02-27 00:59:06 -0800147
148BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, soc_acpi_mode_init, NULL);