File Index
Files and directories
Sign in
FILE

host.c

File preview with syntax highlighting.

linux-6.19.14/drivers/usb/chipidea/host.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * host.c - ChipIdea USB host controller driver
  4 *
  5 * Copyright (c) 2012 Intel Corporation
  6 *
  7 * Author: Alexander Shishkin
  8 */
  9
 10#include <linux/kernel.h>
 11#include <linux/io.h>
 12#include <linux/usb.h>
 13#include <linux/usb/hcd.h>
 14#include <linux/usb/chipidea.h>
 15#include <linux/regulator/consumer.h>
 16#include <linux/string_choices.h>
 17#include <linux/pinctrl/consumer.h>
 18
 19#include "../host/ehci.h"
 20
 21#include "ci.h"
 22#include "bits.h"
 23#include "host.h"
 24
 25static struct hc_driver __read_mostly ci_ehci_hc_driver;
 26static int (*orig_bus_suspend)(struct usb_hcd *hcd);
 27
 28struct ehci_ci_priv {
 29	struct regulator *reg_vbus;
 30	bool enabled;
 31};
 32
 33struct ci_hdrc_dma_aligned_buffer {
 34	void *original_buffer;
 35	u8 data[];
 36};
 37
 38static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
 39{
 40	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 41	struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv;
 42	struct device *dev = hcd->self.controller;
 43	struct ci_hdrc *ci = dev_get_drvdata(dev);
 44	int ret = 0;
 45	int port = HCS_N_PORTS(ehci->hcs_params);
 46
 47	if (priv->reg_vbus && enable != priv->enabled) {
 48		if (port > 1) {
 49			dev_warn(dev,
 50				"Not support multi-port regulator control\n");
 51			return 0;
 52		}
 53		if (enable)
 54			ret = regulator_enable(priv->reg_vbus);
 55		else
 56			ret = regulator_disable(priv->reg_vbus);
 57		if (ret) {
 58			dev_err(dev,
 59				"Failed to %s vbus regulator, ret=%d\n",
 60				str_enable_disable(enable), ret);
 61			return ret;
 62		}
 63		priv->enabled = enable;
 64	}
 65
 66	if (ci->platdata->flags & CI_HDRC_PHY_VBUS_CONTROL) {
 67		if (enable)
 68			usb_phy_vbus_on(ci->usb_phy);
 69		else
 70			usb_phy_vbus_off(ci->usb_phy);
 71	}
 72
 73	if (enable && (ci->platdata->phy_mode == USBPHY_INTERFACE_MODE_HSIC)) {
 74		/*
 75		 * Marvell 28nm HSIC PHY requires forcing the port to HS mode.
 76		 * As HSIC is always HS, this should be safe for others.
 77		 */
 78		hw_port_test_set(ci, 5);
 79		hw_port_test_set(ci, 0);
 80	}
 81	return 0;
 82};
 83
 84static int ehci_ci_reset(struct usb_hcd *hcd)
 85{
 86	struct device *dev = hcd->self.controller;
 87	struct ci_hdrc *ci = dev_get_drvdata(dev);
 88	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 89	int ret;
 90
 91	ret = ehci_setup(hcd);
 92	if (ret)
 93		return ret;
 94
 95	ehci->need_io_watchdog = 0;
 96
 97	if (ci->platdata->notify_event) {
 98		ret = ci->platdata->notify_event(ci,
 99				CI_HDRC_CONTROLLER_RESET_EVENT);
100		if (ret)
101			return ret;
102	}
103
104	ci_platform_configure(ci);
105
106	return ret;
107}
108
109static const struct ehci_driver_overrides ehci_ci_overrides = {
110	.extra_priv_size = sizeof(struct ehci_ci_priv),
111	.port_power	 = ehci_ci_portpower,
112	.reset		 = ehci_ci_reset,
113};
114
115static irqreturn_t host_irq(struct ci_hdrc *ci)
116{
117	return usb_hcd_irq(ci->irq, ci->hcd);
118}
119
120static int host_start(struct ci_hdrc *ci)
121{
122	struct usb_hcd *hcd;
123	struct ehci_hcd *ehci;
124	struct ehci_ci_priv *priv;
125	int ret;
126
127	if (usb_disabled())
128		return -ENODEV;
129
130	hcd = __usb_create_hcd(&ci_ehci_hc_driver, ci->dev->parent,
131			       ci->dev, dev_name(ci->dev), NULL);
132	if (!hcd)
133		return -ENOMEM;
134
135	dev_set_drvdata(ci->dev, ci);
136	hcd->rsrc_start = ci->hw_bank.phys;
137	hcd->rsrc_len = ci->hw_bank.size;
138	hcd->regs = ci->hw_bank.abs;
139	hcd->has_tt = 1;
140
141	hcd->power_budget = ci->platdata->power_budget;
142	hcd->tpl_support = ci->platdata->tpl_support;
143	if (ci->phy || ci->usb_phy) {
144		hcd->skip_phy_initialization = 1;
145		if (ci->usb_phy)
146			hcd->usb_phy = ci->usb_phy;
147	}
148
149	ehci = hcd_to_ehci(hcd);
150	ehci->caps = ci->hw_bank.cap;
151	ehci->has_hostpc = ci->hw_bank.lpm;
152	ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
153	ehci->imx28_write_fix = ci->imx28_write_fix;
154	ehci->has_ci_pec_bug = ci->has_portsc_pec_bug;
155
156	priv = (struct ehci_ci_priv *)ehci->priv;
157	priv->reg_vbus = NULL;
158
159	if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) {
160		if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) {
161			ret = regulator_enable(ci->platdata->reg_vbus);
162			if (ret) {
163				dev_err(ci->dev,
164				"Failed to enable vbus regulator, ret=%d\n",
165									ret);
166				goto put_hcd;
167			}
168		} else {
169			priv->reg_vbus = ci->platdata->reg_vbus;
170		}
171	}
172
173	if (ci->platdata->pins_host)
174		pinctrl_select_state(ci->platdata->pctl,
175				     ci->platdata->pins_host);
176
177	ci->hcd = hcd;
178
179	ret = usb_add_hcd(hcd, 0, 0);
180	if (ret) {
181		ci->hcd = NULL;
182		goto disable_reg;
183	} else {
184		struct usb_otg *otg = &ci->otg;
185
186		if (ci_otg_is_fsm_mode(ci)) {
187			otg->host = &hcd->self;
188			hcd->self.otg_port = 1;
189		}
190
191		if (ci->platdata->notify_event &&
192			(ci->platdata->flags & CI_HDRC_IMX_IS_HSIC))
193			ci->platdata->notify_event
194				(ci, CI_HDRC_IMX_HSIC_ACTIVE_EVENT);
195	}
196
197	return ret;
198
199disable_reg:
200	if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
201			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
202		regulator_disable(ci->platdata->reg_vbus);
203put_hcd:
204	usb_put_hcd(hcd);
205
206	return ret;
207}
208
209static void host_stop(struct ci_hdrc *ci)
210{
211	struct usb_hcd *hcd = ci->hcd;
212
213	if (hcd) {
214		if (ci->platdata->notify_event)
215			ci->platdata->notify_event(ci,
216				CI_HDRC_CONTROLLER_STOPPED_EVENT);
217		usb_remove_hcd(hcd);
218		ci->role = CI_ROLE_END;
219		synchronize_irq(ci->irq);
220		usb_put_hcd(hcd);
221		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
222			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
223				regulator_disable(ci->platdata->reg_vbus);
224	}
225	ci->hcd = NULL;
226	ci->otg.host = NULL;
227
228	if (ci->platdata->pins_host && ci->platdata->pins_default)
229		pinctrl_select_state(ci->platdata->pctl,
230				     ci->platdata->pins_default);
231}
232
233
234void ci_hdrc_host_destroy(struct ci_hdrc *ci)
235{
236	if (ci->role == CI_ROLE_HOST && ci->hcd)
237		host_stop(ci);
238}
239
240/* The below code is based on tegra ehci driver */
241static int ci_ehci_hub_control(
242	struct usb_hcd	*hcd,
243	u16		typeReq,
244	u16		wValue,
245	u16		wIndex,
246	char		*buf,
247	u16		wLength
248)
249{
250	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
251	unsigned int	ports = HCS_N_PORTS(ehci->hcs_params);
252	u32 __iomem	*status_reg;
253	u32		temp, port_index;
254	unsigned long	flags;
255	int		retval = 0;
256	bool		done = false;
257	struct device *dev = hcd->self.controller;
258	struct ci_hdrc *ci = dev_get_drvdata(dev);
259
260	/*
261	 * Avoid out-of-bounds values while calculating the port index
262	 * from wIndex. The compiler doesn't like pointers to invalid
263	 * addresses, even if they are never used.
264	 */
265	port_index = (wIndex - 1) & 0xff;
266	if (port_index >= HCS_N_PORTS_MAX)
267		port_index = 0;
268	status_reg = &ehci->regs->port_status[port_index];
269
270	spin_lock_irqsave(&ehci->lock, flags);
271
272	if (ci->platdata->hub_control) {
273		retval = ci->platdata->hub_control(ci, typeReq, wValue, wIndex,
274						   buf, wLength, &done, &flags);
275		if (done)
276			goto done;
277	}
278
279	if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
280		if (!wIndex || wIndex > ports) {
281			retval = -EPIPE;
282			goto done;
283		}
284
285		temp = ehci_readl(ehci, status_reg);
286		if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
287			retval = -EPIPE;
288			goto done;
289		}
290
291		temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
292		temp |= PORT_WKDISC_E | PORT_WKOC_E;
293		ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
294
295		/*
296		 * If a transaction is in progress, there may be a delay in
297		 * suspending the port. Poll until the port is suspended.
298		 */
299		if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
300			PORT_SUSPEND, 5000))
301			ehci_err(ehci, "timeout waiting for SUSPEND\n");
302
303		if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
304			if (ci->platdata->notify_event)
305				ci->platdata->notify_event(ci,
306					CI_HDRC_IMX_HSIC_SUSPEND_EVENT);
307
308			temp = ehci_readl(ehci, status_reg);
309			temp &= ~(PORT_WKDISC_E | PORT_WKCONN_E);
310			ehci_writel(ehci, temp, status_reg);
311		}
312
313		set_bit(port_index, &ehci->suspended_ports);
314		goto done;
315	}
316
317	/*
318	 * After resume has finished, it needs do some post resume
319	 * operation for some SoCs.
320	 */
321	else if (typeReq == ClearPortFeature &&
322		wValue == USB_PORT_FEAT_C_SUSPEND) {
323		/* Make sure the resume has finished, it should be finished */
324		if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
325			ehci_err(ehci, "timeout waiting for resume\n");
326	}
327
328	spin_unlock_irqrestore(&ehci->lock, flags);
329
330	/* Handle the hub control events here */
331	return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
332done:
333	spin_unlock_irqrestore(&ehci->lock, flags);
334	return retval;
335}
336static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
337{
338	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
339	struct device *dev = hcd->self.controller;
340	struct ci_hdrc *ci = dev_get_drvdata(dev);
341	int port;
342	u32 tmp;
343
344	int ret = orig_bus_suspend(hcd);
345
346	if (ret)
347		return ret;
348
349	port = HCS_N_PORTS(ehci->hcs_params);
350	while (port--) {
351		u32 __iomem *reg = &ehci->regs->port_status[port];
352		u32 portsc = ehci_readl(ehci, reg);
353
354		if (portsc & PORT_CONNECT) {
355			/*
356			 * For chipidea, the resume signal will be ended
357			 * automatically, so for remote wakeup case, the
358			 * usbcmd.rs may not be set before the resume has
359			 * ended if other resume paths consumes too much
360			 * time (~24ms), in that case, the SOF will not
361			 * send out within 3ms after resume ends, then the
362			 * high speed device will enter full speed mode.
363			 */
364
365			tmp = ehci_readl(ehci, &ehci->regs->command);
366			tmp |= CMD_RUN;
367			ehci_writel(ehci, tmp, &ehci->regs->command);
368			/*
369			 * It needs a short delay between set RS bit and PHCD.
370			 */
371			usleep_range(150, 200);
372			/*
373			 * Need to clear WKCN and WKOC for imx HSIC,
374			 * otherwise, there will be wakeup event.
375			 */
376			if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
377				tmp = ehci_readl(ehci, reg);
378				tmp &= ~(PORT_WKDISC_E | PORT_WKCONN_E);
379				ehci_writel(ehci, tmp, reg);
380			}
381
382			break;
383		}
384	}
385
386	return 0;
387}
388
389static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb, bool copy_back)
390{
391	struct ci_hdrc_dma_aligned_buffer *temp;
392
393	if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
394		return;
395	urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
396
397	temp = container_of(urb->transfer_buffer,
398			    struct ci_hdrc_dma_aligned_buffer, data);
399	urb->transfer_buffer = temp->original_buffer;
400
401	if (copy_back && usb_urb_dir_in(urb)) {
402		size_t length;
403
404		if (usb_pipeisoc(urb->pipe))
405			length = urb->transfer_buffer_length;
406		else
407			length = urb->actual_length;
408
409		memcpy(temp->original_buffer, temp->data, length);
410	}
411
412	kfree(temp);
413}
414
415static int ci_hdrc_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
416{
417	struct ci_hdrc_dma_aligned_buffer *temp;
418
419	if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0)
420		return 0;
421	if (IS_ALIGNED((uintptr_t)urb->transfer_buffer, 4)
422	    && IS_ALIGNED(urb->transfer_buffer_length, 4))
423		return 0;
424
425	temp = kmalloc(sizeof(*temp) + ALIGN(urb->transfer_buffer_length, 4), mem_flags);
426	if (!temp)
427		return -ENOMEM;
428
429	if (usb_urb_dir_out(urb))
430		memcpy(temp->data, urb->transfer_buffer,
431		       urb->transfer_buffer_length);
432
433	temp->original_buffer = urb->transfer_buffer;
434	urb->transfer_buffer = temp->data;
435	urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
436
437	return 0;
438}
439
440static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
441				   gfp_t mem_flags)
442{
443	int ret;
444
445	ret = ci_hdrc_alloc_dma_aligned_buffer(urb, mem_flags);
446	if (ret)
447		return ret;
448
449	ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
450	if (ret)
451		ci_hdrc_free_dma_aligned_buffer(urb, false);
452
453	return ret;
454}
455
456static void ci_hdrc_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
457{
458	usb_hcd_unmap_urb_for_dma(hcd, urb);
459	ci_hdrc_free_dma_aligned_buffer(urb, true);
460}
461
462#ifdef CONFIG_PM_SLEEP
463static void ci_hdrc_host_suspend(struct ci_hdrc *ci)
464{
465	ehci_suspend(ci->hcd, device_may_wakeup(ci->dev));
466}
467
468static void ci_hdrc_host_resume(struct ci_hdrc *ci, bool power_lost)
469{
470	ehci_resume(ci->hcd, power_lost);
471}
472#endif
473
474int ci_hdrc_host_init(struct ci_hdrc *ci)
475{
476	struct ci_role_driver *rdrv;
477
478	if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_HC))
479		return -ENXIO;
480
481	rdrv = devm_kzalloc(ci->dev, sizeof(struct ci_role_driver), GFP_KERNEL);
482	if (!rdrv)
483		return -ENOMEM;
484
485	rdrv->start	= host_start;
486	rdrv->stop	= host_stop;
487#ifdef CONFIG_PM_SLEEP
488	rdrv->suspend	= ci_hdrc_host_suspend;
489	rdrv->resume	= ci_hdrc_host_resume;
490#endif
491	rdrv->irq	= host_irq;
492	rdrv->name	= "host";
493	ci->roles[CI_ROLE_HOST] = rdrv;
494
495	if (ci->platdata->flags & CI_HDRC_REQUIRES_ALIGNED_DMA) {
496		ci_ehci_hc_driver.map_urb_for_dma = ci_hdrc_map_urb_for_dma;
497		ci_ehci_hc_driver.unmap_urb_for_dma = ci_hdrc_unmap_urb_for_dma;
498	}
499
500	return 0;
501}
502
503void ci_hdrc_host_driver_init(void)
504{
505	ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides);
506	orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
507	ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
508	ci_ehci_hc_driver.hub_control = ci_ehci_hub_control;
509}
~/ Read-only file preview.