blob: fa59d467e22ee55bff8ba14a0281eac3e7674727 [file] [log] [blame]
Angel Pons16f6aa82020-04-05 15:47:21 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Subrata Banik91e89c52019-11-01 18:30:01 +05302
3/*
4 * This file is created based on Intel Tiger Lake Processor PCH Datasheet
5 * Document number: 575857
6 * Chapter number: 4
7 */
8
9#include <bootstate.h>
10#include <console/console.h>
11#include <device/mmio.h>
12#include <device/device.h>
13#include <intelblocks/pmc.h>
14#include <intelblocks/pmclib.h>
15#include <intelblocks/rtc.h>
16#include <soc/pci_devs.h>
17#include <soc/pm.h>
18#include <soc/soc_chip.h>
19
20/*
21 * Set which power state system will be after reapplying
22 * the power (from G3 State)
23 */
24void pmc_soc_set_afterg3_en(const bool on)
25{
26 uint8_t reg8;
27 uint8_t *const pmcbase = pmc_mmio_regs();
28
29 reg8 = read8(pmcbase + GEN_PMCON_A);
30 if (on)
31 reg8 &= ~SLEEP_AFTER_POWER_FAIL;
32 else
33 reg8 |= SLEEP_AFTER_POWER_FAIL;
34 write8(pmcbase + GEN_PMCON_A, reg8);
35}
36
37static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
38{
39 uint32_t reg;
40 uint8_t *pmcbase = pmc_mmio_regs();
41
42 printk(BIOS_DEBUG, "%sabling Deep S%c\n",
43 enable ? "En" : "Dis", sx + '0');
44 reg = read32(pmcbase + offset);
45 if (enable)
46 reg |= mask;
47 else
48 reg &= ~mask;
49 write32(pmcbase + offset, reg);
50}
51
52static void config_deep_s5(int on_ac, int on_dc)
53{
54 /* Treat S4 the same as S5. */
55 config_deep_sX(S4_PWRGATE_POL, S4AC_GATE_SUS, 4, on_ac);
56 config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS, 4, on_dc);
57 config_deep_sX(S5_PWRGATE_POL, S5AC_GATE_SUS, 5, on_ac);
58 config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS, 5, on_dc);
59}
60
61static void config_deep_s3(int on_ac, int on_dc)
62{
63 config_deep_sX(S3_PWRGATE_POL, S3AC_GATE_SUS, 3, on_ac);
64 config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS, 3, on_dc);
65}
66
67static void config_deep_sx(uint32_t deepsx_config)
68{
69 uint32_t reg;
70 uint8_t *pmcbase = pmc_mmio_regs();
71
72 reg = read32(pmcbase + DSX_CFG);
73 reg &= ~DSX_CFG_MASK;
74 reg |= deepsx_config;
75 write32(pmcbase + DSX_CFG, reg);
76}
77
Tim Wawrzynczak6d20d0c2020-05-13 17:00:33 -060078static void pmc_init(struct device *dev)
Subrata Banik91e89c52019-11-01 18:30:01 +053079{
80 const config_t *config = config_of_soc();
81
82 rtc_init();
83
84 pmc_set_power_failure_state(true);
85 pmc_gpe_init();
86
87 pmc_set_acpi_mode();
88
89 config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc);
90 config_deep_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc);
91 config_deep_sx(config->deep_sx_config);
92}
93
Tim Wawrzynczak6d20d0c2020-05-13 17:00:33 -060094static void soc_pmc_read_resources(struct device *dev)
95{
96 struct resource *res;
97
98 /* Add the fixed MMIO resource */
99 mmio_resource(dev, 0, PCH_PWRM_BASE_ADDRESS / KiB, PCH_PWRM_BASE_SIZE / KiB);
100
101 /* Add the fixed I/O resource */
102 res = new_resource(dev, 1);
103 res->base = (resource_t)ACPI_BASE_ADDRESS;
104 res->size = (resource_t)ACPI_BASE_SIZE;
105 res->limit = res->base + res->size - 1;
106 res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
107}
108
109struct device_operations pmc_ops = {
110 .read_resources = soc_pmc_read_resources,
111 .set_resources = noop_set_resources,
112 .enable = pmc_init,
113 .scan_bus = scan_static_bus,
114};