blob: 6ec4d389e54741328400b24a306d6e1fc27e3e94 [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.
6 * Copyright (C) 2017 Intel Corporation.
7 *
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 <chip.h>
20#include <console/console.h>
21#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
Lijian Zhaoac87a982017-08-28 17:46:55 -070028static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
29{
30 uint32_t reg;
31 uint8_t *pmcbase = pmc_mmio_regs();
32
33 printk(BIOS_DEBUG, "%sabling Deep S%c\n",
34 enable ? "En" : "Dis", sx + '0');
35 reg = read32(pmcbase + offset);
36 if (enable)
37 reg |= mask;
38 else
39 reg &= ~mask;
40 write32(pmcbase + offset, reg);
41}
42
43static void config_deep_s5(int on_ac, int on_dc)
44{
45 /* Treat S4 the same as S5. */
46 config_deep_sX(S4_PWRGATE_POL, S4AC_GATE_SUS, 4, on_ac);
47 config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS, 4, on_dc);
48 config_deep_sX(S5_PWRGATE_POL, S5AC_GATE_SUS, 5, on_ac);
49 config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS, 5, on_dc);
50}
51
52static void config_deep_s3(int on_ac, int on_dc)
53{
54 config_deep_sX(S3_PWRGATE_POL, S3AC_GATE_SUS, 3, on_ac);
55 config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS, 3, on_dc);
56}
57
58static void config_deep_sx(uint32_t deepsx_config)
59{
60 uint32_t reg;
61 uint8_t *pmcbase = pmc_mmio_regs();
62
63 reg = read32(pmcbase + DSX_CFG);
64 reg &= ~DSX_CFG_MASK;
65 reg |= deepsx_config;
66 write32(pmcbase + DSX_CFG, reg);
67}
68
Subrata Banik0baad612017-11-23 13:58:34 +053069static void pmc_init(void *unused)
Lijian Zhaoac87a982017-08-28 17:46:55 -070070{
Subrata Banik0baad612017-11-23 13:58:34 +053071 device_t dev = PCH_DEV_PMC;
Lijian Zhaoac87a982017-08-28 17:46:55 -070072 config_t *config = dev->chip_info;
73
74 rtc_init();
75
76 /* Initialize power management */
77 pmc_gpe_init();
78
Subrata Banik0baad612017-11-23 13:58:34 +053079 pmc_set_acpi_mode();
Lijian Zhaoac87a982017-08-28 17:46:55 -070080
81 config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc);
82 config_deep_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc);
83 config_deep_sx(config->deep_sx_config);
84}
85
Subrata Banik0baad612017-11-23 13:58:34 +053086/*
87* Initialize PMC controller.
88*
89* PMC controller gets hidden from PCI bus during FSP-Silicon init call.
90* Hence PCI enumeration can't be used to initialize bus device and
91* allocate resources.
92*/
93BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, pmc_init, NULL);