blob: 54aa4bfd948c994f7c4513a283868a3a44b01544 [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
56 while (google_chromeec_get_mkbp_event(&mkbp_event) == 0)
57 ;
Aaron Durbin996b15c2016-07-14 00:29:03 -050058}
59
Furquan Shaikh8788fd62017-11-20 20:28:18 -080060void chromeec_smi_sleep(int slp_type, uint64_t s3_mask, uint64_t s5_mask)
Aaron Durbin996b15c2016-07-14 00:29:03 -050061{
Jenny TC1dfc2c32017-12-14 14:24:39 +053062 if (!google_chromeec_is_uhepi_supported()) {
63 switch (slp_type) {
64 case ACPI_S3:
65 /* Enable wake events */
66 google_chromeec_set_wake_mask(s3_mask);
67 break;
68 case ACPI_S5:
69 /* Enable wake events */
70 google_chromeec_set_wake_mask(s5_mask);
71 break;
72 }
Aaron Durbin996b15c2016-07-14 00:29:03 -050073 }
74
75 /* Disable SCI and SMI events */
76 google_chromeec_set_smi_mask(0);
77 google_chromeec_set_sci_mask(0);
78
79 /* Clear pending events that may trigger immediate wake */
80 clear_pending_events();
81}
82
Furquan Shaikh8788fd62017-11-20 20:28:18 -080083void chromeec_smi_device_event_sleep(int slp_type, uint64_t s3_mask,
84 uint64_t s5_mask)
Duncan Laurie7378a172017-06-29 23:52:17 -070085{
86 switch (slp_type) {
87 case ACPI_S3:
88 /* Enable device wake events */
89 google_chromeec_set_device_enabled_events(s3_mask);
90 break;
91 case ACPI_S5:
92 /* Enable device wake events */
93 google_chromeec_set_device_enabled_events(s5_mask);
94 break;
95 }
96
97 /* Read and clear pending events that may trigger immediate wake */
98 google_chromeec_get_device_current_events();
99}
100
Furquan Shaikh8788fd62017-11-20 20:28:18 -0800101void chromeec_smi_apmc(int apmc, uint64_t sci_mask, uint64_t smi_mask)
Aaron Durbin996b15c2016-07-14 00:29:03 -0500102{
103 switch (apmc) {
104 case APM_CNT_ACPI_ENABLE:
105 google_chromeec_set_smi_mask(0);
106 clear_pending_events();
107 google_chromeec_set_sci_mask(sci_mask);
108 break;
109 case APM_CNT_ACPI_DISABLE:
110 google_chromeec_set_sci_mask(0);
111 clear_pending_events();
112 google_chromeec_set_smi_mask(smi_mask);
113 break;
114 }
115}