xref: /linux/drivers/usb/cdns3/core.c (revision 995832b2cebe6969d1b42635db698803ee31294d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Cadence USBSS and USBSSP DRD Driver.
4  *
5  * Copyright (C) 2018-2019 Cadence.
6  * Copyright (C) 2017-2018 NXP
7  * Copyright (C) 2019 Texas Instruments
8  *
9  * Author: Peter Chen <peter.chen@nxp.com>
10  *         Pawel Laszczak <pawell@cadence.com>
11  *         Roger Quadros <rogerq@ti.com>
12  */
13 
14 #include <linux/dma-mapping.h>
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/of.h>
18 #include <linux/platform_device.h>
19 #include <linux/interrupt.h>
20 #include <linux/io.h>
21 #include <linux/pm_runtime.h>
22 
23 #include "core.h"
24 #include "drd.h"
25 
26 static int cdns_idle_init(struct cdns *cdns);
27 
28 static int cdns_role_start(struct cdns *cdns, enum usb_role role)
29 {
30 	int ret;
31 
32 	if (WARN_ON(role > USB_ROLE_DEVICE))
33 		return 0;
34 
35 	mutex_lock(&cdns->mutex);
36 	cdns->role = role;
37 	mutex_unlock(&cdns->mutex);
38 
39 	if (!cdns->roles[role])
40 		return -ENXIO;
41 
42 	if (cdns->roles[role]->state == CDNS_ROLE_STATE_ACTIVE)
43 		return 0;
44 
45 	mutex_lock(&cdns->mutex);
46 	ret = cdns->roles[role]->start(cdns);
47 	if (!ret)
48 		cdns->roles[role]->state = CDNS_ROLE_STATE_ACTIVE;
49 	mutex_unlock(&cdns->mutex);
50 
51 	return ret;
52 }
53 
54 static void cdns_role_stop(struct cdns *cdns)
55 {
56 	enum usb_role role = cdns->role;
57 
58 	if (WARN_ON(role > USB_ROLE_DEVICE))
59 		return;
60 
61 	if (cdns->roles[role]->state == CDNS_ROLE_STATE_INACTIVE)
62 		return;
63 
64 	mutex_lock(&cdns->mutex);
65 	cdns->roles[role]->stop(cdns);
66 	cdns->roles[role]->state = CDNS_ROLE_STATE_INACTIVE;
67 	mutex_unlock(&cdns->mutex);
68 }
69 
70 static void cdns_exit_roles(struct cdns *cdns)
71 {
72 	cdns_role_stop(cdns);
73 	if (!cdns->no_drd)
74 		cdns_drd_exit(cdns);
75 }
76 
77 /**
78  * cdns_core_init_role - initialize role of operation
79  * @cdns: Pointer to cdns structure
80  *
81  * Returns 0 on success otherwise negative errno
82  */
83 int cdns_core_init_role(struct cdns *cdns)
84 {
85 	struct device *dev = cdns->dev;
86 	enum usb_dr_mode best_dr_mode;
87 	enum usb_dr_mode dr_mode;
88 	int ret;
89 
90 	dr_mode = usb_get_dr_mode(dev);
91 	cdns->role = USB_ROLE_NONE;
92 
93 	/*
94 	 * If driver can't read mode by means of usb_get_dr_mode function then
95 	 * chooses mode according with Kernel configuration. This setting
96 	 * can be restricted later depending on strap pin configuration.
97 	 */
98 	if (dr_mode == USB_DR_MODE_UNKNOWN) {
99 		if (IS_ENABLED(CONFIG_USB_CDNS3_HOST) &&
100 		    IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
101 			dr_mode = USB_DR_MODE_OTG;
102 		else if (IS_ENABLED(CONFIG_USB_CDNS3_HOST))
103 			dr_mode = USB_DR_MODE_HOST;
104 		else if (IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
105 			dr_mode = USB_DR_MODE_PERIPHERAL;
106 	}
107 
108 	/*
109 	 * At this point cdns->dr_mode contains strap configuration.
110 	 * Driver try update this setting considering kernel configuration
111 	 */
112 	best_dr_mode = cdns->dr_mode;
113 
114 	ret = cdns_idle_init(cdns);
115 	if (ret)
116 		return ret;
117 
118 	if (dr_mode == USB_DR_MODE_OTG) {
119 		best_dr_mode = cdns->dr_mode;
120 	} else if (cdns->dr_mode == USB_DR_MODE_OTG) {
121 		best_dr_mode = dr_mode;
122 	} else if (cdns->dr_mode != dr_mode) {
123 		dev_err(dev, "Incorrect DRD configuration\n");
124 		return -EINVAL;
125 	}
126 
127 	dr_mode = best_dr_mode;
128 
129 	if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
130 		if (cdns->host_init)
131 			ret = cdns->host_init(cdns);
132 		else
133 			ret = -ENXIO;
134 
135 		if (ret) {
136 			dev_err(dev, "Host initialization failed with %d\n",
137 				ret);
138 			goto err;
139 		}
140 	}
141 
142 	if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
143 		if (cdns->gadget_init)
144 			ret = cdns->gadget_init(cdns);
145 		else
146 			ret = -ENXIO;
147 
148 		if (ret) {
149 			dev_err(dev, "Device initialization failed with %d\n",
150 				ret);
151 			goto err;
152 		}
153 	}
154 
155 	cdns->dr_mode = dr_mode;
156 
157 	ret = cdns_drd_update_mode(cdns);
158 	if (ret)
159 		goto err;
160 
161 	/* Initialize idle role to start with */
162 	ret = cdns_role_start(cdns, USB_ROLE_NONE);
163 	if (ret)
164 		goto err;
165 
166 	switch (cdns->dr_mode) {
167 	case USB_DR_MODE_OTG:
168 		ret = cdns_hw_role_switch(cdns);
169 		if (ret)
170 			goto err;
171 		break;
172 	case USB_DR_MODE_PERIPHERAL:
173 		ret = cdns_role_start(cdns, USB_ROLE_DEVICE);
174 		if (ret)
175 			goto err;
176 		break;
177 	case USB_DR_MODE_HOST:
178 		ret = cdns_role_start(cdns, USB_ROLE_HOST);
179 		if (ret)
180 			goto err;
181 		break;
182 	default:
183 		ret = -EINVAL;
184 		goto err;
185 	}
186 
187 	dev_dbg(dev, "Cadence USB3 core: probe succeed\n");
188 
189 	return 0;
190 err:
191 	cdns_exit_roles(cdns);
192 	return ret;
193 }
194 EXPORT_SYMBOL_GPL(cdns_core_init_role);
195 
196 /**
197  * cdns_hw_role_state_machine  - role switch state machine based on hw events.
198  * @cdns: Pointer to controller structure.
199  *
200  * Returns next role to be entered based on hw events.
201  */
202 static enum usb_role cdns_hw_role_state_machine(struct cdns *cdns)
203 {
204 	enum usb_role role = USB_ROLE_NONE;
205 	int id, vbus;
206 
207 	if (cdns->dr_mode != USB_DR_MODE_OTG) {
208 		if (cdns_is_host(cdns))
209 			role = USB_ROLE_HOST;
210 		if (cdns_is_device(cdns))
211 			role = USB_ROLE_DEVICE;
212 
213 		return role;
214 	}
215 
216 	id = cdns_get_id(cdns);
217 	vbus = cdns_get_vbus(cdns);
218 
219 	/*
220 	 * Role change state machine
221 	 * Inputs: ID, VBUS
222 	 * Previous state: cdns->role
223 	 * Next state: role
224 	 */
225 	role = cdns->role;
226 
227 	switch (role) {
228 	case USB_ROLE_NONE:
229 		/*
230 		 * Driver treats USB_ROLE_NONE synonymous to IDLE state from
231 		 * controller specification.
232 		 */
233 		if (!id)
234 			role = USB_ROLE_HOST;
235 		else if (vbus)
236 			role = USB_ROLE_DEVICE;
237 		break;
238 	case USB_ROLE_HOST: /* from HOST, we can only change to NONE */
239 		if (id)
240 			role = USB_ROLE_NONE;
241 		break;
242 	case USB_ROLE_DEVICE: /* from GADGET, we can only change to NONE*/
243 		if (!vbus)
244 			role = USB_ROLE_NONE;
245 		break;
246 	}
247 
248 	dev_dbg(cdns->dev, "role %d -> %d\n", cdns->role, role);
249 
250 	return role;
251 }
252 
253 static int cdns_idle_role_start(struct cdns *cdns)
254 {
255 	return 0;
256 }
257 
258 static void cdns_idle_role_stop(struct cdns *cdns)
259 {
260 	/* Program Lane swap and bring PHY out of RESET */
261 	phy_reset(cdns->usb3_phy);
262 }
263 
264 static int cdns_idle_init(struct cdns *cdns)
265 {
266 	struct cdns_role_driver *rdrv;
267 
268 	rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL);
269 	if (!rdrv)
270 		return -ENOMEM;
271 
272 	rdrv->start = cdns_idle_role_start;
273 	rdrv->stop = cdns_idle_role_stop;
274 	rdrv->state = CDNS_ROLE_STATE_INACTIVE;
275 	rdrv->suspend = NULL;
276 	rdrv->resume = NULL;
277 	rdrv->name = "idle";
278 
279 	cdns->roles[USB_ROLE_NONE] = rdrv;
280 
281 	return 0;
282 }
283 
284 /**
285  * cdns_hw_role_switch - switch roles based on HW state
286  * @cdns: controller
287  */
288 int cdns_hw_role_switch(struct cdns *cdns)
289 {
290 	enum usb_role real_role, current_role;
291 	int ret = 0;
292 
293 	/* Depends on role switch class */
294 	if (cdns->role_sw)
295 		return 0;
296 
297 	pm_runtime_get_sync(cdns->dev);
298 
299 	current_role = cdns->role;
300 	real_role = cdns_hw_role_state_machine(cdns);
301 
302 	/* Do nothing if nothing changed */
303 	if (current_role == real_role)
304 		goto exit;
305 
306 	cdns_role_stop(cdns);
307 
308 	dev_dbg(cdns->dev, "Switching role %d -> %d", current_role, real_role);
309 
310 	ret = cdns_role_start(cdns, real_role);
311 	if (ret) {
312 		/* Back to current role */
313 		dev_err(cdns->dev, "set %d has failed, back to %d\n",
314 			real_role, current_role);
315 		ret = cdns_role_start(cdns, current_role);
316 		if (ret)
317 			dev_err(cdns->dev, "back to %d failed too\n",
318 				current_role);
319 	}
320 exit:
321 	pm_runtime_put_sync(cdns->dev);
322 	return ret;
323 }
324 
325 /**
326  * cdns_role_get - get current role of controller.
327  *
328  * @sw: pointer to USB role switch structure
329  *
330  * Returns role
331  */
332 static enum usb_role cdns_role_get(struct usb_role_switch *sw)
333 {
334 	struct cdns *cdns = usb_role_switch_get_drvdata(sw);
335 
336 	return cdns->role;
337 }
338 
339 /**
340  * cdns_role_set - set current role of controller.
341  *
342  * @sw: pointer to USB role switch structure
343  * @role: the previous role
344  * Handles below events:
345  * - Role switch for dual-role devices
346  * - USB_ROLE_GADGET <--> USB_ROLE_NONE for peripheral-only devices
347  */
348 static int cdns_role_set(struct usb_role_switch *sw, enum usb_role role)
349 {
350 	struct cdns *cdns = usb_role_switch_get_drvdata(sw);
351 	int ret = 0;
352 
353 	pm_runtime_get_sync(cdns->dev);
354 
355 	if (cdns->role == role)
356 		goto pm_put;
357 
358 	if (cdns->dr_mode == USB_DR_MODE_HOST) {
359 		switch (role) {
360 		case USB_ROLE_NONE:
361 		case USB_ROLE_HOST:
362 			break;
363 		default:
364 			goto pm_put;
365 		}
366 	}
367 
368 	if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL) {
369 		switch (role) {
370 		case USB_ROLE_NONE:
371 		case USB_ROLE_DEVICE:
372 			break;
373 		default:
374 			goto pm_put;
375 		}
376 	}
377 
378 	cdns_role_stop(cdns);
379 	ret = cdns_role_start(cdns, role);
380 	if (ret)
381 		dev_err(cdns->dev, "set role %d has failed\n", role);
382 
383 pm_put:
384 	pm_runtime_put_sync(cdns->dev);
385 	return ret;
386 }
387 
388 /**
389  * cdns_wakeup_irq - interrupt handler for wakeup events
390  * @irq: irq number for cdns3/cdnsp core device
391  * @data: structure of cdns
392  *
393  * Returns IRQ_HANDLED or IRQ_NONE
394  */
395 static irqreturn_t cdns_wakeup_irq(int irq, void *data)
396 {
397 	struct cdns *cdns = data;
398 
399 	if (cdns->in_lpm) {
400 		disable_irq_nosync(irq);
401 		cdns->wakeup_pending = true;
402 		if ((cdns->role == USB_ROLE_HOST) && cdns->host_dev)
403 			pm_request_resume(&cdns->host_dev->dev);
404 
405 		return IRQ_HANDLED;
406 	}
407 
408 	return IRQ_NONE;
409 }
410 
411 /**
412  * cdns_init - probe for cdns3/cdnsp core device
413  * @cdns: Pointer to cdns structure.
414  *
415  * Returns 0 on success otherwise negative errno
416  */
417 int cdns_init(struct cdns *cdns)
418 {
419 	struct device *dev = cdns->dev;
420 	int ret;
421 
422 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
423 	if (ret) {
424 		dev_err(dev, "error setting dma mask: %d\n", ret);
425 		return ret;
426 	}
427 
428 	mutex_init(&cdns->mutex);
429 
430 	if (device_property_read_bool(dev, "usb-role-switch")) {
431 		struct usb_role_switch_desc sw_desc = { };
432 
433 		sw_desc.set = cdns_role_set;
434 		sw_desc.get = cdns_role_get;
435 		sw_desc.allow_userspace_control = true;
436 		sw_desc.driver_data = cdns;
437 		sw_desc.fwnode = dev->fwnode;
438 
439 		cdns->role_sw = usb_role_switch_register(dev, &sw_desc);
440 		if (IS_ERR(cdns->role_sw)) {
441 			dev_warn(dev, "Unable to register Role Switch\n");
442 			return PTR_ERR(cdns->role_sw);
443 		}
444 	}
445 
446 	if (cdns->wakeup_irq) {
447 		ret = devm_request_irq(cdns->dev, cdns->wakeup_irq,
448 						cdns_wakeup_irq,
449 						IRQF_SHARED,
450 						dev_name(cdns->dev), cdns);
451 
452 		if (ret) {
453 			dev_err(cdns->dev, "couldn't register wakeup irq handler\n");
454 			goto role_switch_unregister;
455 		}
456 	}
457 
458 	ret = cdns_drd_init(cdns);
459 	if (ret)
460 		goto init_failed;
461 
462 	spin_lock_init(&cdns->lock);
463 
464 	return 0;
465 init_failed:
466 	cdns_drd_exit(cdns);
467 role_switch_unregister:
468 	if (cdns->role_sw)
469 		usb_role_switch_unregister(cdns->role_sw);
470 
471 	return ret;
472 }
473 EXPORT_SYMBOL_GPL(cdns_init);
474 
475 /**
476  * cdns_remove - unbind drd driver and clean up
477  * @cdns: Pointer to cdns structure.
478  *
479  * Returns 0 on success otherwise negative errno
480  */
481 int cdns_remove(struct cdns *cdns)
482 {
483 	cdns_exit_roles(cdns);
484 	usb_role_switch_unregister(cdns->role_sw);
485 
486 	return 0;
487 }
488 EXPORT_SYMBOL_GPL(cdns_remove);
489 
490 #ifdef CONFIG_PM_SLEEP
491 int cdns_suspend(struct cdns *cdns)
492 {
493 	struct device *dev = cdns->dev;
494 	unsigned long flags;
495 
496 	if (pm_runtime_status_suspended(dev))
497 		pm_runtime_resume(dev);
498 
499 	if (cdns->roles[cdns->role]->suspend) {
500 		spin_lock_irqsave(&cdns->lock, flags);
501 		cdns->roles[cdns->role]->suspend(cdns, false);
502 		spin_unlock_irqrestore(&cdns->lock, flags);
503 	}
504 
505 	return 0;
506 }
507 EXPORT_SYMBOL_GPL(cdns_suspend);
508 
509 int cdns_resume(struct cdns *cdns)
510 {
511 	bool power_lost = cdns_power_is_lost(cdns);
512 	enum usb_role real_role;
513 	bool role_changed = false;
514 	int ret = 0;
515 
516 	if (power_lost) {
517 		if (!cdns->role_sw) {
518 			real_role = cdns_hw_role_state_machine(cdns);
519 			if (real_role != cdns->role) {
520 				ret = cdns_hw_role_switch(cdns);
521 				if (ret)
522 					return ret;
523 				role_changed = true;
524 			}
525 		}
526 
527 		if (!role_changed) {
528 			if (cdns->role == USB_ROLE_HOST)
529 				ret = cdns_drd_host_on(cdns);
530 			else if (cdns->role == USB_ROLE_DEVICE)
531 				ret = cdns_drd_gadget_on(cdns);
532 
533 			if (ret)
534 				return ret;
535 		}
536 	}
537 
538 	if (!role_changed && cdns->roles[cdns->role]->resume)
539 		cdns->roles[cdns->role]->resume(cdns, power_lost);
540 
541 	return 0;
542 }
543 EXPORT_SYMBOL_GPL(cdns_resume);
544 
545 void cdns_set_active(struct cdns *cdns, u8 set_active)
546 {
547 	struct device *dev = cdns->dev;
548 
549 	if (set_active) {
550 		pm_runtime_disable(dev);
551 		pm_runtime_set_active(dev);
552 		pm_runtime_enable(dev);
553 	}
554 
555 	return;
556 }
557 EXPORT_SYMBOL_GPL(cdns_set_active);
558 #endif /* CONFIG_PM_SLEEP */
559 
560 MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>");
561 MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
562 MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>");
563 MODULE_DESCRIPTION("Cadence USBSS/USBSSP DRD driver (core, DRD, platform, optional host/gadget)");
564 MODULE_LICENSE("GPL");
565