blob: 959fb537104945d7d48bbaacf9ba7852ad047286 [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Hannah Williams733b39a2016-02-11 13:46:28 -08002
Subrata Banik2153ea52017-11-22 15:38:19 +05303#include "chip.h"
4#include <console/console.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02005#include <device/mmio.h>
Hannah Williams733b39a2016-02-11 13:46:28 -08006#include <device/device.h>
7#include <device/pci.h>
Subrata Banik2153ea52017-11-22 15:38:19 +05308#include <intelblocks/pmc.h>
Shaunak Saha93cdc8b2017-04-18 15:42:09 -07009#include <intelblocks/pmclib.h>
Hannah Williams733b39a2016-02-11 13:46:28 -080010#include <soc/iomap.h>
Shaunak Saha5b6c5a52016-06-07 02:06:28 -070011#include <soc/pm.h>
Aaron Durbin41a3fa62016-08-25 15:42:04 -050012#include <timer.h>
Hannah Williams733b39a2016-02-11 13:46:28 -080013
Subrata Banik2153ea52017-11-22 15:38:19 +053014/* Fill up PMC resource structure */
15int pmc_soc_get_resources(struct pmc_resource_config *cfg)
Hannah Williams733b39a2016-02-11 13:46:28 -080016{
Subrata Banik2153ea52017-11-22 15:38:19 +053017 cfg->pwrmbase_offset = PCI_BASE_ADDRESS_0;
18 cfg->pwrmbase_addr = PMC_BAR0;
19 cfg->pwrmbase_size = PMC_BAR0_SIZE;
20 cfg->abase_offset = PCI_BASE_ADDRESS_4;
21 cfg->abase_addr = ACPI_BASE_ADDRESS;
22 cfg->abase_size = ACPI_BASE_SIZE;
Hannah Williams733b39a2016-02-11 13:46:28 -080023
Subrata Banik2153ea52017-11-22 15:38:19 +053024 return 0;
Shaunak Saha09115a92016-07-24 20:50:12 -070025}
26
Aaron Durbin41a3fa62016-08-25 15:42:04 -050027static int choose_slp_s3_assertion_width(int width_usecs)
28{
29 int i;
30 static const struct {
31 int max_width;
32 int value;
33 } slp_s3_settings[] = {
34 {
35 .max_width = 60,
36 .value = SLP_S3_ASSERT_60_USEC,
37 },
38 {
39 .max_width = 1 * USECS_PER_MSEC,
40 .value = SLP_S3_ASSERT_1_MSEC,
41 },
42 {
43 .max_width = 50 * USECS_PER_MSEC,
44 .value = SLP_S3_ASSERT_50_MSEC,
45 },
46 {
47 .max_width = 2 * USECS_PER_SEC,
48 .value = SLP_S3_ASSERT_2_SEC,
49 },
50 };
51
52 for (i = 0; i < ARRAY_SIZE(slp_s3_settings); i++) {
53 if (width_usecs <= slp_s3_settings[i].max_width)
54 break;
55 }
56
57 /* Provide conservative default if nothing set in devicetree
58 * or requested assertion width too large. */
59 if (width_usecs <= 0 || i == ARRAY_SIZE(slp_s3_settings))
60 i = ARRAY_SIZE(slp_s3_settings) - 1;
61
62 printk(BIOS_DEBUG, "SLP S3 assertion width: %d usecs\n",
63 slp_s3_settings[i].max_width);
64
65 return slp_s3_settings[i].value;
66}
67
68static void set_slp_s3_assertion_width(int width_usecs)
69{
70 uint32_t reg;
Shaunak Saha93cdc8b2017-04-18 15:42:09 -070071 uintptr_t gen_pmcon3 = soc_read_pmc_base() + GEN_PMCON3;
Aaron Durbin41a3fa62016-08-25 15:42:04 -050072 int setting = choose_slp_s3_assertion_width(width_usecs);
73
Angel Ponsf585c6e2021-06-25 10:09:35 +020074 reg = read32p(gen_pmcon3);
Aaron Durbin41a3fa62016-08-25 15:42:04 -050075 reg &= ~SLP_S3_ASSERT_MASK;
76 reg |= setting << SLP_S3_ASSERT_WIDTH_SHIFT;
Angel Ponsf585c6e2021-06-25 10:09:35 +020077 write32p(gen_pmcon3, reg);
Aaron Durbin41a3fa62016-08-25 15:42:04 -050078}
79
Subrata Banik2153ea52017-11-22 15:38:19 +053080void pmc_soc_init(struct device *dev)
Shaunak Saha5b6c5a52016-06-07 02:06:28 -070081{
Kyösti Mälkki8950cfb2019-07-13 22:16:25 +030082 const struct soc_intel_apollolake_config *cfg = config_of(dev);
Aaron Durbin41a3fa62016-08-25 15:42:04 -050083
Shaunak Saha5b6c5a52016-06-07 02:06:28 -070084 /* Set up GPE configuration */
85 pmc_gpe_init();
Subrata Banik2153ea52017-11-22 15:38:19 +053086 pmc_set_acpi_mode();
Brandon Breitenstein3b0e7612016-07-18 15:14:12 -070087
Aaron Durbin41a3fa62016-08-25 15:42:04 -050088 if (cfg != NULL)
89 set_slp_s3_assertion_width(cfg->slp_s3_assertion_width_usecs);
90
Brandon Breitenstein3b0e7612016-07-18 15:14:12 -070091 /* Log power state */
92 pch_log_state();
Aaron Durbindb52f232016-10-14 10:44:23 -050093
94 /* Now that things have been logged clear out the PMC state. */
Furquan Shaikhc4e652f2017-10-11 14:44:29 -070095 pmc_clear_prsts();
Nico Huber2fe596e2019-01-31 14:31:35 +010096
97 pmc_set_power_failure_state(true);
Shaunak Saha5b6c5a52016-06-07 02:06:28 -070098}