Angel Pons | c3f58f6 | 2020-04-05 15:46:41 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Aaron Durbin | 9a7d7bc | 2013-09-07 00:41:48 -0500 | [diff] [blame] | 2 | |
Aaron Durbin | 9a7d7bc | 2013-09-07 00:41:48 -0500 | [diff] [blame] | 3 | #include <arch/io.h> |
Kyösti Mälkki | a963acd | 2019-08-16 20:34:25 +0300 | [diff] [blame] | 4 | #include <arch/romstage.h> |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 5 | #include <device/mmio.h> |
Kyösti Mälkki | f1b58b7 | 2019-03-01 13:43:02 +0200 | [diff] [blame] | 6 | #include <device/pci_ops.h> |
Aaron Durbin | 9a7d7bc | 2013-09-07 00:41:48 -0500 | [diff] [blame] | 7 | #include <console/console.h> |
| 8 | #include <cbmem.h> |
Aaron Durbin | a8e9b63 | 2013-10-30 15:46:07 -0500 | [diff] [blame] | 9 | #include <elog.h> |
Aaron Durbin | 9a7d7bc | 2013-09-07 00:41:48 -0500 | [diff] [blame] | 10 | #include <romstage_handoff.h> |
Aaron Durbin | afe8aee | 2016-11-29 21:37:42 -0600 | [diff] [blame] | 11 | #include <string.h> |
Aaron Durbin | 794bddf | 2013-09-27 11:38:36 -0500 | [diff] [blame] | 12 | #include <timestamp.h> |
Julius Werner | 18ea2d3 | 2014-10-07 16:42:17 -0700 | [diff] [blame] | 13 | #include <soc/iomap.h> |
Kyösti Mälkki | 8e23bac | 2019-08-17 06:47:50 +0300 | [diff] [blame] | 14 | #include <soc/msr.h> |
Julius Werner | 18ea2d3 | 2014-10-07 16:42:17 -0700 | [diff] [blame] | 15 | #include <soc/pci_devs.h> |
Angel Pons | b5320b2 | 2020-07-07 18:27:30 +0200 | [diff] [blame] | 16 | #include <soc/pm.h> |
Julius Werner | 18ea2d3 | 2014-10-07 16:42:17 -0700 | [diff] [blame] | 17 | #include <soc/romstage.h> |
Aaron Durbin | 6f9947a | 2013-11-18 11:16:20 -0600 | [diff] [blame] | 18 | |
Arthur Heymans | e228678 | 2018-12-29 14:01:12 +0100 | [diff] [blame] | 19 | static struct chipset_power_state power_state; |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 20 | |
Aaron Durbin | 41607a4 | 2015-06-09 13:54:10 -0500 | [diff] [blame] | 21 | static void migrate_power_state(int is_recovery) |
Aaron Durbin | 6e32893 | 2013-11-06 12:04:50 -0600 | [diff] [blame] | 22 | { |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 23 | struct chipset_power_state *ps_cbmem; |
| 24 | struct chipset_power_state *ps_car; |
| 25 | |
Arthur Heymans | e228678 | 2018-12-29 14:01:12 +0100 | [diff] [blame] | 26 | ps_car = &power_state; |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 27 | 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älkki | fa3bc04 | 2022-03-31 07:40:10 +0300 | [diff] [blame] | 35 | CBMEM_CREATION_HOOK(migrate_power_state); |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 36 | |
| 37 | static struct chipset_power_state *fill_power_state(void) |
| 38 | { |
Arthur Heymans | e228678 | 2018-12-29 14:01:12 +0100 | [diff] [blame] | 39 | struct chipset_power_state *ps = &power_state; |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 40 | |
| 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 Herbert | bde6d30 | 2014-12-24 18:43:20 -0800 | [diff] [blame] | 47 | 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 Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 50 | |
| 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älkki | 540902c | 2021-01-22 08:02:50 +0200 | [diff] [blame] | 62 | static int chipset_prev_sleep_state(const struct chipset_power_state *ps) |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 63 | { |
Aaron Durbin | 6e32893 | 2013-11-06 12:04:50 -0600 | [diff] [blame] | 64 | /* Default to S0. */ |
Aaron Durbin | f5cfaa3 | 2016-07-13 23:20:07 -0500 | [diff] [blame] | 65 | int prev_sleep_state = ACPI_S0; |
Aaron Durbin | 6e32893 | 2013-11-06 12:04:50 -0600 | [diff] [blame] | 66 | |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 67 | if (ps->pm1_sts & WAK_STS) { |
Aaron Durbin | f5cfaa3 | 2016-07-13 23:20:07 -0500 | [diff] [blame] | 68 | switch (acpi_sleep_from_pm1(ps->pm1_cnt)) { |
| 69 | case ACPI_S3: |
Julius Werner | cd49cce | 2019-03-05 16:53:33 -0800 | [diff] [blame] | 70 | if (CONFIG(HAVE_ACPI_RESUME)) |
Aaron Durbin | f5cfaa3 | 2016-07-13 23:20:07 -0500 | [diff] [blame] | 71 | prev_sleep_state = ACPI_S3; |
Aaron Durbin | 6e32893 | 2013-11-06 12:04:50 -0600 | [diff] [blame] | 72 | break; |
Aaron Durbin | f5cfaa3 | 2016-07-13 23:20:07 -0500 | [diff] [blame] | 73 | case ACPI_S5: |
| 74 | prev_sleep_state = ACPI_S5; |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 75 | break; |
Aaron Durbin | 6e32893 | 2013-11-06 12:04:50 -0600 | [diff] [blame] | 76 | } |
| 77 | /* Clear SLP_TYP. */ |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 78 | outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT); |
Aaron Durbin | 6e32893 | 2013-11-06 12:04:50 -0600 | [diff] [blame] | 79 | } |
| 80 | |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 81 | if (ps->gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR)) { |
Aaron Durbin | f5cfaa3 | 2016-07-13 23:20:07 -0500 | [diff] [blame] | 82 | prev_sleep_state = ACPI_S5; |
Aaron Durbin | 6e32893 | 2013-11-06 12:04:50 -0600 | [diff] [blame] | 83 | } |
| 84 | |
Aaron Durbin | 6e32893 | 2013-11-06 12:04:50 -0600 | [diff] [blame] | 85 | return prev_sleep_state; |
| 86 | } |
| 87 | |
Kyösti Mälkki | 3e77279 | 2019-08-16 17:37:48 +0300 | [diff] [blame] | 88 | /* Entry from cpu/intel/car/romstage.c */ |
| 89 | void mainboard_romstage_entry(void) |
Kyösti Mälkki | 4444919 | 2019-08-16 17:20:40 +0300 | [diff] [blame] | 90 | { |
Kyösti Mälkki | 3e77279 | 2019-08-16 17:37:48 +0300 | [diff] [blame] | 91 | struct chipset_power_state *ps; |
| 92 | int prev_sleep_state; |
| 93 | struct mrc_params mp; |
Kyösti Mälkki | 4444919 | 2019-08-16 17:20:40 +0300 | [diff] [blame] | 94 | |
Kyösti Mälkki | 4444919 | 2019-08-16 17:20:40 +0300 | [diff] [blame] | 95 | set_max_freq(); |
| 96 | |
| 97 | punit_init(); |
| 98 | |
| 99 | gfx_init(); |
| 100 | |
Kyösti Mälkki | 3e77279 | 2019-08-16 17:37:48 +0300 | [diff] [blame] | 101 | memset(&mp, 0, sizeof(mp)); |
| 102 | mainboard_fill_mrc_params(&mp); |
Aaron Durbin | 5f8ad56 | 2013-10-08 16:54:18 -0500 | [diff] [blame] | 103 | |
Jakub Czapiga | ad6157e | 2022-02-15 11:50:31 +0100 | [diff] [blame] | 104 | timestamp_add_now(TS_INITRAM_START); |
Aaron Durbin | 794bddf | 2013-09-27 11:38:36 -0500 | [diff] [blame] | 105 | |
Aaron Durbin | 00bf3db | 2014-01-09 10:33:23 -0600 | [diff] [blame] | 106 | ps = fill_power_state(); |
| 107 | prev_sleep_state = chipset_prev_sleep_state(ps); |
Aaron Durbin | 6e32893 | 2013-11-06 12:04:50 -0600 | [diff] [blame] | 108 | |
| 109 | printk(BIOS_DEBUG, "prev_sleep_state = S%d\n", prev_sleep_state); |
| 110 | |
Kyösti Mälkki | 6ceec16 | 2021-02-17 20:43:04 +0200 | [diff] [blame] | 111 | int s3resume = prev_sleep_state == ACPI_S3; |
| 112 | |
| 113 | elog_boot_notify(s3resume); |
Aaron Durbin | 4177db5 | 2014-02-05 14:55:26 -0600 | [diff] [blame] | 114 | |
Aaron Durbin | 9a7d7bc | 2013-09-07 00:41:48 -0500 | [diff] [blame] | 115 | /* Initialize RAM */ |
Kyösti Mälkki | 3e77279 | 2019-08-16 17:37:48 +0300 | [diff] [blame] | 116 | raminit(&mp, prev_sleep_state); |
Aaron Durbin | 9a7d7bc | 2013-09-07 00:41:48 -0500 | [diff] [blame] | 117 | |
Jakub Czapiga | ad6157e | 2022-02-15 11:50:31 +0100 | [diff] [blame] | 118 | timestamp_add_now(TS_INITRAM_END); |
Aaron Durbin | 794bddf | 2013-09-27 11:38:36 -0500 | [diff] [blame] | 119 | |
Kyösti Mälkki | 6ceec16 | 2021-02-17 20:43:04 +0200 | [diff] [blame] | 120 | romstage_handoff_init(s3resume); |
Aaron Durbin | 9a7d7bc | 2013-09-07 00:41:48 -0500 | [diff] [blame] | 121 | } |