blob: 42cc7d7ce56ba6ee131efa597adc0b7edc8c33a3 [file] [log] [blame]
Lee Leahy5cb9dda2015-05-01 10:34:54 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2009 coresystems GmbH
5 * Copyright (C) 2015 Intel Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.
19 */
20
21#include <arch/io.h>
22#include <console/console.h>
23#include <cpu/x86/smm.h>
24#include "ec.h"
25
26#include <ec/google/chromeec/ec.h>
27#include <elog.h>
28
29#include <soc/nvs.h>
30#include <soc/pm.h>
31#include <soc/gpio.h>
32
33#include "onboard.h"
34
35/* The wake gpio is SUS_GPIO[0]. */
36#define WAKE_GPIO_EN SUS_GPIO_EN0
37
38int mainboard_io_trap_handler(int smif)
39{
40 switch (smif) {
41 case 0x99:
42 printk(BIOS_DEBUG, "Sample\n");
43 smm_get_gnvs()->smif = 0;
44 break;
45 default:
46 return 0;
47 }
48
49 /*
50 * On success, the IO Trap Handler returns 0
51 * On failure, the IO Trap Handler returns a value != 0
52 *
53 * For now, we force the return value to 0 and log all traps to
54 * see what's going on.
55 */
56 //gnvs->smif = 0;
57 return 1;
58}
59
60#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
61static uint8_t mainboard_smi_ec(void)
62{
63 uint8_t cmd = google_chromeec_get_event();
64 uint16_t pmbase = get_pmbase();
65 uint32_t pm1_cnt;
66
67#if IS_ENABLED(CONFIG_ELOG_GSMI)
68 /* Log this event */
69 if (cmd)
70 elog_add_event_byte(ELOG_TYPE_EC_EVENT, cmd);
71#endif
72
73 switch (cmd) {
74 case EC_HOST_EVENT_LID_CLOSED:
75 printk(BIOS_DEBUG, "LID CLOSED, SHUTDOWN\n");
76
77 /* Go to S5 */
78 pm1_cnt = inl(pmbase + PM1_CNT);
79 pm1_cnt |= SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT);
80 outl(pm1_cnt, pmbase + PM1_CNT);
81 break;
82 }
83
84 return cmd;
85}
86#endif
87
88/*
89 * The entire 32-bit ALT_GPIO_SMI register is passed as a parameter. Note, that
90 * this includes the enable bits in the lower 16 bits.
91 */
92void mainboard_smi_gpi(uint32_t alt_gpio_smi)
93{
94#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
95 if (alt_gpio_smi & (1 << EC_SMI_GPI)) {
96 /* Process all pending events */
97 while (mainboard_smi_ec() != 0)
98 ;
99 }
100#endif
101}
102
103void mainboard_smi_sleep(uint8_t slp_typ)
104{
105 /* Disable USB charging if required */
106 switch (slp_typ) {
107 case 3:
108#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
109 if (smm_get_gnvs()->s3u0 == 0)
110 google_chromeec_set_usb_charge_mode(
111 0, USB_CHARGE_MODE_DISABLED);
112 if (smm_get_gnvs()->s3u1 == 0)
113 google_chromeec_set_usb_charge_mode(
114 1, USB_CHARGE_MODE_DISABLED);
115
116 /* Enable wake events */
117 google_chromeec_set_wake_mask(MAINBOARD_EC_S3_WAKE_EVENTS);
118#endif
119 /* Enable wake pin in GPE block. */
120 enable_gpe(WAKE_GPIO_EN);
121 break;
122 case 5:
123#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
124 if (smm_get_gnvs()->s5u0 == 0)
125 google_chromeec_set_usb_charge_mode(
126 0, USB_CHARGE_MODE_DISABLED);
127 if (smm_get_gnvs()->s5u1 == 0)
128 google_chromeec_set_usb_charge_mode(
129 1, USB_CHARGE_MODE_DISABLED);
130
131 /* Enable wake events */
132 google_chromeec_set_wake_mask(MAINBOARD_EC_S5_WAKE_EVENTS);
133#endif
134 break;
135 }
136
137#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
138 /* Disable SCI and SMI events */
139 google_chromeec_set_smi_mask(0);
140 google_chromeec_set_sci_mask(0);
141
142 /* Clear pending events that may trigger immediate wake */
143 while (google_chromeec_get_event() != 0)
144 ;
145
146 if (smm_get_gnvs()->bdid == BOARD_DVT) {
147 /* Set LPC lines to low power in S3/S5. */
148 if ((slp_typ == SLEEP_STATE_S3) || (slp_typ == SLEEP_STATE_S5))
149 lpc_set_low_power();
150 }
151#endif
152}
153
154int mainboard_smi_apmc(uint8_t apmc)
155{
156 switch (apmc) {
157 case APM_CNT_ACPI_ENABLE:
158#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
159 google_chromeec_set_smi_mask(0);
160 /* Clear all pending events */
161 while (google_chromeec_get_event() != 0)
162 ;
163 google_chromeec_set_sci_mask(MAINBOARD_EC_SCI_EVENTS);
164#endif
165 break;
166 case APM_CNT_ACPI_DISABLE:
167#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
168 google_chromeec_set_sci_mask(0);
169 /* Clear all pending events */
170 while (google_chromeec_get_event() != 0)
171 ;
172 google_chromeec_set_smi_mask(MAINBOARD_EC_SMI_EVENTS);
173#endif
174 break;
175 }
176 return 0;
177}