1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 #include <console/console.h>
5 #include <device/mmio.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <intelblocks/pmc.h>
9 #include <intelblocks/pmclib.h>
10 #include <soc/iomap.h>
14 /* Fill up PMC resource structure */
15 int pmc_soc_get_resources(struct pmc_resource_config
*cfg
)
17 cfg
->pwrmbase_offset
= PCI_BASE_ADDRESS_0
;
18 cfg
->pwrmbase_addr
= PCH_PWRM_BASE_ADDRESS
;
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
;
27 static int choose_slp_s3_assertion_width(int width_usecs
)
33 } slp_s3_settings
[] = {
36 .value
= SLP_S3_ASSERT_60_USEC
,
39 .max_width
= 1 * USECS_PER_MSEC
,
40 .value
= SLP_S3_ASSERT_1_MSEC
,
43 .max_width
= 50 * USECS_PER_MSEC
,
44 .value
= SLP_S3_ASSERT_50_MSEC
,
47 .max_width
= 2 * USECS_PER_SEC
,
48 .value
= SLP_S3_ASSERT_2_SEC
,
52 for (i
= 0; i
< ARRAY_SIZE(slp_s3_settings
); i
++) {
53 if (width_usecs
<= slp_s3_settings
[i
].max_width
)
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;
62 printk(BIOS_DEBUG
, "SLP S3 assertion width: %d usecs\n",
63 slp_s3_settings
[i
].max_width
);
65 return slp_s3_settings
[i
].value
;
68 static void set_slp_s3_assertion_width(int width_usecs
)
71 uintptr_t gen_pmcon3
= soc_read_pmc_base() + GEN_PMCON3
;
72 int setting
= choose_slp_s3_assertion_width(width_usecs
);
74 reg
= read32p(gen_pmcon3
);
75 reg
&= ~SLP_S3_ASSERT_MASK
;
76 reg
|= setting
<< SLP_S3_ASSERT_WIDTH_SHIFT
;
77 write32p(gen_pmcon3
, reg
);
80 void pmc_soc_init(struct device
*dev
)
82 const struct soc_intel_apollolake_config
*cfg
= config_of(dev
);
84 /* Set up GPE configuration */
89 set_slp_s3_assertion_width(cfg
->slp_s3_assertion_width_usecs
);
94 /* Now that things have been logged clear out the PMC state. */
97 pmc_set_power_failure_state(true);