blob: cab71928dab0c008c26a3033ae914979cfcbdf9f [file] [log] [blame]
Aaron Durbin996b15c2016-07-14 00:29:03 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2016 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <arch/acpi.h>
17#include <console/console.h>
18#include <cpu/x86/smm.h>
19#include <ec/google/chromeec/ec.h>
20#include <elog.h>
21#include <halt.h>
22#include "smm.h"
23
24static int chromeec_process_one_event(void)
25{
26 uint8_t event = google_chromeec_get_event();
27
28 /* Log this event */
29 if (IS_ENABLED(CONFIG_ELOG_GSMI) && event)
30 elog_add_event_byte(ELOG_TYPE_EC_EVENT, event);
31
32 switch (event) {
33 case EC_HOST_EVENT_LID_CLOSED:
34 printk(BIOS_DEBUG, "LID CLOSED, SHUTDOWN\n");
35
36 poweroff();
37 break;
38 }
39 return !!event;
40}
41
42void chromeec_smi_process_events(void)
43{
44 /* Process all pending events */
45 while (chromeec_process_one_event())
46 ;
47}
48
49static void clear_pending_events(void)
50{
Furquan Shaikhc1ca65d2017-10-13 11:06:37 -070051 struct ec_response_get_next_event mkbp_event;
52
Aaron Durbin996b15c2016-07-14 00:29:03 -050053 while (google_chromeec_get_event() != 0)
54 ;
Furquan Shaikhc1ca65d2017-10-13 11:06:37 -070055
Martin Roth45cc2ba2018-02-02 15:59:22 -070056 printk(BIOS_DEBUG,"Clearing pending EC events. Error code 1 is expected.\n");
Furquan Shaikhc1ca65d2017-10-13 11:06:37 -070057 while (google_chromeec_get_mkbp_event(&mkbp_event) == 0)
58 ;
Aaron Durbin996b15c2016-07-14 00:29:03 -050059}
60
Furquan Shaikh8788fd62017-11-20 20:28:18 -080061void chromeec_smi_sleep(int slp_type, uint64_t s3_mask, uint64_t s5_mask)
Aaron Durbin996b15c2016-07-14 00:29:03 -050062{
Jenny TC1dfc2c32017-12-14 14:24:39 +053063 if (!google_chromeec_is_uhepi_supported()) {
64 switch (slp_type) {
65 case ACPI_S3:
66 /* Enable wake events */
67 google_chromeec_set_wake_mask(s3_mask);
68 break;
69 case ACPI_S5:
70 /* Enable wake events */
71 google_chromeec_set_wake_mask(s5_mask);
72 break;
73 }
Aaron Durbin996b15c2016-07-14 00:29:03 -050074 }
75
76 /* Disable SCI and SMI events */
77 google_chromeec_set_smi_mask(0);
78 google_chromeec_set_sci_mask(0);
79
80 /* Clear pending events that may trigger immediate wake */
81 clear_pending_events();
82}
83
Furquan Shaikh8788fd62017-11-20 20:28:18 -080084void chromeec_smi_device_event_sleep(int slp_type, uint64_t s3_mask,
85 uint64_t s5_mask)
Duncan Laurie7378a172017-06-29 23:52:17 -070086{
87 switch (slp_type) {
88 case ACPI_S3:
89 /* Enable device wake events */
90 google_chromeec_set_device_enabled_events(s3_mask);
91 break;
92 case ACPI_S5:
93 /* Enable device wake events */
94 google_chromeec_set_device_enabled_events(s5_mask);
95 break;
96 }
97
98 /* Read and clear pending events that may trigger immediate wake */
99 google_chromeec_get_device_current_events();
100}
101
Furquan Shaikh8788fd62017-11-20 20:28:18 -0800102void chromeec_smi_apmc(int apmc, uint64_t sci_mask, uint64_t smi_mask)
Aaron Durbin996b15c2016-07-14 00:29:03 -0500103{
104 switch (apmc) {
105 case APM_CNT_ACPI_ENABLE:
106 google_chromeec_set_smi_mask(0);
107 clear_pending_events();
108 google_chromeec_set_sci_mask(sci_mask);
109 break;
110 case APM_CNT_ACPI_DISABLE:
111 google_chromeec_set_sci_mask(0);
112 clear_pending_events();
113 google_chromeec_set_smi_mask(smi_mask);
114 break;
115 }
116}