Lines Matching +full:hird +full:- +full:threshold
1 // SPDX-License-Identifier: GPL-2.0
3 * core.c - DesignWare USB3 DRD Controller Core file
5 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
10 * Taken from Linux Kernel v3.19-rc1 (drivers/usb/dwc3/core.c) and ported
13 * commit cd72f890d2 : usb: dwc3: core: enable phy suspend quirk on non-FPGA
18 #include <dwc3-uboot.h>
19 #include <asm/dma-mapping.h>
22 #include <generic-phy.h>
30 #include "linux-compat.h"
33 /* -------------------------------------------------------------------------- */
39 reg = dwc3_readl(dwc->regs, DWC3_GCTL); in dwc3_set_mode()
42 dwc3_writel(dwc->regs, DWC3_GCTL, reg); in dwc3_set_mode()
46 * dwc3_core_soft_reset - Issues core soft reset and PHY reset
54 reg = dwc3_readl(dwc->regs, DWC3_GCTL); in dwc3_core_soft_reset()
56 dwc3_writel(dwc->regs, DWC3_GCTL, reg); in dwc3_core_soft_reset()
59 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); in dwc3_core_soft_reset()
61 dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); in dwc3_core_soft_reset()
64 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); in dwc3_core_soft_reset()
66 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); in dwc3_core_soft_reset()
71 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); in dwc3_core_soft_reset()
73 dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); in dwc3_core_soft_reset()
76 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); in dwc3_core_soft_reset()
78 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); in dwc3_core_soft_reset()
83 reg = dwc3_readl(dwc->regs, DWC3_GCTL); in dwc3_core_soft_reset()
85 dwc3_writel(dwc->regs, DWC3_GCTL, reg); in dwc3_core_soft_reset()
91 * dwc3_free_one_event_buffer - Frees one event buffer
98 dma_free_coherent(evt->buf); in dwc3_free_one_event_buffer()
102 * dwc3_alloc_one_event_buffer - Allocates one event buffer structure
114 evt = devm_kzalloc((struct udevice *)dwc->dev, sizeof(*evt), in dwc3_alloc_one_event_buffer()
117 return ERR_PTR(-ENOMEM); in dwc3_alloc_one_event_buffer()
119 evt->dwc = dwc; in dwc3_alloc_one_event_buffer()
120 evt->length = length; in dwc3_alloc_one_event_buffer()
121 evt->buf = dma_alloc_coherent(length, in dwc3_alloc_one_event_buffer()
122 (unsigned long *)&evt->dma); in dwc3_alloc_one_event_buffer()
123 if (!evt->buf) in dwc3_alloc_one_event_buffer()
124 return ERR_PTR(-ENOMEM); in dwc3_alloc_one_event_buffer()
126 dwc3_flush_cache((uintptr_t)evt->buf, evt->length); in dwc3_alloc_one_event_buffer()
132 * dwc3_free_event_buffers - frees all allocated event buffers
140 for (i = 0; i < dwc->num_event_buffers; i++) { in dwc3_free_event_buffers()
141 evt = dwc->ev_buffs[i]; in dwc3_free_event_buffers()
148 * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length
160 num = DWC3_NUM_INT(dwc->hwparams.hwparams1); in dwc3_alloc_event_buffers()
161 dwc->num_event_buffers = num; in dwc3_alloc_event_buffers()
163 dwc->ev_buffs = memalign(CONFIG_SYS_CACHELINE_SIZE, in dwc3_alloc_event_buffers()
164 sizeof(*dwc->ev_buffs) * num); in dwc3_alloc_event_buffers()
165 if (!dwc->ev_buffs) in dwc3_alloc_event_buffers()
166 return -ENOMEM; in dwc3_alloc_event_buffers()
173 dev_err(dwc->dev, "can't allocate event buffer\n"); in dwc3_alloc_event_buffers()
176 dwc->ev_buffs[i] = evt; in dwc3_alloc_event_buffers()
183 * dwc3_event_buffers_setup - setup our allocated event buffers
193 for (n = 0; n < dwc->num_event_buffers; n++) { in dwc3_event_buffers_setup()
194 evt = dwc->ev_buffs[n]; in dwc3_event_buffers_setup()
195 dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n", in dwc3_event_buffers_setup()
196 evt->buf, (unsigned long long) evt->dma, in dwc3_event_buffers_setup()
197 evt->length); in dwc3_event_buffers_setup()
199 evt->lpos = 0; in dwc3_event_buffers_setup()
201 dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), in dwc3_event_buffers_setup()
202 lower_32_bits(evt->dma)); in dwc3_event_buffers_setup()
203 dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), in dwc3_event_buffers_setup()
204 upper_32_bits(evt->dma)); in dwc3_event_buffers_setup()
205 dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), in dwc3_event_buffers_setup()
206 DWC3_GEVNTSIZ_SIZE(evt->length)); in dwc3_event_buffers_setup()
207 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0); in dwc3_event_buffers_setup()
218 for (n = 0; n < dwc->num_event_buffers; n++) { in dwc3_event_buffers_cleanup()
219 evt = dwc->ev_buffs[n]; in dwc3_event_buffers_cleanup()
221 evt->lpos = 0; in dwc3_event_buffers_cleanup()
223 dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0); in dwc3_event_buffers_cleanup()
224 dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0); in dwc3_event_buffers_cleanup()
225 dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), DWC3_GEVNTSIZ_INTMASK in dwc3_event_buffers_cleanup()
227 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0); in dwc3_event_buffers_cleanup()
233 if (!dwc->has_hibernation) in dwc3_alloc_scratch_buffers()
236 if (!dwc->nr_scratch) in dwc3_alloc_scratch_buffers()
239 dwc->scratchbuf = kmalloc_array(dwc->nr_scratch, in dwc3_alloc_scratch_buffers()
241 if (!dwc->scratchbuf) in dwc3_alloc_scratch_buffers()
242 return -ENOMEM; in dwc3_alloc_scratch_buffers()
253 if (!dwc->has_hibernation) in dwc3_setup_scratch_buffers()
256 if (!dwc->nr_scratch) in dwc3_setup_scratch_buffers()
259 scratch_addr = dma_map_single(dwc->scratchbuf, in dwc3_setup_scratch_buffers()
260 dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE, in dwc3_setup_scratch_buffers()
262 if (dma_mapping_error(dwc->dev, scratch_addr)) { in dwc3_setup_scratch_buffers()
263 dev_err(dwc->dev, "failed to map scratch buffer\n"); in dwc3_setup_scratch_buffers()
264 ret = -EFAULT; in dwc3_setup_scratch_buffers()
268 dwc->scratch_addr = scratch_addr; in dwc3_setup_scratch_buffers()
287 dma_unmap_single((void *)(uintptr_t)dwc->scratch_addr, dwc->nr_scratch * in dwc3_setup_scratch_buffers()
296 if (!dwc->has_hibernation) in dwc3_free_scratch_buffers()
299 if (!dwc->nr_scratch) in dwc3_free_scratch_buffers()
302 dma_unmap_single((void *)(uintptr_t)dwc->scratch_addr, dwc->nr_scratch * in dwc3_free_scratch_buffers()
304 kfree(dwc->scratchbuf); in dwc3_free_scratch_buffers()
309 struct dwc3_hwparams *parms = &dwc->hwparams; in dwc3_core_num_eps()
311 dwc->num_in_eps = DWC3_NUM_IN_EPS(parms); in dwc3_core_num_eps()
312 dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps; in dwc3_core_num_eps()
314 dev_vdbg(dwc->dev, "found %d IN and %d OUT endpoints\n", in dwc3_core_num_eps()
315 dwc->num_in_eps, dwc->num_out_eps); in dwc3_core_num_eps()
320 struct dwc3_hwparams *parms = &dwc->hwparams; in dwc3_cache_hwparams()
322 parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0); in dwc3_cache_hwparams()
323 parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1); in dwc3_cache_hwparams()
324 parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2); in dwc3_cache_hwparams()
325 parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3); in dwc3_cache_hwparams()
326 parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4); in dwc3_cache_hwparams()
327 parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5); in dwc3_cache_hwparams()
328 parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6); in dwc3_cache_hwparams()
329 parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7); in dwc3_cache_hwparams()
330 parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8); in dwc3_cache_hwparams()
334 * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
341 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); in dwc3_phy_setup()
349 if (dwc->revision > DWC3_REVISION_194A) in dwc3_phy_setup()
352 if (dwc->u2ss_inp3_quirk) in dwc3_phy_setup()
355 if (dwc->req_p1p2p3_quirk) in dwc3_phy_setup()
358 if (dwc->del_p1p2p3_quirk) in dwc3_phy_setup()
361 if (dwc->del_phy_power_chg_quirk) in dwc3_phy_setup()
364 if (dwc->lfps_filter_quirk) in dwc3_phy_setup()
367 if (dwc->rx_detect_poll_quirk) in dwc3_phy_setup()
370 if (dwc->tx_de_emphasis_quirk) in dwc3_phy_setup()
371 reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis); in dwc3_phy_setup()
373 if (dwc->dis_u3_susphy_quirk) in dwc3_phy_setup()
376 dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); in dwc3_phy_setup()
380 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); in dwc3_phy_setup()
388 if (dwc->revision > DWC3_REVISION_194A) in dwc3_phy_setup()
391 if (dwc->dis_u2_susphy_quirk) in dwc3_phy_setup()
394 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); in dwc3_phy_setup()
400 * dwc3_core_init - Low-level initialization of DWC3 Core
408 u32 hwparams4 = dwc->hwparams.hwparams4; in dwc3_core_init()
412 reg = dwc3_readl(dwc->regs, DWC3_GSNPSID); in dwc3_core_init()
415 dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); in dwc3_core_init()
416 ret = -ENODEV; in dwc3_core_init()
419 dwc->revision = reg; in dwc3_core_init()
421 /* Handle USB2.0-only core configuration */ in dwc3_core_init()
422 if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == in dwc3_core_init()
424 if (dwc->maximum_speed == USB_SPEED_SUPER) in dwc3_core_init()
425 dwc->maximum_speed = USB_SPEED_HIGH; in dwc3_core_init()
430 dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); in dwc3_core_init()
431 while (timeout--) { in dwc3_core_init()
432 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_core_init()
438 dev_err(dwc->dev, "Reset Timed Out\n"); in dwc3_core_init()
439 ret = -ETIMEDOUT; in dwc3_core_init()
447 reg = dwc3_readl(dwc->regs, DWC3_GCTL); in dwc3_core_init()
450 switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) { in dwc3_core_init()
461 * STAR#9000588375: Clock Gating, SOF Issues when ref_clk-Based in dwc3_core_init()
464 if ((dwc->dr_mode == USB_DR_MODE_HOST || in dwc3_core_init()
465 dwc->dr_mode == USB_DR_MODE_OTG) && in dwc3_core_init()
466 (dwc->revision >= DWC3_REVISION_210A && in dwc3_core_init()
467 dwc->revision <= DWC3_REVISION_250A)) in dwc3_core_init()
474 dwc->nr_scratch = DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(hwparams4); in dwc3_core_init()
477 * REVISIT Enabling this bit so that host-mode hibernation in dwc3_core_init()
478 * will work. Device-mode hibernation is not yet implemented. in dwc3_core_init()
483 dev_dbg(dwc->dev, "No power optimization available\n"); in dwc3_core_init()
487 if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { in dwc3_core_init()
488 dev_dbg(dwc->dev, "it is on FPGA board\n"); in dwc3_core_init()
489 dwc->is_fpga = true; in dwc3_core_init()
492 if(dwc->disable_scramble_quirk && !dwc->is_fpga) in dwc3_core_init()
494 "disable_scramble cannot be used on non-FPGA builds\n"); in dwc3_core_init()
496 if (dwc->disable_scramble_quirk && dwc->is_fpga) in dwc3_core_init()
501 if (dwc->u2exit_lfps_quirk) in dwc3_core_init()
507 * and falls back to high-speed mode which causes in dwc3_core_init()
510 if (dwc->revision < DWC3_REVISION_190A) in dwc3_core_init()
515 dwc3_writel(dwc->regs, DWC3_GCTL, reg); in dwc3_core_init()
545 switch (dwc->dr_mode) { in dwc3_core_init_mode()
577 dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode); in dwc3_core_init_mode()
578 return -EINVAL; in dwc3_core_init_mode()
586 switch (dwc->dr_mode) { in dwc3_core_exit_mode()
603 #define DWC3_ALIGN_MASK (16 - 1)
606 * dwc3_uboot_init - dwc3 core uboot initialization code
631 return -ENOMEM; in dwc3_uboot_init()
634 dwc->mem = mem; in dwc3_uboot_init()
636 dwc->regs = (void *)(uintptr_t)(dwc3_dev->base + in dwc3_uboot_init()
639 /* default to highest possible threshold */ in dwc3_uboot_init()
642 /* default to -3.5dB de-emphasis */ in dwc3_uboot_init()
646 * default to assert utmi_sleep_n and use maximum allowed HIRD in dwc3_uboot_init()
647 * threshold value of 0b1100 in dwc3_uboot_init()
651 dwc->maximum_speed = dwc3_dev->maximum_speed; in dwc3_uboot_init()
652 dwc->has_lpm_erratum = dwc3_dev->has_lpm_erratum; in dwc3_uboot_init()
653 if (dwc3_dev->lpm_nyet_threshold) in dwc3_uboot_init()
654 lpm_nyet_threshold = dwc3_dev->lpm_nyet_threshold; in dwc3_uboot_init()
655 dwc->is_utmi_l1_suspend = dwc3_dev->is_utmi_l1_suspend; in dwc3_uboot_init()
656 if (dwc3_dev->hird_threshold) in dwc3_uboot_init()
657 hird_threshold = dwc3_dev->hird_threshold; in dwc3_uboot_init()
659 dwc->needs_fifo_resize = dwc3_dev->tx_fifo_resize; in dwc3_uboot_init()
660 dwc->dr_mode = dwc3_dev->dr_mode; in dwc3_uboot_init()
662 dwc->disable_scramble_quirk = dwc3_dev->disable_scramble_quirk; in dwc3_uboot_init()
663 dwc->u2exit_lfps_quirk = dwc3_dev->u2exit_lfps_quirk; in dwc3_uboot_init()
664 dwc->u2ss_inp3_quirk = dwc3_dev->u2ss_inp3_quirk; in dwc3_uboot_init()
665 dwc->req_p1p2p3_quirk = dwc3_dev->req_p1p2p3_quirk; in dwc3_uboot_init()
666 dwc->del_p1p2p3_quirk = dwc3_dev->del_p1p2p3_quirk; in dwc3_uboot_init()
667 dwc->del_phy_power_chg_quirk = dwc3_dev->del_phy_power_chg_quirk; in dwc3_uboot_init()
668 dwc->lfps_filter_quirk = dwc3_dev->lfps_filter_quirk; in dwc3_uboot_init()
669 dwc->rx_detect_poll_quirk = dwc3_dev->rx_detect_poll_quirk; in dwc3_uboot_init()
670 dwc->dis_u3_susphy_quirk = dwc3_dev->dis_u3_susphy_quirk; in dwc3_uboot_init()
671 dwc->dis_u2_susphy_quirk = dwc3_dev->dis_u2_susphy_quirk; in dwc3_uboot_init()
673 dwc->tx_de_emphasis_quirk = dwc3_dev->tx_de_emphasis_quirk; in dwc3_uboot_init()
674 if (dwc3_dev->tx_de_emphasis) in dwc3_uboot_init()
675 tx_de_emphasis = dwc3_dev->tx_de_emphasis; in dwc3_uboot_init()
678 if (dwc->maximum_speed == USB_SPEED_UNKNOWN) in dwc3_uboot_init()
679 dwc->maximum_speed = USB_SPEED_SUPER; in dwc3_uboot_init()
681 dwc->lpm_nyet_threshold = lpm_nyet_threshold; in dwc3_uboot_init()
682 dwc->tx_de_emphasis = tx_de_emphasis; in dwc3_uboot_init()
684 dwc->hird_threshold = hird_threshold in dwc3_uboot_init()
685 | (dwc->is_utmi_l1_suspend << 4); in dwc3_uboot_init()
687 dwc->index = dwc3_dev->index; in dwc3_uboot_init()
693 dev_err(dwc->dev, "failed to allocate event buffers\n"); in dwc3_uboot_init()
694 return -ENOMEM; in dwc3_uboot_init()
698 dwc->dr_mode = USB_DR_MODE_HOST; in dwc3_uboot_init()
700 dwc->dr_mode = USB_DR_MODE_PERIPHERAL; in dwc3_uboot_init()
702 if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) in dwc3_uboot_init()
703 dwc->dr_mode = USB_DR_MODE_OTG; in dwc3_uboot_init()
713 dev_err(dwc->dev, "failed to setup event buffers\n"); in dwc3_uboot_init()
721 list_add_tail(&dwc->list, &dwc3_list); in dwc3_uboot_init()
738 * dwc3_uboot_exit - dwc3 core uboot cleanup code
753 if (dwc->index != index) in dwc3_uboot_exit()
760 list_del(&dwc->list); in dwc3_uboot_exit()
761 kfree(dwc->mem); in dwc3_uboot_exit()
767 * dwc3_uboot_handle_interrupt - handle dwc3 core interrupt
779 if (dwc->index != index) in dwc3_uboot_handle_interrupt()
801 count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); in dwc3_setup_phy()
808 return -ENOMEM; in dwc3_setup_phy()
812 if (ret && ret != -ENOENT) { in dwc3_setup_phy()
814 i, dev->name); in dwc3_setup_phy()
823 i, dev->name); in dwc3_setup_phy()
832 i, dev->name); in dwc3_setup_phy()
842 for (i = count - 1; i >= 0; i--) in dwc3_setup_phy()
851 for (; i >= 0; i--) in dwc3_setup_phy()
869 i, dev->name); in dwc3_shutdown_phy()
886 dev_err(dwc->dev, "failed to allocate event buffers\n"); in dwc3_init()
887 return -ENOMEM; in dwc3_init()
898 dev_err(dwc->dev, "failed to setup event buffers\n"); in dwc3_init()
926 kfree(dwc->mem); in dwc3_remove()