blob: 3dc9f19668ef1be3fd8c501d96cfdf3a310f1028 [file] [log] [blame]
Angel Ponsd9d1d202020-04-05 13:22:41 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Duncan Laurie558602f2018-10-31 10:38:16 -07002
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpi.h>
Kyösti Mälkkibe7692a2021-11-03 17:54:14 +02004#include <bootmode.h>
Duncan Laurie558602f2018-10-31 10:38:16 -07005#include <boot/coreboot_tables.h>
6#include <gpio.h>
Duncan Laurie558602f2018-10-31 10:38:16 -07007#include <soc/gpio.h>
8#include <variant/gpio.h>
9#include <vendorcode/google/chromeos/chromeos.h>
Keith Shortd1215262019-01-15 10:32:22 -070010#include <security/tpm/tss.h>
Duncan Laurie5e963992019-01-23 15:05:42 -080011#include <device/device.h>
12#include <intelblocks/pmclib.h>
Keith Shortd1215262019-01-15 10:32:22 -070013
Duncan Laurieb2e61002019-01-22 15:50:01 -080014enum rec_mode_state {
15 REC_MODE_UNINITIALIZED,
16 REC_MODE_NOT_REQUESTED,
17 REC_MODE_REQUESTED,
18};
Duncan Laurie558602f2018-10-31 10:38:16 -070019
20void fill_lb_gpios(struct lb_gpios *gpios)
21{
22 struct lb_gpio chromeos_gpios[] = {
Duncan Laurie558602f2018-10-31 10:38:16 -070023 {-1, ACTIVE_HIGH, get_lid_switch(), "lid"},
24 {-1, ACTIVE_HIGH, 0, "power"},
25 {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"},
26 {-1, ACTIVE_HIGH, 0, "EC in RW"},
27 };
28 lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios));
29}
30
31static int cros_get_gpio_value(int type)
32{
33 const struct cros_gpio *cros_gpios;
34 size_t i, num_gpios = 0;
35
36 cros_gpios = variant_cros_gpios(&num_gpios);
37
38 for (i = 0; i < num_gpios; i++) {
39 const struct cros_gpio *gpio = &cros_gpios[i];
40 if (gpio->type == type) {
41 int state = gpio_get(gpio->gpio_num);
42 if (gpio->polarity == CROS_GPIO_ACTIVE_LOW)
43 return !state;
44 else
45 return state;
46 }
47 }
48 return 0;
49}
50
51void mainboard_chromeos_acpi_generate(void)
52{
53 const struct cros_gpio *cros_gpios;
54 size_t num_gpios = 0;
55
56 cros_gpios = variant_cros_gpios(&num_gpios);
57
58 chromeos_acpi_gpio_generate(cros_gpios, num_gpios);
59}
60
61int get_write_protect_state(void)
62{
63 return cros_get_gpio_value(CROS_GPIO_WP);
64}
65
66int get_recovery_mode_switch(void)
67{
Jett Rink837f6552019-03-22 14:41:42 -060068 static enum rec_mode_state saved_rec_mode = REC_MODE_UNINITIALIZED;
69 enum rec_mode_state state = REC_MODE_NOT_REQUESTED;
70 uint8_t cr50_state = 0;
Keith Shortd1215262019-01-15 10:32:22 -070071
Jett Rink837f6552019-03-22 14:41:42 -060072 /* Check cached state, since TPM will only tell us the first time */
73 if (saved_rec_mode != REC_MODE_UNINITIALIZED)
74 return saved_rec_mode == REC_MODE_REQUESTED;
Duncan Laurieb2e61002019-01-22 15:50:01 -080075
Jett Rink837f6552019-03-22 14:41:42 -060076 /*
77 * Read one-time recovery request from cr50 in verstage only since
78 * the TPM driver won't be set up in time for other stages like romstage
79 * and the value from the TPM would be wrong anyway since the verstage
80 * read would have cleared the value on the TPM.
81 *
Joel Kitching2332c742019-10-23 15:01:37 +080082 * The TPM recovery request is passed between stages through vboot data
83 * or cbmem depending on stage.
Jett Rink837f6552019-03-22 14:41:42 -060084 */
Julius Werner21a40532020-04-21 16:03:53 -070085 if (ENV_SEPARATE_VERSTAGE &&
Jett Rink837f6552019-03-22 14:41:42 -060086 tlcl_cr50_get_recovery_button(&cr50_state) == TPM_SUCCESS &&
87 cr50_state)
88 state = REC_MODE_REQUESTED;
Duncan Laurieb2e61002019-01-22 15:50:01 -080089
90 /* Read state from the GPIO controlled by servo. */
Keith Shortd1215262019-01-15 10:32:22 -070091 if (cros_get_gpio_value(CROS_GPIO_REC))
Duncan Laurieb2e61002019-01-22 15:50:01 -080092 state = REC_MODE_REQUESTED;
Keith Shortd1215262019-01-15 10:32:22 -070093
Duncan Laurieb2e61002019-01-22 15:50:01 -080094 /* Store the state in case this is called again in verstage. */
Arthur Heymans7e8bad42018-12-29 14:20:23 +010095 saved_rec_mode = state;
Duncan Laurieb2e61002019-01-22 15:50:01 -080096
97 return state == REC_MODE_REQUESTED;
Duncan Laurie558602f2018-10-31 10:38:16 -070098}
99
100int get_lid_switch(void)
101{
102 return 1;
103}
Duncan Laurie5e963992019-01-23 15:05:42 -0800104
Keith Shorte0f34002019-02-05 16:15:10 -0700105void mainboard_prepare_cr50_reset(void)
Duncan Laurie5e963992019-01-23 15:05:42 -0800106{
Duncan Laurie5e963992019-01-23 15:05:42 -0800107 /* Ensure system powers up after CR50 reset */
Kyösti Mälkki17887d02019-07-23 19:08:01 +0300108 if (ENV_RAMSTAGE)
Nico Huber733c28f2019-08-05 19:33:09 +0200109 pmc_soc_set_afterg3_en(true);
Duncan Laurie5e963992019-01-23 15:05:42 -0800110}