blob: 658da2c44b00fe7cbeda96b5818d7b71576f151b [file] [log] [blame]
Angel Ponsc3f58f62020-04-05 15:46:41 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -05002
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -05003#include <arch/io.h>
Kyösti Mälkkia963acd2019-08-16 20:34:25 +03004#include <arch/romstage.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02005#include <device/mmio.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02006#include <device/pci_ops.h>
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -05007#include <console/console.h>
8#include <cbmem.h>
Aaron Durbina8e9b632013-10-30 15:46:07 -05009#include <elog.h>
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -050010#include <romstage_handoff.h>
Aaron Durbinafe8aee2016-11-29 21:37:42 -060011#include <string.h>
Aaron Durbin794bddf2013-09-27 11:38:36 -050012#include <timestamp.h>
Julius Werner18ea2d32014-10-07 16:42:17 -070013#include <soc/iomap.h>
Kyösti Mälkki8e23bac2019-08-17 06:47:50 +030014#include <soc/msr.h>
Julius Werner18ea2d32014-10-07 16:42:17 -070015#include <soc/pci_devs.h>
Angel Ponsb5320b22020-07-07 18:27:30 +020016#include <soc/pm.h>
Julius Werner18ea2d32014-10-07 16:42:17 -070017#include <soc/romstage.h>
Aaron Durbin6f9947a2013-11-18 11:16:20 -060018
Arthur Heymanse2286782018-12-29 14:01:12 +010019static struct chipset_power_state power_state;
Aaron Durbin00bf3db2014-01-09 10:33:23 -060020
Aaron Durbin41607a42015-06-09 13:54:10 -050021static void migrate_power_state(int is_recovery)
Aaron Durbin6e328932013-11-06 12:04:50 -060022{
Aaron Durbin00bf3db2014-01-09 10:33:23 -060023 struct chipset_power_state *ps_cbmem;
24 struct chipset_power_state *ps_car;
25
Arthur Heymanse2286782018-12-29 14:01:12 +010026 ps_car = &power_state;
Aaron Durbin00bf3db2014-01-09 10:33:23 -060027 ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem));
28
29 if (ps_cbmem == NULL) {
30 printk(BIOS_DEBUG, "Not adding power state to cbmem!\n");
31 return;
32 }
33 memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem));
34}
Kyösti Mälkkifa3bc042022-03-31 07:40:10 +030035CBMEM_CREATION_HOOK(migrate_power_state);
Aaron Durbin00bf3db2014-01-09 10:33:23 -060036
37static struct chipset_power_state *fill_power_state(void)
38{
Arthur Heymanse2286782018-12-29 14:01:12 +010039 struct chipset_power_state *ps = &power_state;
Aaron Durbin00bf3db2014-01-09 10:33:23 -060040
41 ps->pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
42 ps->pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN);
43 ps->pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
44 ps->gpe0_sts = inl(ACPI_BASE_ADDRESS + GPE0_STS);
45 ps->gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN);
46 ps->tco_sts = inl(ACPI_BASE_ADDRESS + TCO_STS);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080047 ps->prsts = read32((u32 *)(PMC_BASE_ADDRESS + PRSTS));
48 ps->gen_pmcon1 = read32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON1));
49 ps->gen_pmcon2 = read32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON2));
Aaron Durbin00bf3db2014-01-09 10:33:23 -060050
51 printk(BIOS_DEBUG, "pm1_sts: %04x pm1_en: %04x pm1_cnt: %08x\n",
52 ps->pm1_sts, ps->pm1_en, ps->pm1_cnt);
53 printk(BIOS_DEBUG, "gpe0_sts: %08x gpe0_en: %08x tco_sts: %08x\n",
54 ps->gpe0_sts, ps->gpe0_en, ps->tco_sts);
55 printk(BIOS_DEBUG, "prsts: %08x gen_pmcon1: %08x gen_pmcon2: %08x\n",
56 ps->prsts, ps->gen_pmcon1, ps->gen_pmcon2);
57
58 return ps;
59}
60
61/* Return 0, 3, or 5 to indicate the previous sleep state. */
Kyösti Mälkki540902c2021-01-22 08:02:50 +020062static int chipset_prev_sleep_state(const struct chipset_power_state *ps)
Aaron Durbin00bf3db2014-01-09 10:33:23 -060063{
Aaron Durbin6e328932013-11-06 12:04:50 -060064 /* Default to S0. */
Aaron Durbinf5cfaa32016-07-13 23:20:07 -050065 int prev_sleep_state = ACPI_S0;
Aaron Durbin6e328932013-11-06 12:04:50 -060066
Aaron Durbin00bf3db2014-01-09 10:33:23 -060067 if (ps->pm1_sts & WAK_STS) {
Aaron Durbinf5cfaa32016-07-13 23:20:07 -050068 switch (acpi_sleep_from_pm1(ps->pm1_cnt)) {
69 case ACPI_S3:
Julius Wernercd49cce2019-03-05 16:53:33 -080070 if (CONFIG(HAVE_ACPI_RESUME))
Aaron Durbinf5cfaa32016-07-13 23:20:07 -050071 prev_sleep_state = ACPI_S3;
Aaron Durbin6e328932013-11-06 12:04:50 -060072 break;
Aaron Durbinf5cfaa32016-07-13 23:20:07 -050073 case ACPI_S5:
74 prev_sleep_state = ACPI_S5;
Aaron Durbin00bf3db2014-01-09 10:33:23 -060075 break;
Aaron Durbin6e328932013-11-06 12:04:50 -060076 }
77 /* Clear SLP_TYP. */
Aaron Durbin00bf3db2014-01-09 10:33:23 -060078 outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT);
Aaron Durbin6e328932013-11-06 12:04:50 -060079 }
80
Aaron Durbin00bf3db2014-01-09 10:33:23 -060081 if (ps->gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR)) {
Aaron Durbinf5cfaa32016-07-13 23:20:07 -050082 prev_sleep_state = ACPI_S5;
Aaron Durbin6e328932013-11-06 12:04:50 -060083 }
84
Aaron Durbin6e328932013-11-06 12:04:50 -060085 return prev_sleep_state;
86}
87
Kyösti Mälkki3e772792019-08-16 17:37:48 +030088/* Entry from cpu/intel/car/romstage.c */
89void mainboard_romstage_entry(void)
Kyösti Mälkki44449192019-08-16 17:20:40 +030090{
Kyösti Mälkki3e772792019-08-16 17:37:48 +030091 struct chipset_power_state *ps;
92 int prev_sleep_state;
93 struct mrc_params mp;
Kyösti Mälkki44449192019-08-16 17:20:40 +030094
Kyösti Mälkki44449192019-08-16 17:20:40 +030095 set_max_freq();
96
97 punit_init();
98
99 gfx_init();
100
Kyösti Mälkki3e772792019-08-16 17:37:48 +0300101 memset(&mp, 0, sizeof(mp));
102 mainboard_fill_mrc_params(&mp);
Aaron Durbin5f8ad562013-10-08 16:54:18 -0500103
Jakub Czapigaad6157e2022-02-15 11:50:31 +0100104 timestamp_add_now(TS_INITRAM_START);
Aaron Durbin794bddf2013-09-27 11:38:36 -0500105
Aaron Durbin00bf3db2014-01-09 10:33:23 -0600106 ps = fill_power_state();
107 prev_sleep_state = chipset_prev_sleep_state(ps);
Aaron Durbin6e328932013-11-06 12:04:50 -0600108
109 printk(BIOS_DEBUG, "prev_sleep_state = S%d\n", prev_sleep_state);
110
Kyösti Mälkki6ceec162021-02-17 20:43:04 +0200111 int s3resume = prev_sleep_state == ACPI_S3;
112
113 elog_boot_notify(s3resume);
Aaron Durbin4177db52014-02-05 14:55:26 -0600114
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500115 /* Initialize RAM */
Kyösti Mälkki3e772792019-08-16 17:37:48 +0300116 raminit(&mp, prev_sleep_state);
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500117
Jakub Czapigaad6157e2022-02-15 11:50:31 +0100118 timestamp_add_now(TS_INITRAM_END);
Aaron Durbin794bddf2013-09-27 11:38:36 -0500119
Kyösti Mälkki6ceec162021-02-17 20:43:04 +0200120 romstage_handoff_init(s3resume);
Aaron Durbin9a7d7bc2013-09-07 00:41:48 -0500121}