blob: 970413904b56e8e6ffb42a8806a873bf09a448a0 [file] [log] [blame]
Duncan Laurie2cc126b2020-08-28 19:46:35 +00001/* SPDX-License-Identifier: GPL-2.0-or-later */
2
3#include <acpi/acpigen.h>
4#include <acpi/acpi_device.h>
John Zhao0b3f15c2021-04-27 10:47:25 -07005#include <acpi/acpi_pld.h>
Duncan Laurie2cc126b2020-08-28 19:46:35 +00006#include <console/console.h>
7#include <device/device.h>
8#include <device/path.h>
Maulik V Vaghela0f7e0862021-06-29 17:16:49 +05309#include <drivers/usb/acpi/chip.h>
Duncan Laurie2cc126b2020-08-28 19:46:35 +000010#include <gpio.h>
John Zhao0b3f15c2021-04-27 10:47:25 -070011#include <string.h>
Duncan Laurie2cc126b2020-08-28 19:46:35 +000012#include "chip.h"
Brandon Breitenstein297d27b2020-12-14 13:52:24 -080013#include "retimer.h"
Duncan Laurie2cc126b2020-08-28 19:46:35 +000014
15/* Unique ID for the retimer _DSM. */
John Zhao0b3f15c2021-04-27 10:47:25 -070016#define INTEL_USB4_RETIMER_DSM_UUID "E0053122-795B-4122-8A5E-57BE1D26ACB3"
17
18static const char *usb4_retimer_scope;
19static const char *usb4_retimer_path_arg(const char *arg)
20{
21 /* \\_SB.PCI0.TDMx.ARG */
22 static char name[DEVICE_PATH_MAX];
23 snprintf(name, sizeof(name), "%s%c%s", usb4_retimer_scope, '.', arg);
24 return name;
25}
26
27/* Each polling cycle takes up to 25 ms with a total of 12 of these iterations */
28#define USB4_RETIMER_ITERATION_NUM 12
29#define USB4_RETIMER_POLL_CYCLE_MS 25
John1dfed8f2022-04-21 17:58:16 -070030static void usb4_retimer_execute_ec_cmd(uint8_t port, uint8_t cmd, uint8_t expected_value,
31 struct acpi_gpio *power_gpio)
John Zhao0b3f15c2021-04-27 10:47:25 -070032{
33 const char *RFWU = ec_retimer_fw_update_path();
34 const uint8_t data = cmd << USB_RETIMER_FW_UPDATE_OP_SHIFT | port;
35
36 /* Invoke EC Retimer firmware update command execution */
37 ec_retimer_fw_update(data);
38 /* If RFWU has return value 0xfe, return error -1 */
39 acpigen_write_if_lequal_namestr_int(RFWU, USB_RETIMER_FW_UPDATE_ERROR);
John1dfed8f2022-04-21 17:58:16 -070040 acpigen_disable_tx_gpio(power_gpio);
John Zhao0b3f15c2021-04-27 10:47:25 -070041 acpigen_write_return_integer(-1);
42 acpigen_pop_len(); /* If */
43
44 acpigen_write_store_int_to_op(USB4_RETIMER_ITERATION_NUM, LOCAL2_OP);
45 acpigen_emit_byte(WHILE_OP);
46 acpigen_write_len_f();
47 acpigen_emit_byte(LGREATER_OP);
48 acpigen_emit_byte(LOCAL2_OP);
49 acpigen_emit_byte(ZERO_OP);
50 acpigen_write_if_lequal_namestr_int(RFWU, expected_value);
51 acpigen_emit_byte(BREAK_OP);
52 acpigen_pop_len(); /* If */
53
John1dfed8f2022-04-21 17:58:16 -070054 if (cmd == USB_RETIMER_FW_UPDATE_GET_MUX) {
55 acpigen_write_if_lequal_namestr_int(RFWU, USB_RETIMER_FW_UPDATE_INVALID_MUX);
56 acpigen_write_sleep(USB4_RETIMER_POLL_CYCLE_MS);
57 acpigen_emit_byte(DECREMENT_OP);
58 acpigen_emit_byte(LOCAL2_OP);
59 acpigen_emit_byte(CONTINUE_OP);
60 acpigen_pop_len(); /* If */
61
62 acpigen_emit_byte(AND_OP);
63 acpigen_emit_namestring(RFWU);
64 acpigen_write_integer(USB_RETIMER_FW_UPDATE_MUX_MASK);
65 acpigen_emit_byte(LOCAL3_OP);
66 acpigen_write_if();
67 acpigen_emit_byte(LNOT_OP);
68 acpigen_emit_byte(LEQUAL_OP);
69 acpigen_emit_byte(LOCAL3_OP);
70 acpigen_emit_byte(0);
71 acpigen_disable_tx_gpio(power_gpio);
72 acpigen_write_return_integer(-1);
73 acpigen_pop_len(); /* If */
74 } else if (cmd == USB_RETIMER_FW_UPDATE_SET_TBT) {
John Zhao0b3f15c2021-04-27 10:47:25 -070075 /*
76 * EC return either USB_PD_MUX_USB4_ENABLED or USB_PD_MUX_TBT_COMPAT_ENABLED
77 * to RFWU after the USB_RETIMER_FW_UPDATE_SET_TBT command execution. It is
78 * needed to add additional check for USB_PD_MUX_TBT_COMPAT_ENABLED.
79 */
80 acpigen_write_if_lequal_namestr_int(RFWU, USB_PD_MUX_TBT_COMPAT_ENABLED);
81 acpigen_emit_byte(BREAK_OP);
82 acpigen_pop_len(); /* If */
83 }
84
85 acpigen_write_sleep(USB4_RETIMER_POLL_CYCLE_MS);
86 acpigen_emit_byte(DECREMENT_OP);
87 acpigen_emit_byte(LOCAL2_OP);
88 acpigen_pop_len(); /* While */
89
90 /*
91 * Check whether there is timeout error
92 * Return: -1 if timeout error occurring
93 */
94 acpigen_write_if_lequal_op_int(LOCAL2_OP, 0);
John1dfed8f2022-04-21 17:58:16 -070095 acpigen_disable_tx_gpio(power_gpio);
John Zhao0b3f15c2021-04-27 10:47:25 -070096 acpigen_write_return_integer(-1);
97 acpigen_pop_len(); /* If */
98}
99
100static void enable_retimer_online_state(uint8_t port, struct acpi_gpio *power_gpio)
101{
102 uint8_t expected_value;
103
104 /*
105 * Enable_retimer_online_state under NDA
106 * 1. Force power on
107 * 2. Check if there is a device connected
108 * 3. Suspend PD
109 * 4. Set Mux to USB mode
110 * 5. Set Mux to Safe mode
111 * 6. Set Mux to TBT mode
112 */
113
114 /* Force power on for the retimer on the port */
115 acpigen_enable_tx_gpio(power_gpio);
116
117 /*
118 * Get MUX mode state
119 * Return -1 if there is a device connected on the port.
120 * Otherwise proceed Retimer firmware upgrade operation.
121 */
122 expected_value = USB_PD_MUX_NONE;
John1dfed8f2022-04-21 17:58:16 -0700123 usb4_retimer_execute_ec_cmd(port, USB_RETIMER_FW_UPDATE_GET_MUX, expected_value,
124 power_gpio);
John Zhao0b3f15c2021-04-27 10:47:25 -0700125
126 /*
127 * Suspend PD
128 * Command: USB_RETIMER_FW_UPDATE_SUSPEND_PD
129 * Expect return value: 0
130 */
131 expected_value = 0;
John1dfed8f2022-04-21 17:58:16 -0700132 usb4_retimer_execute_ec_cmd(port, USB_RETIMER_FW_UPDATE_SUSPEND_PD, expected_value,
133 power_gpio);
John Zhao0b3f15c2021-04-27 10:47:25 -0700134
135 /*
136 * Set MUX USB Mode
137 * Command: USB_RETIMER_FW_UPDATE_SUSPEND_PD
138 * Expect return value: USB_PD_MUX_USB_ENABLED
139 */
140 expected_value = USB_PD_MUX_USB_ENABLED;
John1dfed8f2022-04-21 17:58:16 -0700141 usb4_retimer_execute_ec_cmd(port, USB_RETIMER_FW_UPDATE_SET_USB, expected_value,
142 power_gpio);
John Zhao0b3f15c2021-04-27 10:47:25 -0700143
144 /*
145 * Set MUX Safe Mode
146 * Command: USB_RETIMER_FW_UPDATE_SET_SAFE
147 * Expect return value: USB_PD_MUX_SAFE_MODE
148 */
149 expected_value = USB_PD_MUX_SAFE_MODE;
John1dfed8f2022-04-21 17:58:16 -0700150 usb4_retimer_execute_ec_cmd(port, USB_RETIMER_FW_UPDATE_SET_SAFE, expected_value,
151 power_gpio);
John Zhao0b3f15c2021-04-27 10:47:25 -0700152
153 /*
154 * Set MUX TBT Mode
155 * Command: USB_RETIMER_FW_UPDATE_SET_TBT
156 * Expect return value: USB_PD_MUX_USB4_ENABLED or USB_PD_MUX_TBT_COMPAT_ENABLED
157 */
158 expected_value = USB_PD_MUX_USB4_ENABLED;
John1dfed8f2022-04-21 17:58:16 -0700159 usb4_retimer_execute_ec_cmd(port, USB_RETIMER_FW_UPDATE_SET_TBT, expected_value,
160 power_gpio);
John Zhao0b3f15c2021-04-27 10:47:25 -0700161}
162
163static void disable_retimer_online_state(uint8_t port, struct acpi_gpio *power_gpio)
164{
165 uint8_t expected_value;
166
167 /*
168 * Disable_retimer_online_state
169 * 1. Set Mux to disconnect mode
170 * 2. Resume PD
171 * 3. Force power off
172 */
173
174 /*
175 * Set MUX Disconnect Mode
176 * Command: USB_RETIMER_FW_UPDATE_DISCONNECT
177 * Expect return value: 0
178 */
179 expected_value = 0;
John1dfed8f2022-04-21 17:58:16 -0700180 usb4_retimer_execute_ec_cmd(port, USB_RETIMER_FW_UPDATE_DISCONNECT, expected_value,
181 power_gpio);
John Zhao0b3f15c2021-04-27 10:47:25 -0700182
183 /*
184 * Resume PD
185 * Command: USB_RETIMER_FW_UPDATE_RESUME_PD
186 * Expect return value: 1
187 */
188 expected_value = 1;
John1dfed8f2022-04-21 17:58:16 -0700189 usb4_retimer_execute_ec_cmd(port, USB_RETIMER_FW_UPDATE_RESUME_PD, expected_value,
190 power_gpio);
John Zhao0b3f15c2021-04-27 10:47:25 -0700191
192 /* Force power off */
193 acpigen_disable_tx_gpio(power_gpio);
194}
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000195
196/*
John Zhao0b3f15c2021-04-27 10:47:25 -0700197 * Arg0: UUID e0053122-795b-4122-8a5e-57be1d26acb3
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000198 * Arg1: Revision ID (set to 1)
199 * Arg2: Function Index
200 * 0: Query command implemented
John Zhao0b3f15c2021-04-27 10:47:25 -0700201 * 1: Get power state
202 * 2: Set power state
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000203 * Arg3: A package containing parameters for the function specified
John Zhao0b3f15c2021-04-27 10:47:25 -0700204 * by the UUID, revision ID, function index and port index.
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000205 */
John Zhao0b3f15c2021-04-27 10:47:25 -0700206static void usb4_retimer_cb_standard_query(uint8_t port, void *arg)
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000207{
208 /*
John Zhao0b3f15c2021-04-27 10:47:25 -0700209 * ToInteger (Arg1, Local1)
210 * If (Local1 == 1) {
211 * Return(Buffer() {0x7})
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000212 * }
213 * Return (Buffer() {0x01})
214 */
John Zhao0b3f15c2021-04-27 10:47:25 -0700215 acpigen_write_to_integer(ARG1_OP, LOCAL1_OP);
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000216
John Zhao0b3f15c2021-04-27 10:47:25 -0700217 /* Revision 1 supports 2 Functions beyond the standard query */
218 acpigen_write_if_lequal_op_int(LOCAL1_OP, 1);
219 acpigen_write_return_singleton_buffer(0x7);
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000220 acpigen_pop_len(); /* If */
221
222 /* Other revisions support no additional functions */
John Zhao0b3f15c2021-04-27 10:47:25 -0700223 acpigen_write_return_singleton_buffer(0x1);
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000224}
225
John Zhao0b3f15c2021-04-27 10:47:25 -0700226static void usb4_retimer_cb_get_power_state(uint8_t port, void *arg)
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000227{
John Zhao0b3f15c2021-04-27 10:47:25 -0700228 const char *PWR;
229 char pwr[DEVICE_PATH_MAX];
230
231 snprintf(pwr, sizeof(pwr), "HR.DFP%1d.PWR", port);
232 PWR = usb4_retimer_path_arg(pwr);
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000233
234 /*
John Zhao0b3f15c2021-04-27 10:47:25 -0700235 * If (PWR > 0) {
236 * Return (1)
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000237 * }
238 */
John Zhao0b3f15c2021-04-27 10:47:25 -0700239 acpigen_write_if();
240 acpigen_emit_byte(LGREATER_OP);
241 acpigen_emit_namestring(PWR);
242 acpigen_emit_byte(0);
243 acpigen_write_return_integer(1);
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000244
245 /*
246 * Else {
John Zhao0b3f15c2021-04-27 10:47:25 -0700247 * Return (0)
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000248 * }
249 */
250 acpigen_write_else();
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000251 acpigen_write_return_integer(0);
John Zhao0b3f15c2021-04-27 10:47:25 -0700252 acpigen_pop_len();
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000253}
254
John Zhao0b3f15c2021-04-27 10:47:25 -0700255static void usb4_retimer_cb_set_power_state(uint8_t port, void *arg)
Brandon Breitenstein297d27b2020-12-14 13:52:24 -0800256{
John Zhao0b3f15c2021-04-27 10:47:25 -0700257 struct acpi_gpio *power_gpio = arg;
258 const char *PWR;
259 char pwr[DEVICE_PATH_MAX];
260
261 snprintf(pwr, sizeof(pwr), "HR.DFP%1d.PWR", port);
262 PWR = usb4_retimer_path_arg(pwr);
Brandon Breitenstein297d27b2020-12-14 13:52:24 -0800263
264 /*
John Zhao0b3f15c2021-04-27 10:47:25 -0700265 * Get information to set retimer power state from Arg3[0]
266 * Local1 = DeRefOf (Arg3[0])
Brandon Breitenstein297d27b2020-12-14 13:52:24 -0800267 */
John Zhao0b3f15c2021-04-27 10:47:25 -0700268 acpigen_get_package_op_element(ARG3_OP, 0, LOCAL1_OP);
269
270 /*
271 * If ((Local1 == 0) && (PWR > 0)) {
272 * PWR--
273 * If (PWR == 0) {
274 * // Disable retimer online state
275 * }
276 * }
277 */
278 acpigen_write_if();
279 acpigen_emit_byte(LAND_OP);
280 acpigen_emit_byte(LEQUAL_OP);
281 acpigen_emit_byte(LOCAL1_OP);
282 acpigen_emit_byte(0);
283 acpigen_emit_byte(LGREATER_OP);
284 acpigen_emit_namestring(PWR);
285 acpigen_emit_byte(0);
286 /* PWR-- */
287 acpigen_emit_byte(DECREMENT_OP);
288 acpigen_emit_namestring(PWR);
289 acpigen_write_if_lequal_namestr_int(PWR, 0); /* If (PWR == 0) */
290 disable_retimer_online_state(port, power_gpio);
291 acpigen_pop_len(); /* If (PWR == 0) */
292
293 /*
294 * Else If ((Local1 == 1) && (PWR == 0)) {
295 * // Enable retimer online state
296 * PWR++
297 * }
298 */
299 acpigen_write_else();
300 acpigen_write_if();
301 acpigen_emit_byte(LAND_OP);
302 acpigen_emit_byte(LEQUAL_OP);
303 acpigen_emit_byte(LOCAL1_OP);
304 acpigen_emit_byte(1);
305 acpigen_emit_byte(LEQUAL_OP);
306 acpigen_emit_namestring(PWR);
307 acpigen_emit_byte(0);
308 enable_retimer_online_state(port, power_gpio);
309 /* PWR++ */
310 acpigen_emit_byte(INCREMENT_OP);
311 acpigen_emit_namestring(PWR);
312
313 /*
314 * Else {
315 * Return (0)
316 * }
317 */
318 acpigen_write_else();
319 acpigen_write_return_integer(0);
320 acpigen_pop_len(); /* Else */
321 acpigen_pop_len(); /* If */
322
323 /*
324 * If (PWR == 1) {
325 * Return (1)
326 * }
327 */
328 acpigen_write_if_lequal_namestr_int(PWR, 1);
329 acpigen_write_return_integer(1);
330
331 /*
332 * Else {
333 * Return (0)
334 * }
335 */
336 acpigen_write_else();
337 acpigen_write_return_integer(0);
338 acpigen_pop_len();
Brandon Breitenstein297d27b2020-12-14 13:52:24 -0800339}
340
John Zhao0b3f15c2021-04-27 10:47:25 -0700341static void (*usb4_retimer_callbacks[3])(uint8_t port, void *) = {
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000342 usb4_retimer_cb_standard_query, /* Function 0 */
343 usb4_retimer_cb_get_power_state, /* Function 1 */
344 usb4_retimer_cb_set_power_state, /* Function 2 */
345};
346
John Zhao0b3f15c2021-04-27 10:47:25 -0700347static void usb4_retimer_write_dsm(uint8_t port, const char *uuid,
348 void (**callbacks)(uint8_t port, void *), size_t count, void *arg)
349{
350 struct usb4_retimer_dsm_uuid id = DSM_UUID(uuid, callbacks, count, arg);
351 size_t i;
352
353 acpigen_write_to_integer(ARG2_OP, LOCAL0_OP);
354
355 for (i = 0; i < id.count; i++) {
356 /* If (LEqual (Local0, i)) */
357 acpigen_write_if_lequal_op_int(LOCAL0_OP, i);
358
359 /* Callback to write if handler. */
360 if (id.callbacks[i])
361 id.callbacks[i](port, id.arg);
362
363 acpigen_pop_len(); /* If */
364 }
365}
366
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000367static void usb4_retimer_fill_ssdt(const struct device *dev)
368{
John Zhao0b3f15c2021-04-27 10:47:25 -0700369 struct drivers_intel_usb4_retimer_config *config = dev->chip_info;
Maulik V Vaghela0f7e0862021-06-29 17:16:49 +0530370 const struct device *usb_device;
John Zhao0b3f15c2021-04-27 10:47:25 -0700371 static char dfp[DEVICE_PATH_MAX];
372 struct acpi_pld pld;
Maulik V Vaghela0f7e0862021-06-29 17:16:49 +0530373 uint8_t dfp_port, usb_port;
MAULIK V VAGHELAa70288d2021-11-25 14:41:19 +0530374 int ec_port = 0;
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000375
John Zhao0b3f15c2021-04-27 10:47:25 -0700376 usb4_retimer_scope = acpi_device_scope(dev);
377 if (!usb4_retimer_scope || !config)
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000378 return;
379
John Zhao0b3f15c2021-04-27 10:47:25 -0700380 /* Scope */
381 acpigen_write_scope(usb4_retimer_scope);
382
383 /* Host router */
384 acpigen_write_device("HR");
385 acpigen_write_ADR(0);
386 acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
387
Maulik V Vaghela0f7e0862021-06-29 17:16:49 +0530388 for (dfp_port = 0; dfp_port < DFP_NUM_MAX; dfp_port++) {
Maulik V Vaghela0f7e0862021-06-29 17:16:49 +0530389 if (!config->dfp[dfp_port].power_gpio.pin_count) {
Wisley Chendc27d802022-03-15 16:31:47 +0600390 printk(BIOS_WARNING, "%s: No DFP%1d power GPIO for %s\n",
Maulik V Vaghela0f7e0862021-06-29 17:16:49 +0530391 __func__, dfp_port, dev_path(dev));
John Zhao0b3f15c2021-04-27 10:47:25 -0700392 continue;
393 }
394
Maulik V Vaghela0f7e0862021-06-29 17:16:49 +0530395 usb_device = config->dfp[dfp_port].typec_port;
396 usb_port = usb_device->path.usb.port_id;
397
MAULIK V VAGHELAa70288d2021-11-25 14:41:19 +0530398 ec_port = retimer_get_index_for_typec(usb_port);
399 if (ec_port == -1) {
400 printk(BIOS_ERR, "%s: No relative EC port found for TC port %d\n",
401 __func__, usb_port);
Elyes Haouas5b0103f2022-02-16 16:43:42 +0100402 continue;
MAULIK V VAGHELAa70288d2021-11-25 14:41:19 +0530403 }
John Zhao0b3f15c2021-04-27 10:47:25 -0700404 /* DFPx */
MAULIK V VAGHELAa70288d2021-11-25 14:41:19 +0530405 snprintf(dfp, sizeof(dfp), "DFP%1d", ec_port);
John Zhao0b3f15c2021-04-27 10:47:25 -0700406 acpigen_write_device(dfp);
407 /* _ADR part is for the lane adapter */
Maulik V Vaghela0f7e0862021-06-29 17:16:49 +0530408 acpigen_write_ADR(dfp_port*2 + 1);
John Zhao0b3f15c2021-04-27 10:47:25 -0700409
410 /* Fill _PLD with the same USB 3.x object on the Type-C connector */
Maulik V Vaghela0f7e0862021-06-29 17:16:49 +0530411 if (CONFIG(DRIVERS_USB_ACPI)) {
412 if (usb_acpi_get_pld(usb_device, &pld))
413 acpigen_write_pld(&pld);
414 else
415 printk(BIOS_ERR, "Error retrieving PLD for USB Type-C %d\n",
416 usb_port);
417 }
John Zhao0b3f15c2021-04-27 10:47:25 -0700418
419 /* Power online reference counter(_PWR) */
420 acpigen_write_name("PWR");
421 acpigen_write_zero();
422
423 /* Method (_DSM, 4, Serialized) */
424 acpigen_write_method_serialized("_DSM", 0x4);
425 /* ToBuffer (Arg0, Local0) */
426 acpigen_write_to_buffer(ARG0_OP, LOCAL0_OP);
427 acpigen_write_if(); /* If (UUID != INTEL_USB4_RETIMER_DSM_UUID) */
428 acpigen_emit_byte(LNOT_OP);
429 acpigen_emit_byte(LEQUAL_OP);
430 acpigen_emit_byte(LOCAL0_OP);
431 acpigen_write_uuid(INTEL_USB4_RETIMER_DSM_UUID);
432 /* Return (Buffer (One) { 0x0 }) */
433 acpigen_write_return_singleton_buffer(0x0);
434 acpigen_pop_len();
MAULIK V VAGHELAa70288d2021-11-25 14:41:19 +0530435 usb4_retimer_write_dsm(ec_port, INTEL_USB4_RETIMER_DSM_UUID,
John Zhao0b3f15c2021-04-27 10:47:25 -0700436 usb4_retimer_callbacks, ARRAY_SIZE(usb4_retimer_callbacks),
Maulik V Vaghela0f7e0862021-06-29 17:16:49 +0530437 (void *)&config->dfp[dfp_port].power_gpio);
John Zhao0b3f15c2021-04-27 10:47:25 -0700438 /* Default case: Return (Buffer (One) { 0x0 }) */
439 acpigen_write_return_singleton_buffer(0x0);
440
441 acpigen_pop_len(); /* Method _DSM */
442 acpigen_pop_len(); /* DFP */
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000443 }
John Zhao0b3f15c2021-04-27 10:47:25 -0700444 acpigen_pop_len(); /* Host Router */
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000445 acpigen_pop_len(); /* Scope */
446
Eric Laief8a1392022-01-22 14:06:54 +0800447 printk(BIOS_INFO, "%s.HR: %s at %s\n", usb4_retimer_scope, dev->chip_ops->name,
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000448 dev_path(dev));
449}
450
451static struct device_operations usb4_retimer_dev_ops = {
452 .read_resources = noop_read_resources,
453 .set_resources = noop_set_resources,
454 .acpi_fill_ssdt = usb4_retimer_fill_ssdt,
455};
456
457static void usb4_retimer_enable(struct device *dev)
458{
459 dev->ops = &usb4_retimer_dev_ops;
460}
461
462struct chip_operations drivers_intel_usb4_retimer_ops = {
Nicholas Sudsgaardbfb11be2024-01-30 09:53:46 +0900463 .name = "Intel USB4 Retimer",
Duncan Laurie2cc126b2020-08-28 19:46:35 +0000464 .enable_dev = usb4_retimer_enable
465};
Brandon Breitenstein297d27b2020-12-14 13:52:24 -0800466
467__weak const char *ec_retimer_fw_update_path(void)
468{
469 return NULL;
470}
471
John Zhao0b3f15c2021-04-27 10:47:25 -0700472__weak void ec_retimer_fw_update(uint8_t data)
Brandon Breitenstein297d27b2020-12-14 13:52:24 -0800473{
474}
MAULIK V VAGHELAa70288d2021-11-25 14:41:19 +0530475
476/*
477 * This function will convert CPU physical port mapping to abstract
478 * EC port mapping.
479 * For example, board might have enabled TCSS port 1 and 3 as per physical
480 * port mapping. Since only 2 TCSS ports are enabled EC will index it as port 0
481 * and port 1. So there will be an issue when coreboot sends command to EC for
482 * port 3 (with coreboot index of 2). EC will produce an error due to wrong index.
483 *
484 * Note: Each SoC code using retimer driver needs to implement this function
485 * since SoC will have physical port details.
486 */
487__weak int retimer_get_index_for_typec(uint8_t typec_port)
488{
489 /* By default assume that retimer port index = Type C port */
490 return (int)typec_port;
491}