2 * This file is part of the coreboot project.
4 * Copyright (C) 2016-2017 Intel Corp.
5 * (Written by Alexandru Gagniuc <alexandrux.gagniuc@intel.com> for Intel Corp.)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
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.
19 #include <console/console.h>
20 #include <device/device.h>
21 #include <device/pci.h>
22 #include <intelblocks/pmc.h>
23 #include <intelblocks/pmclib.h>
24 #include <soc/iomap.h>
28 /* Fill up PMC resource structure */
29 int pmc_soc_get_resources(struct pmc_resource_config
*cfg
)
31 cfg
->pwrmbase_offset
= PCI_BASE_ADDRESS_0
;
32 cfg
->pwrmbase_addr
= PMC_BAR0
;
33 cfg
->pwrmbase_size
= PMC_BAR0_SIZE
;
34 cfg
->abase_offset
= PCI_BASE_ADDRESS_4
;
35 cfg
->abase_addr
= ACPI_BASE_ADDRESS
;
36 cfg
->abase_size
= ACPI_BASE_SIZE
;
41 static int choose_slp_s3_assertion_width(int width_usecs
)
47 } slp_s3_settings
[] = {
50 .value
= SLP_S3_ASSERT_60_USEC
,
53 .max_width
= 1 * USECS_PER_MSEC
,
54 .value
= SLP_S3_ASSERT_1_MSEC
,
57 .max_width
= 50 * USECS_PER_MSEC
,
58 .value
= SLP_S3_ASSERT_50_MSEC
,
61 .max_width
= 2 * USECS_PER_SEC
,
62 .value
= SLP_S3_ASSERT_2_SEC
,
66 for (i
= 0; i
< ARRAY_SIZE(slp_s3_settings
); i
++) {
67 if (width_usecs
<= slp_s3_settings
[i
].max_width
)
71 /* Provide conservative default if nothing set in devicetree
72 * or requested assertion width too large. */
73 if (width_usecs
<= 0 || i
== ARRAY_SIZE(slp_s3_settings
))
74 i
= ARRAY_SIZE(slp_s3_settings
) - 1;
76 printk(BIOS_DEBUG
, "SLP S3 assertion width: %d usecs\n",
77 slp_s3_settings
[i
].max_width
);
79 return slp_s3_settings
[i
].value
;
82 static void set_slp_s3_assertion_width(int width_usecs
)
85 uintptr_t gen_pmcon3
= soc_read_pmc_base() + GEN_PMCON3
;
86 int setting
= choose_slp_s3_assertion_width(width_usecs
);
88 reg
= read32((void *)gen_pmcon3
);
89 reg
&= ~SLP_S3_ASSERT_MASK
;
90 reg
|= setting
<< SLP_S3_ASSERT_WIDTH_SHIFT
;
91 write32((void *)gen_pmcon3
, reg
);
94 void pmc_soc_init(struct device
*dev
)
96 const struct soc_intel_apollolake_config
*cfg
= dev
->chip_info
;
98 /* Set up GPE configuration */
100 pmc_fixup_power_state();
104 set_slp_s3_assertion_width(cfg
->slp_s3_assertion_width_usecs
);
106 /* Log power state */
109 /* Now that things have been logged clear out the PMC state. */