/ src / mainboard / google / cyan / smihandler.c
smihandler.c
 1  /* SPDX-License-Identifier: GPL-2.0-only */
 2  
 3  #include <acpi/acpi.h>
 4  #include <device/mmio.h>
 5  #include <cpu/x86/smm.h>
 6  #include "ec.h"
 7  #include <ec/google/chromeec/smm.h>
 8  #include <soc/pm.h>
 9  #include <soc/gpio.h>
10  
11  #include <variant/onboard.h>
12  
13  /* The wake gpio is SUS_GPIO[0]. */
14  #define WAKE_GPIO_EN SUS_GPIO_EN0
15  #define GPIO_SUS7_WAKE_MASK     (1 << 12)
16  #define GPIO_SUS1_WAKE_MASK     (1 << 13)
17  
18  /*
19   * The entire 32-bit ALT_GPIO_SMI register is passed as a parameter. Note, that
20   * this includes the enable bits in the lower 16 bits.
21   */
22  void mainboard_smi_gpi(uint32_t alt_gpio_smi)
23  {
24  	if (alt_gpio_smi & (1 << EC_SMI_GPI))
25  		chromeec_smi_process_events();
26  }
27  
28  void mainboard_smi_sleep(uint8_t slp_typ)
29  {
30  	void		*addr;
31  	uint32_t	mask;
32  
33  	/* Disable USB charging if required */
34  	chromeec_set_usb_charge_mode(slp_typ);
35  
36  	switch (slp_typ) {
37  	case ACPI_S3:
38  		/* Enable wake pin in GPE block. */
39  		enable_gpe(WAKE_GPIO_EN);
40  		break;
41  	case ACPI_S5:
42  		/* Disabling wake from SUS_GPIO1 (TOUCH INT) and
43  		 * SUS_GPIO7 (TRACKPAD INT) in North bank as they are not
44  		 * valid S5 wake sources
45  		 */
46  		addr = (void *)(IO_BASE_ADDRESS + COMMUNITY_OFFSET_GPNORTH +
47  			GPIO_WAKE_MASK_REG0);
48  		mask = ~(GPIO_SUS1_WAKE_MASK | GPIO_SUS7_WAKE_MASK);
49  		write32(addr, read32(addr) & mask);
50  		break;
51  	}
52  
53  	chromeec_smi_sleep(slp_typ, MAINBOARD_EC_S3_WAKE_EVENTS, MAINBOARD_EC_S5_WAKE_EVENTS);
54  
55  	/* Set LPC lines to low power in S3/S5. */
56  	if ((slp_typ == ACPI_S3) || (slp_typ == ACPI_S5)) {
57  		lpc_set_low_power();
58  	}
59  }
60  
61  int mainboard_smi_apmc(uint8_t apmc)
62  {
63  	chromeec_smi_apmc(apmc, MAINBOARD_EC_SCI_EVENTS, MAINBOARD_EC_SMI_EVENTS);
64  	return 0;
65  }