1 /* This file is part of the coreboot project. */
2 /* SPDX-License-Identifier: GPL-2.0-or-later */
5 #include <console/console.h>
6 #include <device/mmio.h>
7 #include <device/device.h>
8 #include <device/pci.h>
9 #include <intelblocks/pmc.h>
10 #include <intelblocks/pmclib.h>
11 #include <soc/iomap.h>
15 /* Fill up PMC resource structure */
16 int pmc_soc_get_resources(struct pmc_resource_config
*cfg
)
18 cfg
->pwrmbase_offset
= PCI_BASE_ADDRESS_0
;
19 cfg
->pwrmbase_addr
= PMC_BAR0
;
20 cfg
->pwrmbase_size
= PMC_BAR0_SIZE
;
21 cfg
->abase_offset
= PCI_BASE_ADDRESS_4
;
22 cfg
->abase_addr
= ACPI_BASE_ADDRESS
;
23 cfg
->abase_size
= ACPI_BASE_SIZE
;
28 static int choose_slp_s3_assertion_width(int width_usecs
)
34 } slp_s3_settings
[] = {
37 .value
= SLP_S3_ASSERT_60_USEC
,
40 .max_width
= 1 * USECS_PER_MSEC
,
41 .value
= SLP_S3_ASSERT_1_MSEC
,
44 .max_width
= 50 * USECS_PER_MSEC
,
45 .value
= SLP_S3_ASSERT_50_MSEC
,
48 .max_width
= 2 * USECS_PER_SEC
,
49 .value
= SLP_S3_ASSERT_2_SEC
,
53 for (i
= 0; i
< ARRAY_SIZE(slp_s3_settings
); i
++) {
54 if (width_usecs
<= slp_s3_settings
[i
].max_width
)
58 /* Provide conservative default if nothing set in devicetree
59 * or requested assertion width too large. */
60 if (width_usecs
<= 0 || i
== ARRAY_SIZE(slp_s3_settings
))
61 i
= ARRAY_SIZE(slp_s3_settings
) - 1;
63 printk(BIOS_DEBUG
, "SLP S3 assertion width: %d usecs\n",
64 slp_s3_settings
[i
].max_width
);
66 return slp_s3_settings
[i
].value
;
69 static void set_slp_s3_assertion_width(int width_usecs
)
72 uintptr_t gen_pmcon3
= soc_read_pmc_base() + GEN_PMCON3
;
73 int setting
= choose_slp_s3_assertion_width(width_usecs
);
75 reg
= read32((void *)gen_pmcon3
);
76 reg
&= ~SLP_S3_ASSERT_MASK
;
77 reg
|= setting
<< SLP_S3_ASSERT_WIDTH_SHIFT
;
78 write32((void *)gen_pmcon3
, reg
);
81 void pmc_soc_set_afterg3_en(const bool on
)
83 void *const gen_pmcon1
= (void *)(soc_read_pmc_base() + GEN_PMCON1
);
86 reg32
= read32(gen_pmcon1
);
88 reg32
&= ~SLEEP_AFTER_POWER_FAIL
;
90 reg32
|= SLEEP_AFTER_POWER_FAIL
;
91 write32(gen_pmcon1
, reg32
);
94 void pmc_soc_init(struct device
*dev
)
96 const struct soc_intel_apollolake_config
*cfg
= config_of(dev
);
98 /* Set up GPE configuration */
103 set_slp_s3_assertion_width(cfg
->slp_s3_assertion_width_usecs
);
105 /* Log power state */
108 /* Now that things have been logged clear out the PMC state. */
111 pmc_set_power_failure_state(true);