Lines Matching +full:needs +full:- +full:reset +full:- +full:on +full:- +full:resume

1 // SPDX-License-Identifier: GPL-2.0+
3 * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs
6 * Copyright (C) 2009 - 2013 NVIDIA Corporation
10 #include <linux/dma-mapping.h>
21 #include <linux/reset.h>
36 #define DRV_NAME "tegra-ehci"
56 (struct tegra_ehci_hcd *)hcd_to_ehci(hcd)->priv; in tegra_reset_usb_controller()
60 phy_np = of_parse_phandle(pdev->dev.of_node, "nvidia,phy", 0); in tegra_reset_usb_controller()
62 return -ENOENT; in tegra_reset_usb_controller()
66 * global for all the controllers on the chip. Those registers are in tegra_reset_usb_controller()
67 * also cleared when reset is asserted to the 1st controller. in tegra_reset_usb_controller()
69 rst = of_reset_control_get_shared(phy_np, "utmi-pads"); in tegra_reset_usb_controller()
71 dev_warn(&pdev->dev, in tegra_reset_usb_controller()
72 "can't get utmi-pads reset from the PHY\n"); in tegra_reset_usb_controller()
73 dev_warn(&pdev->dev, in tegra_reset_usb_controller()
77 * PHY driver performs UTMI-pads reset in a case of in tegra_reset_usb_controller()
78 * non-legacy DT. in tegra_reset_usb_controller()
85 /* reset control is shared, hence initialize it first */ in tegra_reset_usb_controller()
86 err = reset_control_deassert(tegra->rst); in tegra_reset_usb_controller()
90 err = reset_control_assert(tegra->rst); in tegra_reset_usb_controller()
96 err = reset_control_deassert(tegra->rst); in tegra_reset_usb_controller()
114 spin_lock_irqsave(&ehci->lock, flags); in tegra_ehci_internal_port_reset()
115 saved_usbintr = ehci_readl(ehci, &ehci->regs->intr_enable); in tegra_ehci_internal_port_reset()
117 ehci_writel(ehci, 0, &ehci->regs->intr_enable); in tegra_ehci_internal_port_reset()
118 spin_unlock_irqrestore(&ehci->lock, flags); in tegra_ehci_internal_port_reset()
121 * Here we have to do Port Reset at most twice for in tegra_ehci_internal_port_reset()
142 } while (!(temp & PORT_PE) && tries--); in tegra_ehci_internal_port_reset()
147 retval = -ETIMEDOUT; in tegra_ehci_internal_port_reset()
158 * during port reset. in tegra_ehci_internal_port_reset()
160 temp = ehci_readl(ehci, &ehci->regs->status); in tegra_ehci_internal_port_reset()
161 ehci_writel(ehci, temp, &ehci->regs->status); in tegra_ehci_internal_port_reset()
164 ehci_writel(ehci, saved_usbintr, &ehci->regs->intr_enable); in tegra_ehci_internal_port_reset()
178 struct tegra_ehci_hcd *tegra = (struct tegra_ehci_hcd *)ehci->priv; in tegra_ehci_hub_control()
184 status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; in tegra_ehci_hub_control()
186 spin_lock_irqsave(&ehci->lock, flags); in tegra_ehci_hub_control()
190 if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { in tegra_ehci_hub_control()
191 /* Resume completed, re-enable disconnect detection */ in tegra_ehci_hub_control()
192 tegra->port_resuming = 0; in tegra_ehci_hub_control()
193 tegra_usb_phy_postresume(hcd->usb_phy); in tegra_ehci_hub_control()
200 retval = -EPIPE; in tegra_ehci_hub_control()
216 set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); in tegra_ehci_hub_control()
220 /* For USB1 port we need to issue Port Reset twice internally */ in tegra_ehci_hub_control()
221 if (tegra->needs_double_reset && in tegra_ehci_hub_control()
223 spin_unlock_irqrestore(&ehci->lock, flags); in tegra_ehci_hub_control()
228 * Tegra host controller will time the resume operation to clear the bit in tegra_ehci_hub_control()
231 * to set this bit to a zero after the resume duration is timed in the in tegra_ehci_hub_control()
238 retval = -EPIPE; in tegra_ehci_hub_control()
245 /* Disable disconnect detection during port resume */ in tegra_ehci_hub_control()
246 tegra_usb_phy_preresume(hcd->usb_phy); in tegra_ehci_hub_control()
248 ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25); in tegra_ehci_hub_control()
251 /* start resume signalling */ in tegra_ehci_hub_control()
253 set_bit(wIndex-1, &ehci->resuming_ports); in tegra_ehci_hub_control()
255 spin_unlock_irqrestore(&ehci->lock, flags); in tegra_ehci_hub_control()
257 spin_lock_irqsave(&ehci->lock, flags); in tegra_ehci_hub_control()
259 /* Poll until the controller clears RESUME and SUSPEND */ in tegra_ehci_hub_control()
261 pr_err("%s: timeout waiting for RESUME\n", __func__); in tegra_ehci_hub_control()
265 ehci->reset_done[wIndex-1] = 0; in tegra_ehci_hub_control()
266 clear_bit(wIndex-1, &ehci->resuming_ports); in tegra_ehci_hub_control()
268 tegra->port_resuming = 1; in tegra_ehci_hub_control()
272 spin_unlock_irqrestore(&ehci->lock, flags); in tegra_ehci_hub_control()
278 spin_unlock_irqrestore(&ehci->lock, flags); in tegra_ehci_hub_control()
293 if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) in free_dma_aligned_buffer()
296 temp = container_of(urb->transfer_buffer, in free_dma_aligned_buffer()
300 if (usb_pipeisoc(urb->pipe)) in free_dma_aligned_buffer()
301 length = urb->transfer_buffer_length; in free_dma_aligned_buffer()
303 length = urb->actual_length; in free_dma_aligned_buffer()
305 memcpy(temp->old_xfer_buffer, temp->data, length); in free_dma_aligned_buffer()
307 urb->transfer_buffer = temp->old_xfer_buffer; in free_dma_aligned_buffer()
308 kfree(temp->kmalloc_ptr); in free_dma_aligned_buffer()
310 urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; in free_dma_aligned_buffer()
318 if (urb->num_sgs || urb->sg || in alloc_dma_aligned_buffer()
319 urb->transfer_buffer_length == 0 || in alloc_dma_aligned_buffer()
320 !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1))) in alloc_dma_aligned_buffer()
324 kmalloc_size = urb->transfer_buffer_length + in alloc_dma_aligned_buffer()
325 sizeof(struct dma_aligned_buffer) + TEGRA_USB_DMA_ALIGN - 1; in alloc_dma_aligned_buffer()
329 return -ENOMEM; in alloc_dma_aligned_buffer()
332 temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1; in alloc_dma_aligned_buffer()
333 temp->kmalloc_ptr = kmalloc_ptr; in alloc_dma_aligned_buffer()
334 temp->old_xfer_buffer = urb->transfer_buffer; in alloc_dma_aligned_buffer()
336 memcpy(temp->data, urb->transfer_buffer, in alloc_dma_aligned_buffer()
337 urb->transfer_buffer_length); in alloc_dma_aligned_buffer()
338 urb->transfer_buffer = temp->data; in alloc_dma_aligned_buffer()
340 urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER; in alloc_dma_aligned_buffer()
376 { .compatible = "nvidia,tegra30-ehci", .data = &tegra30_soc_config },
377 { .compatible = "nvidia,tegra20-ehci", .data = &tegra20_soc_config },
393 match = of_match_device(tegra_ehci_of_match, &pdev->dev); in tegra_ehci_probe()
395 dev_err(&pdev->dev, "Error: No device match found\n"); in tegra_ehci_probe()
396 return -ENODEV; in tegra_ehci_probe()
398 soc_config = match->data; in tegra_ehci_probe()
400 /* Right now device-tree probed devices don't get dma_mask set. in tegra_ehci_probe()
401 * Since shared usb code relies on it, set it here for now. in tegra_ehci_probe()
404 err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); in tegra_ehci_probe()
408 hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev, in tegra_ehci_probe()
409 dev_name(&pdev->dev)); in tegra_ehci_probe()
411 dev_err(&pdev->dev, "Unable to create HCD\n"); in tegra_ehci_probe()
412 return -ENOMEM; in tegra_ehci_probe()
416 tegra = (struct tegra_ehci_hcd *)ehci->priv; in tegra_ehci_probe()
418 hcd->has_tt = 1; in tegra_ehci_probe()
420 tegra->clk = devm_clk_get(&pdev->dev, NULL); in tegra_ehci_probe()
421 if (IS_ERR(tegra->clk)) { in tegra_ehci_probe()
422 dev_err(&pdev->dev, "Can't get ehci clock\n"); in tegra_ehci_probe()
423 err = PTR_ERR(tegra->clk); in tegra_ehci_probe()
427 tegra->rst = devm_reset_control_get_shared(&pdev->dev, "usb"); in tegra_ehci_probe()
428 if (IS_ERR(tegra->rst)) { in tegra_ehci_probe()
429 dev_err(&pdev->dev, "Can't get ehci reset\n"); in tegra_ehci_probe()
430 err = PTR_ERR(tegra->rst); in tegra_ehci_probe()
434 err = clk_prepare_enable(tegra->clk); in tegra_ehci_probe()
440 dev_err(&pdev->dev, "Failed to reset controller\n"); in tegra_ehci_probe()
444 u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); in tegra_ehci_probe()
446 err = -EPROBE_DEFER; in tegra_ehci_probe()
449 hcd->usb_phy = u_phy; in tegra_ehci_probe()
450 hcd->skip_phy_initialization = 1; in tegra_ehci_probe()
452 tegra->needs_double_reset = of_property_read_bool(pdev->dev.of_node, in tegra_ehci_probe()
453 "nvidia,needs-double-reset"); in tegra_ehci_probe()
456 hcd->regs = devm_ioremap_resource(&pdev->dev, res); in tegra_ehci_probe()
457 if (IS_ERR(hcd->regs)) { in tegra_ehci_probe()
458 err = PTR_ERR(hcd->regs); in tegra_ehci_probe()
461 hcd->rsrc_start = res->start; in tegra_ehci_probe()
462 hcd->rsrc_len = resource_size(res); in tegra_ehci_probe()
464 ehci->caps = hcd->regs + 0x100; in tegra_ehci_probe()
465 ehci->has_hostpc = soc_config->has_hostpc; in tegra_ehci_probe()
467 err = usb_phy_init(hcd->usb_phy); in tegra_ehci_probe()
469 dev_err(&pdev->dev, "Failed to initialize phy\n"); in tegra_ehci_probe()
473 u_phy->otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), in tegra_ehci_probe()
475 if (!u_phy->otg) { in tegra_ehci_probe()
476 err = -ENOMEM; in tegra_ehci_probe()
479 u_phy->otg->host = hcd_to_bus(hcd); in tegra_ehci_probe()
487 otg_set_host(u_phy->otg, &hcd->self); in tegra_ehci_probe()
491 dev_err(&pdev->dev, "Failed to add USB HCD\n"); in tegra_ehci_probe()
494 device_wakeup_enable(hcd->self.controller); in tegra_ehci_probe()
499 otg_set_host(u_phy->otg, NULL); in tegra_ehci_probe()
501 usb_phy_shutdown(hcd->usb_phy); in tegra_ehci_probe()
503 clk_disable_unprepare(tegra->clk); in tegra_ehci_probe()
513 (struct tegra_ehci_hcd *)hcd_to_ehci(hcd)->priv; in tegra_ehci_remove()
516 otg_set_host(hcd->usb_phy->otg, NULL); in tegra_ehci_remove()
517 usb_phy_shutdown(hcd->usb_phy); in tegra_ehci_remove()
518 clk_disable_unprepare(tegra->clk); in tegra_ehci_remove()
528 if (hcd->driver->shutdown) in tegra_ehci_hcd_shutdown()
529 hcd->driver->shutdown(hcd); in tegra_ehci_hcd_shutdown()
555 * the only one so far that needs a value of 10, and Tegra20 is the in tegra_ehci_reset()
558 txfifothresh = ehci->has_hostpc ? 0x10 : 10; in tegra_ehci_reset()
559 ehci_writel(ehci, txfifothresh << 16, &ehci->regs->txfill_tuning); in tegra_ehci_reset()
566 .reset = tegra_ehci_reset,
572 return -ENODEV; in ehci_tegra_init()
579 * The Tegra HW has some unusual quirks, which require Tegra-specific in ehci_tegra_init()