1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Driver for Intel PMC USB mux control
4 *
5 * Copyright (C) 2020 Intel Corporation
6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
7 */
8
9 #include <linux/acpi.h>
10 #include <linux/module.h>
11 #include <linux/platform_data/x86/intel_scu_ipc.h>
12 #include <linux/platform_device.h>
13 #include <linux/property.h>
14 #include <linux/usb/pd.h>
15 #include <linux/usb/role.h>
16 #include <linux/usb/typec_mux.h>
17 #include <linux/usb/typec_dp.h>
18 #include <linux/usb/typec_tbt.h>
19 #include <linux/debugfs.h>
20 #include <linux/usb.h>
21
22 #define PMC_USBC_CMD 0xa7
23
24 /* Response status bits */
25 #define PMC_USB_RESP_STATUS_FAILURE BIT(0)
26 #define PMC_USB_RESP_STATUS_FATAL BIT(1)
27
28 /* "Usage" OOB Message field values */
29 enum {
30 PMC_USB_CONNECT,
31 PMC_USB_DISCONNECT,
32 PMC_USB_SAFE_MODE,
33 PMC_USB_ALT_MODE,
34 PMC_USB_DP_HPD,
35 };
36
37 #define PMC_USB_MSG_USB2_PORT_SHIFT 0
38 #define PMC_USB_MSG_USB3_PORT_SHIFT 4
39 #define PMC_USB_MSG_UFP_SHIFT 4
40 #define PMC_USB_MSG_ORI_HSL_SHIFT 5
41 #define PMC_USB_MSG_ORI_AUX_SHIFT 6
42
43 /* Alt Mode Request */
44 struct altmode_req {
45 u8 usage;
46 u8 mode_type;
47 u8 mode_id;
48 u8 reserved;
49 u32 mode_data;
50 } __packed;
51
52 #define PMC_USB_MODE_TYPE_SHIFT 4
53
54 enum {
55 PMC_USB_MODE_TYPE_USB,
56 PMC_USB_MODE_TYPE_DP,
57 PMC_USB_MODE_TYPE_TBT,
58 };
59
60 /* Common Mode Data bits */
61 #define PMC_USB_ALTMODE_RETIMER_CABLE BIT(2)
62
63 #define PMC_USB_ALTMODE_ORI_SHIFT 1
64 #define PMC_USB_ALTMODE_UFP_SHIFT 3
65
66 /* DP specific Mode Data bits */
67 #define PMC_USB_ALTMODE_DP_MODE_SHIFT 8
68
69 /* TBT specific Mode Data bits */
70 #define PMC_USB_ALTMODE_TBT_TYPE BIT(17)
71 #define PMC_USB_ALTMODE_CABLE_TYPE BIT(18)
72 #define PMC_USB_ALTMODE_ACTIVE_LINK BIT(20)
73 #define PMC_USB_ALTMODE_ACTIVE_CABLE BIT(22)
74 #define PMC_USB_ALTMODE_FORCE_LSR BIT(23)
75 #define PMC_USB_ALTMODE_CABLE_SPD(_s_) (((_s_) & GENMASK(2, 0)) << 25)
76 #define PMC_USB_ALTMODE_CABLE_USB31 1
77 #define PMC_USB_ALTMODE_CABLE_10GPS 2
78 #define PMC_USB_ALTMODE_CABLE_20GPS 3
79 #define PMC_USB_ALTMODE_TBT_GEN(_g_) (((_g_) & GENMASK(1, 0)) << 28)
80
81 /* Display HPD Request bits */
82 #define PMC_USB_DP_HPD_LVL BIT(4)
83 #define PMC_USB_DP_HPD_IRQ BIT(5)
84
85 /*
86 * Input Output Manager (IOM) PORT STATUS
87 */
88 #define IOM_PORT_STATUS_ACTIVITY_TYPE_MASK GENMASK(9, 6)
89 #define IOM_PORT_STATUS_ACTIVITY_TYPE_SHIFT 6
90 #define IOM_PORT_STATUS_ACTIVITY_TYPE_USB 0x03
91 /* activity type: Safe Mode */
92 #define IOM_PORT_STATUS_ACTIVITY_TYPE_SAFE_MODE 0x04
93 /* activity type: Display Port */
94 #define IOM_PORT_STATUS_ACTIVITY_TYPE_DP 0x05
95 /* activity type: Display Port Multi Function Device */
96 #define IOM_PORT_STATUS_ACTIVITY_TYPE_DP_MFD 0x06
97 /* activity type: Thunderbolt */
98 #define IOM_PORT_STATUS_ACTIVITY_TYPE_TBT 0x07
99 #define IOM_PORT_STATUS_ACTIVITY_TYPE_ALT_MODE_USB 0x0c
100 #define IOM_PORT_STATUS_ACTIVITY_TYPE_ALT_MODE_TBT_USB 0x0d
101 /* Upstream Facing Port Information */
102 #define IOM_PORT_STATUS_UFP BIT(10)
103 /* Display Port Hot Plug Detect status */
104 #define IOM_PORT_STATUS_DHPD_HPD_STATUS_MASK GENMASK(13, 12)
105 #define IOM_PORT_STATUS_DHPD_HPD_STATUS_SHIFT 12
106 #define IOM_PORT_STATUS_DHPD_HPD_STATUS_ASSERT 0x01
107 #define IOM_PORT_STATUS_DHPD_HPD_SOURCE_TBT BIT(14)
108 #define IOM_PORT_STATUS_CONNECTED BIT(31)
109
110 #define IOM_PORT_ACTIVITY_IS(_status_, _type_) \
111 ((((_status_) & IOM_PORT_STATUS_ACTIVITY_TYPE_MASK) >> \
112 IOM_PORT_STATUS_ACTIVITY_TYPE_SHIFT) == \
113 (IOM_PORT_STATUS_ACTIVITY_TYPE_##_type_))
114
115 #define IOM_PORT_HPD_ASSERTED(_status_) \
116 ((((_status_) & IOM_PORT_STATUS_DHPD_HPD_STATUS_MASK) >> \
117 IOM_PORT_STATUS_DHPD_HPD_STATUS_SHIFT) & \
118 IOM_PORT_STATUS_DHPD_HPD_STATUS_ASSERT)
119
120 /* IOM port status register */
121 #define IOM_PORT_STATUS_REGS(_offset_, _size_) ((_offset_) | (_size_))
122 #define IOM_PORT_STATUS_REGS_SZ_MASK BIT(0)
123 #define IOM_PORT_STATUS_REGS_SZ_4 0
124 #define IOM_PORT_STATUS_REGS_SZ_8 1
125 #define IOM_PORT_STATUS_REGS_OFFSET(_d_) \
126 ((_d_) & ~IOM_PORT_STATUS_REGS_SZ_MASK)
127 #define IOM_PORT_STATUS_REGS_SIZE(_d_) \
128 (4 << ((_d_) & IOM_PORT_STATUS_REGS_SZ_MASK))
129
130 struct pmc_usb;
131
132 struct pmc_usb_port {
133 int num;
134 u32 iom_status;
135 struct pmc_usb *pmc;
136 struct typec_mux_dev *typec_mux;
137 struct typec_switch_dev *typec_sw;
138 struct usb_role_switch *usb_sw;
139
140 enum typec_orientation orientation;
141 enum usb_role role;
142
143 u8 usb2_port;
144 u8 usb3_port;
145
146 enum typec_orientation sbu_orientation;
147 enum typec_orientation hsl_orientation;
148 };
149
150 struct pmc_usb {
151 u8 num_ports;
152 struct device *dev;
153 struct intel_scu_ipc_dev *ipc;
154 struct pmc_usb_port *port;
155 struct acpi_device *iom_adev;
156 void __iomem *iom_base;
157 u32 iom_port_status_offset;
158 u8 iom_port_status_size;
159
160 struct dentry *dentry;
161 };
162
163 static struct dentry *pmc_mux_debugfs_root;
164
update_port_status(struct pmc_usb_port * port)165 static void update_port_status(struct pmc_usb_port *port)
166 {
167 u8 port_num;
168
169 /* SoC expects the USB Type-C port numbers to start with 0 */
170 port_num = port->usb3_port - 1;
171
172 port->iom_status = readl(port->pmc->iom_base +
173 port->pmc->iom_port_status_offset +
174 port_num * port->pmc->iom_port_status_size);
175 }
176
sbu_orientation(struct pmc_usb_port * port)177 static int sbu_orientation(struct pmc_usb_port *port)
178 {
179 if (port->sbu_orientation)
180 return port->sbu_orientation - 1;
181
182 return port->orientation - 1;
183 }
184
hsl_orientation(struct pmc_usb_port * port)185 static int hsl_orientation(struct pmc_usb_port *port)
186 {
187 if (port->hsl_orientation)
188 return port->hsl_orientation - 1;
189
190 return port->orientation - 1;
191 }
192
is_pmc_mux_tbt(struct acpi_device * adev)193 static bool is_pmc_mux_tbt(struct acpi_device *adev)
194 {
195 return acpi_dev_hid_uid_match(adev, "INTC1072", NULL) ||
196 acpi_dev_hid_uid_match(adev, "INTC1079", NULL);
197 }
198
pmc_usb_send_command(struct intel_scu_ipc_dev * ipc,u8 * msg,u32 len)199 static int pmc_usb_send_command(struct intel_scu_ipc_dev *ipc, u8 *msg, u32 len)
200 {
201 u8 response[4];
202 u8 status_res;
203 int ret;
204
205 /*
206 * Error bit will always be 0 with the USBC command.
207 * Status can be checked from the response message if the
208 * function intel_scu_ipc_dev_command succeeds.
209 */
210 ret = intel_scu_ipc_dev_command(ipc, PMC_USBC_CMD, 0, msg,
211 len, response, sizeof(response));
212
213 if (ret)
214 return ret;
215
216 status_res = (msg[0] & 0xf) < PMC_USB_SAFE_MODE ?
217 response[2] : response[1];
218
219 if (status_res & PMC_USB_RESP_STATUS_FAILURE) {
220 if (status_res & PMC_USB_RESP_STATUS_FATAL)
221 return -EIO;
222
223 return -EBUSY;
224 }
225
226 return 0;
227 }
228
pmc_usb_command(struct pmc_usb_port * port,u8 * msg,u32 len)229 static int pmc_usb_command(struct pmc_usb_port *port, u8 *msg, u32 len)
230 {
231 int retry_count = 3;
232 int ret;
233
234 /*
235 * If PMC is busy then retry the command once again
236 */
237 while (retry_count--) {
238 ret = pmc_usb_send_command(port->pmc->ipc, msg, len);
239 if (ret != -EBUSY)
240 break;
241 }
242
243 return ret;
244 }
245
246 static int
pmc_usb_mux_dp_hpd(struct pmc_usb_port * port,struct typec_displayport_data * dp)247 pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_displayport_data *dp)
248 {
249 u8 msg[2] = { };
250 int ret;
251
252 msg[0] = PMC_USB_DP_HPD;
253 msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
254
255 /* Configure HPD first if HPD,IRQ comes together */
256 if (!IOM_PORT_HPD_ASSERTED(port->iom_status) &&
257 dp->status & DP_STATUS_IRQ_HPD &&
258 dp->status & DP_STATUS_HPD_STATE) {
259 msg[1] = PMC_USB_DP_HPD_LVL;
260 ret = pmc_usb_command(port, msg, sizeof(msg));
261 if (ret)
262 return ret;
263 }
264
265 if (dp->status & DP_STATUS_IRQ_HPD)
266 msg[1] = PMC_USB_DP_HPD_IRQ;
267
268 if (dp->status & DP_STATUS_HPD_STATE)
269 msg[1] |= PMC_USB_DP_HPD_LVL;
270
271 return pmc_usb_command(port, msg, sizeof(msg));
272 }
273
274 static int
pmc_usb_mux_dp(struct pmc_usb_port * port,struct typec_mux_state * state)275 pmc_usb_mux_dp(struct pmc_usb_port *port, struct typec_mux_state *state)
276 {
277 struct typec_displayport_data *data = state->data;
278 struct altmode_req req = { };
279 int ret;
280
281 if (IOM_PORT_ACTIVITY_IS(port->iom_status, DP) ||
282 IOM_PORT_ACTIVITY_IS(port->iom_status, DP_MFD)) {
283 if (IOM_PORT_HPD_ASSERTED(port->iom_status) &&
284 (!(data->status & DP_STATUS_IRQ_HPD) &&
285 data->status & DP_STATUS_HPD_STATE))
286 return 0;
287
288 return pmc_usb_mux_dp_hpd(port, state->data);
289 }
290
291 req.usage = PMC_USB_ALT_MODE;
292 req.usage |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
293 req.mode_type = PMC_USB_MODE_TYPE_DP << PMC_USB_MODE_TYPE_SHIFT;
294
295 req.mode_data = (port->orientation - 1) << PMC_USB_ALTMODE_ORI_SHIFT;
296 req.mode_data |= (port->role - 1) << PMC_USB_ALTMODE_UFP_SHIFT;
297
298 req.mode_data |= (state->mode - TYPEC_STATE_MODAL) <<
299 PMC_USB_ALTMODE_DP_MODE_SHIFT;
300
301 if (!is_pmc_mux_tbt(port->pmc->iom_adev)) {
302 u8 cable_speed = (data->conf & DP_CONF_SIGNALLING_MASK) >>
303 DP_CONF_SIGNALLING_SHIFT;
304
305 u8 cable_type = (data->conf & DP_CONF_CABLE_TYPE_MASK) >>
306 DP_CONF_CABLE_TYPE_SHIFT;
307
308 req.mode_data |= PMC_USB_ALTMODE_CABLE_SPD(cable_speed);
309
310 if (cable_type == DP_CONF_CABLE_TYPE_OPTICAL)
311 req.mode_data |= PMC_USB_ALTMODE_CABLE_TYPE;
312 else if (cable_type == DP_CONF_CABLE_TYPE_RE_TIMER)
313 req.mode_data |= PMC_USB_ALTMODE_ACTIVE_CABLE |
314 PMC_USB_ALTMODE_RETIMER_CABLE;
315 else if (cable_type == DP_CONF_CABLE_TYPE_RE_DRIVER)
316 req.mode_data |= PMC_USB_ALTMODE_ACTIVE_CABLE;
317 }
318
319 ret = pmc_usb_command(port, (void *)&req, sizeof(req));
320 if (ret)
321 return ret;
322
323 if (data->status & (DP_STATUS_IRQ_HPD | DP_STATUS_HPD_STATE))
324 return pmc_usb_mux_dp_hpd(port, state->data);
325
326 return 0;
327 }
328
329 static int
pmc_usb_mux_tbt(struct pmc_usb_port * port,struct typec_mux_state * state)330 pmc_usb_mux_tbt(struct pmc_usb_port *port, struct typec_mux_state *state)
331 {
332 struct typec_thunderbolt_data *data = state->data;
333 u8 cable_rounded = TBT_CABLE_ROUNDED_SUPPORT(data->cable_mode);
334 u8 cable_speed = TBT_CABLE_SPEED(data->cable_mode);
335 struct altmode_req req = { };
336
337 if (IOM_PORT_ACTIVITY_IS(port->iom_status, TBT) ||
338 IOM_PORT_ACTIVITY_IS(port->iom_status, ALT_MODE_TBT_USB))
339 return 0;
340
341 req.usage = PMC_USB_ALT_MODE;
342 req.usage |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
343 req.mode_type = PMC_USB_MODE_TYPE_TBT << PMC_USB_MODE_TYPE_SHIFT;
344
345 req.mode_data = (port->orientation - 1) << PMC_USB_ALTMODE_ORI_SHIFT;
346 req.mode_data |= (port->role - 1) << PMC_USB_ALTMODE_UFP_SHIFT;
347
348 if (TBT_ADAPTER(data->device_mode) == TBT_ADAPTER_TBT3)
349 req.mode_data |= PMC_USB_ALTMODE_TBT_TYPE;
350
351 if (data->cable_mode & TBT_CABLE_OPTICAL)
352 req.mode_data |= PMC_USB_ALTMODE_CABLE_TYPE;
353
354 if (data->cable_mode & TBT_CABLE_LINK_TRAINING)
355 req.mode_data |= PMC_USB_ALTMODE_ACTIVE_LINK;
356
357 if (acpi_dev_hid_uid_match(port->pmc->iom_adev, "INTC1072", NULL) ||
358 acpi_dev_hid_uid_match(port->pmc->iom_adev, "INTC1079", NULL)) {
359 if ((data->enter_vdo & TBT_ENTER_MODE_ACTIVE_CABLE) ||
360 (data->cable_mode & TBT_CABLE_RETIMER))
361 req.mode_data |= PMC_USB_ALTMODE_RETIMER_CABLE;
362 } else {
363 if (data->enter_vdo & TBT_ENTER_MODE_ACTIVE_CABLE)
364 req.mode_data |= PMC_USB_ALTMODE_ACTIVE_CABLE;
365
366 if (data->cable_mode & TBT_CABLE_RETIMER)
367 req.mode_data |= PMC_USB_ALTMODE_RETIMER_CABLE;
368 }
369
370 req.mode_data |= PMC_USB_ALTMODE_CABLE_SPD(cable_speed);
371
372 req.mode_data |= PMC_USB_ALTMODE_TBT_GEN(cable_rounded);
373
374 return pmc_usb_command(port, (void *)&req, sizeof(req));
375 }
376
377 static int
pmc_usb_mux_usb4(struct pmc_usb_port * port,struct typec_mux_state * state)378 pmc_usb_mux_usb4(struct pmc_usb_port *port, struct typec_mux_state *state)
379 {
380 struct enter_usb_data *data = state->data;
381 struct altmode_req req = { };
382 u8 cable_speed;
383
384 if (IOM_PORT_ACTIVITY_IS(port->iom_status, TBT) ||
385 IOM_PORT_ACTIVITY_IS(port->iom_status, ALT_MODE_TBT_USB))
386 return 0;
387
388 req.usage = PMC_USB_ALT_MODE;
389 req.usage |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
390 req.mode_type = PMC_USB_MODE_TYPE_TBT << PMC_USB_MODE_TYPE_SHIFT;
391
392 /* USB4 Mode */
393 req.mode_data = PMC_USB_ALTMODE_FORCE_LSR;
394
395 if (data->active_link_training)
396 req.mode_data |= PMC_USB_ALTMODE_ACTIVE_LINK;
397
398 req.mode_data |= (port->orientation - 1) << PMC_USB_ALTMODE_ORI_SHIFT;
399 req.mode_data |= (port->role - 1) << PMC_USB_ALTMODE_UFP_SHIFT;
400
401 switch ((data->eudo & EUDO_CABLE_TYPE_MASK) >> EUDO_CABLE_TYPE_SHIFT) {
402 case EUDO_CABLE_TYPE_PASSIVE:
403 break;
404 case EUDO_CABLE_TYPE_OPTICAL:
405 req.mode_data |= PMC_USB_ALTMODE_CABLE_TYPE;
406 fallthrough;
407 case EUDO_CABLE_TYPE_RE_TIMER:
408 if (!acpi_dev_hid_uid_match(port->pmc->iom_adev, "INTC1072", NULL) ||
409 !acpi_dev_hid_uid_match(port->pmc->iom_adev, "INTC1079", NULL))
410 req.mode_data |= PMC_USB_ALTMODE_RETIMER_CABLE;
411 fallthrough;
412 default:
413 if (acpi_dev_hid_uid_match(port->pmc->iom_adev, "INTC1072", NULL) ||
414 acpi_dev_hid_uid_match(port->pmc->iom_adev, "INTC1079", NULL))
415 req.mode_data |= PMC_USB_ALTMODE_RETIMER_CABLE;
416 else
417 req.mode_data |= PMC_USB_ALTMODE_ACTIVE_CABLE;
418
419 /* Configure data rate to rounded in the case of Active TBT3
420 * and USB4 cables.
421 */
422 req.mode_data |= PMC_USB_ALTMODE_TBT_GEN(1);
423 break;
424 }
425
426 cable_speed = (data->eudo & EUDO_CABLE_SPEED_MASK) >> EUDO_CABLE_SPEED_SHIFT;
427 req.mode_data |= PMC_USB_ALTMODE_CABLE_SPD(cable_speed);
428
429 return pmc_usb_command(port, (void *)&req, sizeof(req));
430 }
431
pmc_usb_mux_safe_state(struct pmc_usb_port * port,struct typec_mux_state * state)432 static int pmc_usb_mux_safe_state(struct pmc_usb_port *port,
433 struct typec_mux_state *state)
434 {
435 u8 msg;
436
437 if (IOM_PORT_ACTIVITY_IS(port->iom_status, SAFE_MODE))
438 return 0;
439
440 if ((IOM_PORT_ACTIVITY_IS(port->iom_status, DP) ||
441 IOM_PORT_ACTIVITY_IS(port->iom_status, DP_MFD)) &&
442 state->alt && state->alt->svid == USB_TYPEC_DP_SID)
443 return 0;
444
445 if ((IOM_PORT_ACTIVITY_IS(port->iom_status, TBT) ||
446 IOM_PORT_ACTIVITY_IS(port->iom_status, ALT_MODE_TBT_USB)) &&
447 state->alt && state->alt->svid == USB_TYPEC_TBT_SID)
448 return 0;
449
450 msg = PMC_USB_SAFE_MODE;
451 msg |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
452
453 return pmc_usb_command(port, &msg, sizeof(msg));
454 }
455
pmc_usb_disconnect(struct pmc_usb_port * port)456 static int pmc_usb_disconnect(struct pmc_usb_port *port)
457 {
458 struct typec_displayport_data data = { };
459 u8 msg[2];
460
461 if (!(port->iom_status & IOM_PORT_STATUS_CONNECTED))
462 return 0;
463
464 /* Clear DisplayPort HPD if it's still asserted. */
465 if (IOM_PORT_HPD_ASSERTED(port->iom_status))
466 pmc_usb_mux_dp_hpd(port, &data);
467
468 msg[0] = PMC_USB_DISCONNECT;
469 msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
470
471 msg[1] = port->usb2_port << PMC_USB_MSG_USB2_PORT_SHIFT;
472
473 return pmc_usb_command(port, msg, sizeof(msg));
474 }
475
pmc_usb_connect(struct pmc_usb_port * port,enum usb_role role)476 static int pmc_usb_connect(struct pmc_usb_port *port, enum usb_role role)
477 {
478 u8 ufp = role == USB_ROLE_DEVICE ? 1 : 0;
479 u8 msg[2];
480 int ret;
481
482 if (port->orientation == TYPEC_ORIENTATION_NONE)
483 return -EINVAL;
484
485 if (port->iom_status & IOM_PORT_STATUS_CONNECTED) {
486 if (port->role == role || port->role == USB_ROLE_NONE)
487 return 0;
488
489 /* Role swap */
490 ret = pmc_usb_disconnect(port);
491 if (ret)
492 return ret;
493 }
494
495 msg[0] = PMC_USB_CONNECT;
496 msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
497
498 msg[1] = port->usb2_port << PMC_USB_MSG_USB2_PORT_SHIFT;
499 msg[1] |= ufp << PMC_USB_MSG_UFP_SHIFT;
500 msg[1] |= hsl_orientation(port) << PMC_USB_MSG_ORI_HSL_SHIFT;
501 msg[1] |= sbu_orientation(port) << PMC_USB_MSG_ORI_AUX_SHIFT;
502
503 return pmc_usb_command(port, msg, sizeof(msg));
504 }
505
506 static int
pmc_usb_mux_set(struct typec_mux_dev * mux,struct typec_mux_state * state)507 pmc_usb_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
508 {
509 struct pmc_usb_port *port = typec_mux_get_drvdata(mux);
510
511 update_port_status(port);
512
513 if (port->orientation == TYPEC_ORIENTATION_NONE || port->role == USB_ROLE_NONE)
514 return 0;
515
516 if (state->mode == TYPEC_STATE_SAFE)
517 return pmc_usb_mux_safe_state(port, state);
518 if (state->mode == TYPEC_STATE_USB)
519 return pmc_usb_connect(port, port->role);
520
521 if (state->alt) {
522 switch (state->alt->svid) {
523 case USB_TYPEC_TBT_SID:
524 return pmc_usb_mux_tbt(port, state);
525 case USB_TYPEC_DP_SID:
526 return pmc_usb_mux_dp(port, state);
527 }
528 } else {
529 switch (state->mode) {
530 case TYPEC_MODE_USB2:
531 /* REVISIT: Try with usb3_port set to 0? */
532 break;
533 case TYPEC_MODE_USB3:
534 return pmc_usb_connect(port, port->role);
535 case TYPEC_MODE_USB4:
536 return pmc_usb_mux_usb4(port, state);
537 }
538 }
539
540 return -EOPNOTSUPP;
541 }
542
pmc_usb_set_orientation(struct typec_switch_dev * sw,enum typec_orientation orientation)543 static int pmc_usb_set_orientation(struct typec_switch_dev *sw,
544 enum typec_orientation orientation)
545 {
546 struct pmc_usb_port *port = typec_switch_get_drvdata(sw);
547
548 update_port_status(port);
549
550 port->orientation = orientation;
551
552 return 0;
553 }
554
pmc_usb_set_role(struct usb_role_switch * sw,enum usb_role role)555 static int pmc_usb_set_role(struct usb_role_switch *sw, enum usb_role role)
556 {
557 struct pmc_usb_port *port = usb_role_switch_get_drvdata(sw);
558 int ret;
559
560 update_port_status(port);
561
562 if (role == USB_ROLE_NONE)
563 ret = pmc_usb_disconnect(port);
564 else
565 ret = pmc_usb_connect(port, role);
566
567 port->role = role;
568
569 return ret;
570 }
571
pmc_usb_register_port(struct pmc_usb * pmc,int index,struct fwnode_handle * fwnode)572 static int pmc_usb_register_port(struct pmc_usb *pmc, int index,
573 struct fwnode_handle *fwnode)
574 {
575 struct pmc_usb_port *port = &pmc->port[index];
576 struct usb_role_switch_desc desc = { };
577 struct typec_switch_desc sw_desc = { };
578 struct typec_mux_desc mux_desc = { };
579 const char *str;
580 int ret;
581
582 ret = fwnode_property_read_u8(fwnode, "usb2-port-number", &port->usb2_port);
583 if (ret)
584 return ret;
585
586 ret = fwnode_property_read_u8(fwnode, "usb3-port-number", &port->usb3_port);
587 if (ret)
588 return ret;
589
590 ret = fwnode_property_read_string(fwnode, "sbu-orientation", &str);
591 if (!ret)
592 port->sbu_orientation = typec_find_orientation(str);
593
594 ret = fwnode_property_read_string(fwnode, "hsl-orientation", &str);
595 if (!ret)
596 port->hsl_orientation = typec_find_orientation(str);
597
598 port->num = index;
599 port->pmc = pmc;
600
601 sw_desc.fwnode = fwnode;
602 sw_desc.drvdata = port;
603 sw_desc.name = fwnode_get_name(fwnode);
604 sw_desc.set = pmc_usb_set_orientation;
605
606 port->typec_sw = typec_switch_register(pmc->dev, &sw_desc);
607 if (IS_ERR(port->typec_sw))
608 return PTR_ERR(port->typec_sw);
609
610 mux_desc.fwnode = fwnode;
611 mux_desc.drvdata = port;
612 mux_desc.name = fwnode_get_name(fwnode);
613 mux_desc.set = pmc_usb_mux_set;
614
615 port->typec_mux = typec_mux_register(pmc->dev, &mux_desc);
616 if (IS_ERR(port->typec_mux)) {
617 ret = PTR_ERR(port->typec_mux);
618 goto err_unregister_switch;
619 }
620
621 desc.fwnode = fwnode;
622 desc.driver_data = port;
623 desc.name = fwnode_get_name(fwnode);
624 desc.set = pmc_usb_set_role;
625 desc.allow_userspace_control = true;
626
627 port->usb_sw = usb_role_switch_register(pmc->dev, &desc);
628 if (IS_ERR(port->usb_sw)) {
629 ret = PTR_ERR(port->usb_sw);
630 goto err_unregister_mux;
631 }
632
633 return 0;
634
635 err_unregister_mux:
636 typec_mux_unregister(port->typec_mux);
637
638 err_unregister_switch:
639 typec_switch_unregister(port->typec_sw);
640
641 return ret;
642 }
643
644 /* IOM ACPI IDs and IOM_PORT_STATUS_OFFSET */
645 static const struct acpi_device_id iom_acpi_ids[] = {
646 /* TigerLake */
647 { "INTC1072", IOM_PORT_STATUS_REGS(0x560, IOM_PORT_STATUS_REGS_SZ_4) },
648
649 /* AlderLake */
650 { "INTC1079", IOM_PORT_STATUS_REGS(0x160, IOM_PORT_STATUS_REGS_SZ_4) },
651
652 /* Meteor Lake */
653 { "INTC107A", IOM_PORT_STATUS_REGS(0x160, IOM_PORT_STATUS_REGS_SZ_4) },
654
655 /* Lunar Lake */
656 { "INTC10EA", IOM_PORT_STATUS_REGS(0x150, IOM_PORT_STATUS_REGS_SZ_8) },
657 {}
658 };
659
pmc_usb_probe_iom(struct pmc_usb * pmc)660 static int pmc_usb_probe_iom(struct pmc_usb *pmc)
661 {
662 struct list_head resource_list;
663 struct resource_entry *rentry;
664 static const struct acpi_device_id *dev_id;
665 struct acpi_device *adev = NULL;
666 int ret;
667
668 for (dev_id = &iom_acpi_ids[0]; dev_id->id[0]; dev_id++) {
669 adev = acpi_dev_get_first_match_dev(dev_id->id, NULL, -1);
670 if (adev)
671 break;
672 }
673 if (!adev)
674 return -ENODEV;
675
676 pmc->iom_port_status_offset = IOM_PORT_STATUS_REGS_OFFSET(dev_id->driver_data);
677 pmc->iom_port_status_size = IOM_PORT_STATUS_REGS_SIZE(dev_id->driver_data);
678
679 INIT_LIST_HEAD(&resource_list);
680 ret = acpi_dev_get_memory_resources(adev, &resource_list);
681 if (ret < 0) {
682 acpi_dev_put(adev);
683 return ret;
684 }
685
686 rentry = list_first_entry_or_null(&resource_list, struct resource_entry, node);
687 if (rentry)
688 pmc->iom_base = devm_ioremap_resource(pmc->dev, rentry->res);
689
690 acpi_dev_free_resource_list(&resource_list);
691
692 if (!pmc->iom_base) {
693 acpi_dev_put(adev);
694 return -ENOMEM;
695 }
696
697 if (IS_ERR(pmc->iom_base)) {
698 acpi_dev_put(adev);
699 return PTR_ERR(pmc->iom_base);
700 }
701
702 pmc->iom_adev = adev;
703
704 return 0;
705 }
706
port_iom_status_show(struct seq_file * s,void * unused)707 static int port_iom_status_show(struct seq_file *s, void *unused)
708 {
709 struct pmc_usb_port *port = s->private;
710
711 update_port_status(port);
712 seq_printf(s, "0x%08x\n", port->iom_status);
713
714 return 0;
715 }
716 DEFINE_SHOW_ATTRIBUTE(port_iom_status);
717
pmc_mux_port_debugfs_init(struct pmc_usb_port * port)718 static void pmc_mux_port_debugfs_init(struct pmc_usb_port *port)
719 {
720 struct dentry *debugfs_dir;
721 char name[6];
722
723 snprintf(name, sizeof(name), "port%d", port->usb3_port - 1);
724
725 debugfs_dir = debugfs_create_dir(name, port->pmc->dentry);
726 debugfs_create_file("iom_status", 0400, debugfs_dir, port,
727 &port_iom_status_fops);
728 }
729
pmc_usb_probe(struct platform_device * pdev)730 static int pmc_usb_probe(struct platform_device *pdev)
731 {
732 struct fwnode_handle *fwnode = NULL;
733 struct pmc_usb *pmc;
734 int i = 0;
735 int ret;
736
737 pmc = devm_kzalloc(&pdev->dev, sizeof(*pmc), GFP_KERNEL);
738 if (!pmc)
739 return -ENOMEM;
740
741 device_for_each_child_node(&pdev->dev, fwnode)
742 pmc->num_ports++;
743
744 /* The IOM microcontroller has a limitation of max 4 ports. */
745 if (pmc->num_ports > 4) {
746 dev_err(&pdev->dev, "driver limited to 4 ports\n");
747 return -ERANGE;
748 }
749
750 pmc->port = devm_kcalloc(&pdev->dev, pmc->num_ports,
751 sizeof(struct pmc_usb_port), GFP_KERNEL);
752 if (!pmc->port)
753 return -ENOMEM;
754
755 pmc->ipc = devm_intel_scu_ipc_dev_get(&pdev->dev);
756 if (!pmc->ipc)
757 return -ENODEV;
758
759 pmc->dev = &pdev->dev;
760
761 ret = pmc_usb_probe_iom(pmc);
762 if (ret)
763 return ret;
764
765 pmc->dentry = debugfs_create_dir(dev_name(pmc->dev), pmc_mux_debugfs_root);
766
767 /*
768 * For every physical USB connector (USB2 and USB3 combo) there is a
769 * child ACPI device node under the PMC mux ACPI device object.
770 */
771 for (i = 0; i < pmc->num_ports; i++) {
772 fwnode = device_get_next_child_node(pmc->dev, fwnode);
773 if (!fwnode)
774 break;
775
776 ret = pmc_usb_register_port(pmc, i, fwnode);
777 if (ret) {
778 fwnode_handle_put(fwnode);
779 goto err_remove_ports;
780 }
781
782 pmc_mux_port_debugfs_init(&pmc->port[i]);
783 }
784
785 platform_set_drvdata(pdev, pmc);
786
787 return 0;
788
789 err_remove_ports:
790 for (i = 0; i < pmc->num_ports; i++) {
791 typec_switch_unregister(pmc->port[i].typec_sw);
792 typec_mux_unregister(pmc->port[i].typec_mux);
793 usb_role_switch_unregister(pmc->port[i].usb_sw);
794 }
795
796 acpi_dev_put(pmc->iom_adev);
797
798 debugfs_remove(pmc->dentry);
799
800 return ret;
801 }
802
pmc_usb_remove(struct platform_device * pdev)803 static void pmc_usb_remove(struct platform_device *pdev)
804 {
805 struct pmc_usb *pmc = platform_get_drvdata(pdev);
806 int i;
807
808 for (i = 0; i < pmc->num_ports; i++) {
809 typec_switch_unregister(pmc->port[i].typec_sw);
810 typec_mux_unregister(pmc->port[i].typec_mux);
811 usb_role_switch_unregister(pmc->port[i].usb_sw);
812 }
813
814 acpi_dev_put(pmc->iom_adev);
815
816 debugfs_remove(pmc->dentry);
817 }
818
819 static const struct acpi_device_id pmc_usb_acpi_ids[] = {
820 { "INTC105C", },
821 { }
822 };
823 MODULE_DEVICE_TABLE(acpi, pmc_usb_acpi_ids);
824
825 static struct platform_driver pmc_usb_driver = {
826 .driver = {
827 .name = "intel_pmc_usb",
828 .acpi_match_table = ACPI_PTR(pmc_usb_acpi_ids),
829 },
830 .probe = pmc_usb_probe,
831 .remove_new = pmc_usb_remove,
832 };
833
pmc_usb_init(void)834 static int __init pmc_usb_init(void)
835 {
836 pmc_mux_debugfs_root = debugfs_create_dir("intel_pmc_mux", usb_debug_root);
837
838 return platform_driver_register(&pmc_usb_driver);
839 }
840 module_init(pmc_usb_init);
841
pmc_usb_exit(void)842 static void __exit pmc_usb_exit(void)
843 {
844 platform_driver_unregister(&pmc_usb_driver);
845 debugfs_remove(pmc_mux_debugfs_root);
846 }
847 module_exit(pmc_usb_exit);
848
849 MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
850 MODULE_LICENSE("GPL v2");
851 MODULE_DESCRIPTION("Intel PMC USB mux control");
852