blob: 9916bf09ed55549f67c2960eaa0d31a137897c13 [file] [log] [blame]
Sean Rhodes296994b2021-10-14 20:58:15 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <console/console.h>
Sean Rhodes296994b2021-10-14 20:58:15 +01004#include <device/device.h>
5#include <device/pnp.h>
6#include <ec/acpi/ec.h>
7#include <option.h>
8#include <pc80/keyboard.h>
Sean Rhodes0579c602023-02-16 15:00:14 +00009#include <halt.h>
Sean Rhodes296994b2021-10-14 20:58:15 +010010
11#include "ec.h"
12#include "ecdefs.h"
13
Sean Rhodes6082ee52022-03-09 08:07:30 +000014uint16_t ec_get_version(void)
Sean Rhodes296994b2021-10-14 20:58:15 +010015{
16 return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION);
17}
18
19static uint8_t get_ec_value_from_option(const char *name,
20 unsigned int fallback,
21 const uint8_t *lut,
22 size_t lut_size)
23{
24 unsigned int index = get_uint_option(name, fallback);
25 if (index >= lut_size)
26 index = fallback;
27 return lut[index];
28}
29
Sean Rhodes0579c602023-02-16 15:00:14 +000030static void ec_mirror_with_count(void)
31{
32 unsigned int cmos_mirror_flag_counter = get_uint_option("mirror_flag_counter", UINT_MAX);
33
Sean Rhodes981e61b2023-07-18 12:07:29 +010034 if (cmos_mirror_flag_counter == UINT_MAX)
35 return;
Sean Rhodes0579c602023-02-16 15:00:14 +000036
Sean Rhodes981e61b2023-07-18 12:07:29 +010037 printk(BIOS_DEBUG, "ITE: mirror_flag_counter = %u\n", cmos_mirror_flag_counter);
Sean Rhodes0579c602023-02-16 15:00:14 +000038
Sean Rhodes981e61b2023-07-18 12:07:29 +010039 /* Avoid boot loops by only trying a state change once */
40 if (cmos_mirror_flag_counter < MIRROR_ATTEMPTS) {
41 cmos_mirror_flag_counter++;
42 set_uint_option("mirror_flag_counter", cmos_mirror_flag_counter);
43 printk(BIOS_DEBUG, "ITE: Mirror attempt %u/%u.\n", cmos_mirror_flag_counter,
44 MIRROR_ATTEMPTS);
Sean Rhodes0579c602023-02-16 15:00:14 +000045
Sean Rhodes0579c602023-02-16 15:00:14 +000046 /* Write the EC mirror flag */
47 ec_write(ECRAM_MIRROR_FLAG, MIRROR_ENABLED);
48
49 /* Check what has been written */
50 if (ec_read(ECRAM_MIRROR_FLAG) == MIRROR_ENABLED)
51 poweroff();
Sean Rhodes981e61b2023-07-18 12:07:29 +010052 } else {
53 /*
54 * If the mirror flags fails after 1 attempt, it will
55 * likely need a cold boot, or recovering.
56 */
57 printk(BIOS_ERR, "ITE: Failed to mirror the EC in %u attempts!\n",
58 MIRROR_ATTEMPTS);
Sean Rhodes0579c602023-02-16 15:00:14 +000059 }
60}
61
62
63void ec_mirror_flag(void)
64{
65 /*
66 * For the mirror flag to work, the status of the EC pin must be known
67 * at all times, which means external power. This can be either a DC
68 * charger, or PD with CCG6. PD with an ANX7447 requires configuration
69 * from the EC, so the update will interrupt this.
70 *
71 * This means we can unconditionally apply the mirror flag to devices
72 * that have CCG6, present on devices with TBT, but have a manual
73 * flag for devices without it.
74 */
Sean Rhodes7d00b7c2023-07-07 14:27:28 +010075 uint16_t ec_version = ec_get_version();
76
Sean Rhodes0579c602023-02-16 15:00:14 +000077 if (CONFIG(EC_STARLABS_MIRROR_SUPPORT) &&
Sean Rhodese4fd5612023-07-18 11:49:19 +010078 (CONFIG(DRIVERS_INTEL_USB4_RETIMER) || get_uint_option("mirror_flag", 0)) &&
Sean Rhodes7d00b7c2023-07-07 14:27:28 +010079 (ec_version != CONFIG_EC_STARLABS_MIRROR_VERSION)) {
80 printk(BIOS_ERR, "ITE: EC version 0x%x doesn't match coreboot version 0x%x.\n",
81 ec_version, CONFIG_EC_STARLABS_MIRROR_VERSION);
Sean Rhodes0579c602023-02-16 15:00:14 +000082 ec_mirror_with_count();
83 }
84}
85
Sean Rhodes6082ee52022-03-09 08:07:30 +000086static uint16_t ec_get_chip_id(unsigned int port)
Sean Rhodes296994b2021-10-14 20:58:15 +010087{
88 return (pnp_read_index(port, ITE_CHIPID1) << 8) |
89 pnp_read_index(port, ITE_CHIPID2);
90}
91
92static void merlin_init(struct device *dev)
93{
94 if (!dev->enabled)
95 return;
96
97 /*
98 * The address/data IO port pair for the ite EC are configurable
99 * through the EC domain and are fixed by the EC's firmware blob. If
100 * the value(s) passed through the "dev" structure don't match the
101 * expected values then output severe warnings.
102 */
103 if (dev->path.pnp.port != ITE_FIXED_ADDR) {
104 printk(BIOS_ERR, "ITE: Incorrect ports defined in devicetree.cb.\n");
105 printk(BIOS_ERR, "ITE: Serious operational issues will arise.\n");
106 return;
107 }
108
Sean Rhodes6082ee52022-03-09 08:07:30 +0000109 const uint16_t chip_id = ec_get_chip_id(dev->path.pnp.port);
Sean Rhodes296994b2021-10-14 20:58:15 +0100110
111 if (chip_id != ITE_CHIPID_VAL) {
112 printk(BIOS_ERR, "ITE: Expected chip ID 0x%04x, but got 0x%04x instead.\n",
113 ITE_CHIPID_VAL, chip_id);
114 return;
115 }
116
Sean Rhodes0579c602023-02-16 15:00:14 +0000117 ec_mirror_flag();
118
Sean Rhodes296994b2021-10-14 20:58:15 +0100119 pc_keyboard_init(NO_AUX_DEVICE);
120
121 /*
122 * Restore settings from CMOS into EC RAM:
123 *
124 * kbl_timeout
125 * fn_ctrl_swap
126 * max_charge
127 * fan_mode
128 * fn_lock_state
129 * trackpad_state
130 * kbl_brightness
131 * kbl_state
132 */
133
134 /*
135 * Keyboard Backlight Timeout
136 *
137 * Setting: kbl_timeout
138 *
139 * Values: 30 Seconds, 1 Minute, 3 Minutes, 5 Minutes, Never
140 * Default: 30 Seconds
141 *
142 */
143 const uint8_t kbl_timeout[] = {
144 SEC_30,
145 MIN_1,
146 MIN_3,
147 MIN_5,
148 NEVER
149 };
150
151 ec_write(ECRAM_KBL_TIMEOUT,
152 get_ec_value_from_option("kbl_timeout",
153 0,
154 kbl_timeout,
155 ARRAY_SIZE(kbl_timeout)));
156
157 /*
158 * Fn Ctrl Reverse
159 *
160 * Setting: fn_ctrl_swap
161 *
162 * Values: Enabled, Disabled
163 * Default: Disabled
164 *
165 */
166 const uint8_t fn_ctrl_swap[] = {
167 FN_CTRL,
168 CTRL_FN
169 };
170
171 ec_write(ECRAM_FN_CTRL_REVERSE,
172 get_ec_value_from_option("fn_ctrl_swap",
Sean Rhodesc45cfad2023-04-25 22:51:57 +0100173 0,
Sean Rhodes296994b2021-10-14 20:58:15 +0100174 fn_ctrl_swap,
175 ARRAY_SIZE(fn_ctrl_swap)));
176
177 /*
178 * Maximum Charge Level
179 *
180 * Setting: max_charge
181 *
182 * Values: 60%, 80%, 100%
183 * Default: 100%
184 *
185 */
186 const uint8_t max_charge[] = {
187 CHARGE_100,
188 CHARGE_80,
189 CHARGE_60
190 };
191
Sean Rhodes4d1bf7b2022-02-17 13:55:34 +0000192 if (CONFIG(EC_STARLABS_MAX_CHARGE))
193 ec_write(ECRAM_MAX_CHARGE,
194 get_ec_value_from_option("max_charge",
195 0,
196 max_charge,
197 ARRAY_SIZE(max_charge)));
Sean Rhodes296994b2021-10-14 20:58:15 +0100198
199 /*
200 * Fan Mode
201 *
202 * Setting: fan_mode
203 *
204 * Values: Quiet, Normal, Aggressive
205 * Default: Normal
206 *
207 */
208 const uint8_t fan_mode[] = {
209 FAN_NORMAL,
210 FAN_AGGRESSIVE,
211 FAN_QUIET
212 };
213
214 if (CONFIG(EC_STARLABS_FAN))
215 ec_write(ECRAM_FAN_MODE,
216 get_ec_value_from_option("fan_mode",
217 0,
218 fan_mode,
219 ARRAY_SIZE(fan_mode)));
220
221 /*
222 * Function Lock
223 *
224 * Setting: fn_lock_state
225 *
226 * Values: Locked, Unlocked
227 * Default: Locked
228 *
229 */
230 const uint8_t fn_lock_state[] = {
231 UNLOCKED,
232 LOCKED
233 };
234
235 ec_write(ECRAM_FN_LOCK_STATE,
236 get_ec_value_from_option("fn_lock_state",
237 1,
238 fn_lock_state,
239 ARRAY_SIZE(fn_lock_state)));
240
241 /*
242 * Trackpad State
243 *
244 * Setting: trackpad_state
245 *
246 * Values: Enabled, Disabled
247 * Default: Enabled
248 *
249 */
250 const uint8_t trackpad_state[] = {
251 TRACKPAD_ENABLED,
252 TRACKPAD_DISABLED
253 };
254
255 ec_write(ECRAM_TRACKPAD_STATE,
256 get_ec_value_from_option("trackpad_state",
257 0,
258 trackpad_state,
259 ARRAY_SIZE(trackpad_state)));
260
261 /*
262 * Keyboard Backlight Brightness
263 *
264 * Setting: kbl_brightness
265 *
266 * Values: Off, Low, High / Off, On
267 * Default: Low
268 *
269 */
270 const uint8_t kbl_brightness[] = {
271 KBL_ON,
272 KBL_OFF,
273 KBL_LOW,
274 KBL_HIGH
275 };
276
277 if (CONFIG(EC_STARLABS_KBL_LEVELS))
278 ec_write(ECRAM_KBL_BRIGHTNESS,
279 get_ec_value_from_option("kbl_brightness",
280 2,
281 kbl_brightness,
282 ARRAY_SIZE(kbl_brightness)));
283 else
284 ec_write(ECRAM_KBL_BRIGHTNESS,
285 get_ec_value_from_option("kbl_brightness",
286 0,
287 kbl_brightness,
288 ARRAY_SIZE(kbl_brightness)));
289
290 /*
291 * Keyboard Backlight State
292 *
293 * Setting: kbl_state
294 *
295 * Values: Off, On
296 * Default: On
297 *
298 */
299 const uint8_t kbl_state[] = {
300 KBL_DISABLED,
301 KBL_ENABLED
302 };
303
304 ec_write(ECRAM_KBL_STATE,
305 get_ec_value_from_option("kbl_state",
306 1,
307 kbl_state,
308 ARRAY_SIZE(kbl_state)));
Sean Rhodes296994b2021-10-14 20:58:15 +0100309}
310
311static struct device_operations ops = {
312 .init = merlin_init,
313 .read_resources = noop_read_resources,
314 .set_resources = noop_set_resources,
315};
316
317static struct pnp_info pnp_dev_info[] = {
318 /* Serial Port 1 (UART1) */
319 { NULL, ITE_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
320 /* Serial Port 2 (UART2) */
321 { NULL, ITE_SP2, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
322 /* System Wake-Up Control (SWUC) */
323 { NULL, ITE_SWUC, PNP_IO0 | PNP_IRQ0, 0xfff0, },
324 /* KBC / Mouse Interface */
325 { NULL, ITE_SWUC, PNP_IRQ0, },
326 /* KBC / Keyboard Interface */
327 { NULL, ITE_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
328 /* Consumer IR (CIR) */
329 { NULL, ITE_IR, PNP_IO0 | PNP_IRQ0, 0xfff8, },
330 /* Shared Memory / Flash Interface (SMFI) */
331 { NULL, ITE_SMFI, PNP_IO0 | PNP_IRQ0, 0xfff0, },
332 /* RTC-like Timer (RCTC) */
333 { NULL, ITE_RTCT, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IO3 | PNP_IRQ0,
334 0xfffe, 0xfffe, 0xfffe, 0xfffe, },
335 /* Power Management I/F Channel 1 (PMC1) */
336 { NULL, ITE_PMC1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
337 /* Power Management I/F Channel 2 (PMC2) */
338 { NULL, ITE_PMC2, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IRQ0, 0x07fc,
339 0x07fc, 0xfff0, },
340 /* Serial Peripheral Interface (SSPI) */
341 { NULL, ITE_SSPI, PNP_IO0 | PNP_IRQ0, 0xfff8, },
342 /* Platform Environment Control Interface (PECI) */
343 { NULL, ITE_PECI, PNP_IRQ0, 0xfff8, },
344 /* Power Management I/F Channel 3 (PMC3) */
345 { NULL, ITE_PMC3, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
346 /* Power Management I/F Channel 4 (PMC4) */
347 { NULL, ITE_PMC4, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
348 /* Power Management I/F Channel 5 (PMC5) */
349 { NULL, ITE_PMC5, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
350};
351
352static void enable_dev(struct device *dev)
353{
354 pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
355}
356
357struct chip_operations ec_starlabs_merlin_ops = {
358 CHIP_NAME("ITE EC")
359 .enable_dev = enable_dev
360};