Lines Matching +full:mtk +full:- +full:xhci
1 // SPDX-License-Identifier: GPL-2.0
3 * MediaTek xHCI Host Controller Driver
11 #include <linux/dma-mapping.h>
24 #include "xhci.h"
25 #include "xhci-mtk.h"
61 /* xHCI CSR */
139 static void xhci_mtk_set_frame_interval(struct xhci_hcd_mtk *mtk) in xhci_mtk_set_frame_interval() argument
141 struct device *dev = mtk->dev; in xhci_mtk_set_frame_interval()
142 struct usb_hcd *hcd = mtk->hcd; in xhci_mtk_set_frame_interval()
145 if (!of_device_is_compatible(dev->of_node, "mediatek,mt8195-xhci")) in xhci_mtk_set_frame_interval()
148 value = readl(hcd->regs + HFCNTR_CFG); in xhci_mtk_set_frame_interval()
151 writel(value, hcd->regs + HFCNTR_CFG); in xhci_mtk_set_frame_interval()
153 value = readl(hcd->regs + LS_EOF_CFG); in xhci_mtk_set_frame_interval()
156 writel(value, hcd->regs + LS_EOF_CFG); in xhci_mtk_set_frame_interval()
158 value = readl(hcd->regs + FS_EOF_CFG); in xhci_mtk_set_frame_interval()
161 writel(value, hcd->regs + FS_EOF_CFG); in xhci_mtk_set_frame_interval()
163 value = readl(hcd->regs + SS_GEN1_EOF_CFG); in xhci_mtk_set_frame_interval()
166 writel(value, hcd->regs + SS_GEN1_EOF_CFG); in xhci_mtk_set_frame_interval()
168 value = readl(hcd->regs + SS_GEN2_EOF_CFG); in xhci_mtk_set_frame_interval()
171 writel(value, hcd->regs + SS_GEN2_EOF_CFG); in xhci_mtk_set_frame_interval()
179 static void xhci_mtk_rxfifo_depth_set(struct xhci_hcd_mtk *mtk) in xhci_mtk_rxfifo_depth_set() argument
181 struct usb_hcd *hcd = mtk->hcd; in xhci_mtk_rxfifo_depth_set()
184 if (!mtk->rxfifo_depth) in xhci_mtk_rxfifo_depth_set()
187 value = readl(hcd->regs + HSCH_CFG1); in xhci_mtk_rxfifo_depth_set()
190 SCH_FIFO_TO_KB(mtk->rxfifo_depth) - 1); in xhci_mtk_rxfifo_depth_set()
191 writel(value, hcd->regs + HSCH_CFG1); in xhci_mtk_rxfifo_depth_set()
194 static void xhci_mtk_init_quirk(struct xhci_hcd_mtk *mtk) in xhci_mtk_init_quirk() argument
197 xhci_mtk_set_frame_interval(mtk); in xhci_mtk_init_quirk()
200 xhci_mtk_rxfifo_depth_set(mtk); in xhci_mtk_init_quirk()
203 static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) in xhci_mtk_host_enable() argument
205 struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; in xhci_mtk_host_enable()
211 if (!mtk->has_ippc) in xhci_mtk_host_enable()
215 value = readl(&ippc->ip_pw_ctr1); in xhci_mtk_host_enable()
217 writel(value, &ippc->ip_pw_ctr1); in xhci_mtk_host_enable()
220 for (i = 0; i < mtk->num_u3_ports; i++) { in xhci_mtk_host_enable()
221 if ((0x1 << i) & mtk->u3p_dis_msk) { in xhci_mtk_host_enable()
226 value = readl(&ippc->u3_ctrl_p[i]); in xhci_mtk_host_enable()
229 writel(value, &ippc->u3_ctrl_p[i]); in xhci_mtk_host_enable()
233 for (i = 0; i < mtk->num_u2_ports; i++) { in xhci_mtk_host_enable()
234 if (BIT(i) & mtk->u2p_dis_msk) in xhci_mtk_host_enable()
237 value = readl(&ippc->u2_ctrl_p[i]); in xhci_mtk_host_enable()
240 writel(value, &ippc->u2_ctrl_p[i]); in xhci_mtk_host_enable()
250 if (mtk->num_u3_ports > u3_ports_disabled) in xhci_mtk_host_enable()
253 ret = readl_poll_timeout(&ippc->ip_pw_sts1, value, in xhci_mtk_host_enable()
256 dev_err(mtk->dev, "clocks are not stable (0x%x)\n", value); in xhci_mtk_host_enable()
263 static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk) in xhci_mtk_host_disable() argument
265 struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; in xhci_mtk_host_disable()
270 if (!mtk->has_ippc) in xhci_mtk_host_disable()
274 for (i = 0; i < mtk->num_u3_ports; i++) { in xhci_mtk_host_disable()
275 if ((0x1 << i) & mtk->u3p_dis_msk) in xhci_mtk_host_disable()
278 value = readl(&ippc->u3_ctrl_p[i]); in xhci_mtk_host_disable()
280 writel(value, &ippc->u3_ctrl_p[i]); in xhci_mtk_host_disable()
284 for (i = 0; i < mtk->num_u2_ports; i++) { in xhci_mtk_host_disable()
285 if (BIT(i) & mtk->u2p_dis_msk) in xhci_mtk_host_disable()
288 value = readl(&ippc->u2_ctrl_p[i]); in xhci_mtk_host_disable()
290 writel(value, &ippc->u2_ctrl_p[i]); in xhci_mtk_host_disable()
294 value = readl(&ippc->ip_pw_ctr1); in xhci_mtk_host_disable()
296 writel(value, &ippc->ip_pw_ctr1); in xhci_mtk_host_disable()
299 ret = readl_poll_timeout(&ippc->ip_pw_sts1, value, in xhci_mtk_host_disable()
302 dev_err(mtk->dev, "ip sleep failed!!!\n"); in xhci_mtk_host_disable()
309 static int xhci_mtk_ssusb_config(struct xhci_hcd_mtk *mtk) in xhci_mtk_ssusb_config() argument
311 struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; in xhci_mtk_ssusb_config()
314 if (!mtk->has_ippc) in xhci_mtk_ssusb_config()
318 value = readl(&ippc->ip_pw_ctr0); in xhci_mtk_ssusb_config()
320 writel(value, &ippc->ip_pw_ctr0); in xhci_mtk_ssusb_config()
322 value = readl(&ippc->ip_pw_ctr0); in xhci_mtk_ssusb_config()
324 writel(value, &ippc->ip_pw_ctr0); in xhci_mtk_ssusb_config()
327 * device ip is default power-on in fact in xhci_mtk_ssusb_config()
328 * power down device ip, otherwise ip-sleep will fail in xhci_mtk_ssusb_config()
330 value = readl(&ippc->ip_pw_ctr2); in xhci_mtk_ssusb_config()
332 writel(value, &ippc->ip_pw_ctr2); in xhci_mtk_ssusb_config()
334 value = readl(&ippc->ip_xhci_cap); in xhci_mtk_ssusb_config()
335 mtk->num_u3_ports = CAP_U3_PORT_NUM(value); in xhci_mtk_ssusb_config()
336 mtk->num_u2_ports = CAP_U2_PORT_NUM(value); in xhci_mtk_ssusb_config()
337 dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n", __func__, in xhci_mtk_ssusb_config()
338 mtk->num_u2_ports, mtk->num_u3_ports); in xhci_mtk_ssusb_config()
340 return xhci_mtk_host_enable(mtk); in xhci_mtk_ssusb_config()
343 /* only clocks can be turn off for ip-sleep wakeup mode */
344 static void usb_wakeup_ip_sleep_set(struct xhci_hcd_mtk *mtk, bool enable) in usb_wakeup_ip_sleep_set() argument
348 switch (mtk->uwk_vers) { in usb_wakeup_ip_sleep_set()
350 reg = mtk->uwk_reg_base + PERI_WK_CTRL1; in usb_wakeup_ip_sleep_set()
355 reg = mtk->uwk_reg_base + PERI_WK_CTRL0; in usb_wakeup_ip_sleep_set()
360 reg = mtk->uwk_reg_base + PERI_WK_CTRL0; in usb_wakeup_ip_sleep_set()
365 reg = mtk->uwk_reg_base + PERI_WK_CTRL1_8195; in usb_wakeup_ip_sleep_set()
370 reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8195; in usb_wakeup_ip_sleep_set()
375 reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8195; in usb_wakeup_ip_sleep_set()
380 reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8195; in usb_wakeup_ip_sleep_set()
385 reg = mtk->uwk_reg_base + PERI_SSUSB_SPM_CTRL; in usb_wakeup_ip_sleep_set()
392 regmap_update_bits(mtk->uwk, reg, msk, val); in usb_wakeup_ip_sleep_set()
395 static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk, in usb_wakeup_of_property_parse() argument
402 mtk->uwk_en = of_property_read_bool(dn, "wakeup-source"); in usb_wakeup_of_property_parse()
403 if (!mtk->uwk_en) in usb_wakeup_of_property_parse()
407 "mediatek,syscon-wakeup", 2, 0, &args); in usb_wakeup_of_property_parse()
411 mtk->uwk_reg_base = args.args[0]; in usb_wakeup_of_property_parse()
412 mtk->uwk_vers = args.args[1]; in usb_wakeup_of_property_parse()
413 mtk->uwk = syscon_node_to_regmap(args.np); in usb_wakeup_of_property_parse()
415 dev_info(mtk->dev, "uwk - reg:0x%x, version:%d\n", in usb_wakeup_of_property_parse()
416 mtk->uwk_reg_base, mtk->uwk_vers); in usb_wakeup_of_property_parse()
418 return PTR_ERR_OR_ZERO(mtk->uwk); in usb_wakeup_of_property_parse()
421 static void usb_wakeup_set(struct xhci_hcd_mtk *mtk, bool enable) in usb_wakeup_set() argument
423 if (mtk->uwk_en) in usb_wakeup_set()
424 usb_wakeup_ip_sleep_set(mtk, enable); in usb_wakeup_set()
427 static int xhci_mtk_clks_get(struct xhci_hcd_mtk *mtk) in xhci_mtk_clks_get() argument
429 struct clk_bulk_data *clks = mtk->clks; in xhci_mtk_clks_get()
438 return devm_clk_bulk_get_optional(mtk->dev, BULK_CLKS_NUM, clks); in xhci_mtk_clks_get()
441 static int xhci_mtk_vregs_get(struct xhci_hcd_mtk *mtk) in xhci_mtk_vregs_get() argument
443 struct regulator_bulk_data *supplies = mtk->supplies; in xhci_mtk_vregs_get()
448 return devm_regulator_bulk_get(mtk->dev, BULK_VREGS_NUM, supplies); in xhci_mtk_vregs_get()
451 static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci) in xhci_mtk_quirks() argument
453 struct usb_hcd *hcd = xhci_to_hcd(xhci); in xhci_mtk_quirks()
454 struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); in xhci_mtk_quirks() local
456 xhci->quirks |= XHCI_MTK_HOST; in xhci_mtk_quirks()
458 * MTK host controller gives a spurious successful event after a in xhci_mtk_quirks()
461 xhci->quirks |= XHCI_SPURIOUS_SUCCESS; in xhci_mtk_quirks()
462 if (mtk->lpm_support) in xhci_mtk_quirks()
463 xhci->quirks |= XHCI_LPM_SUPPORT; in xhci_mtk_quirks()
464 if (mtk->u2_lpm_disable) in xhci_mtk_quirks()
465 xhci->quirks |= XHCI_HW_LPM_DISABLE; in xhci_mtk_quirks()
468 * MTK xHCI 0.96: PSA is 1 by default even if doesn't support stream, in xhci_mtk_quirks()
471 if (xhci->hci_version < 0x100 && HCC_MAX_PSA(xhci->hcc_params) == 4) in xhci_mtk_quirks()
472 xhci->quirks |= XHCI_BROKEN_STREAMS; in xhci_mtk_quirks()
478 struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); in xhci_mtk_setup() local
482 ret = xhci_mtk_ssusb_config(mtk); in xhci_mtk_setup()
486 xhci_mtk_init_quirk(mtk); in xhci_mtk_setup()
494 ret = xhci_mtk_sch_init(mtk); in xhci_mtk_setup()
511 struct device *dev = &pdev->dev; in xhci_mtk_probe()
512 struct device_node *node = dev->of_node; in xhci_mtk_probe()
513 struct xhci_hcd_mtk *mtk; in xhci_mtk_probe() local
515 struct xhci_hcd *xhci; in xhci_mtk_probe() local
519 int ret = -ENODEV; in xhci_mtk_probe()
524 return -ENODEV; in xhci_mtk_probe()
527 mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL); in xhci_mtk_probe()
528 if (!mtk) in xhci_mtk_probe()
529 return -ENOMEM; in xhci_mtk_probe()
531 mtk->dev = dev; in xhci_mtk_probe()
533 ret = xhci_mtk_vregs_get(mtk); in xhci_mtk_probe()
537 ret = xhci_mtk_clks_get(mtk); in xhci_mtk_probe()
543 if (irq == -EPROBE_DEFER) in xhci_mtk_probe()
553 if (wakeup_irq == -EPROBE_DEFER) in xhci_mtk_probe()
556 mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable"); in xhci_mtk_probe()
557 mtk->u2_lpm_disable = of_property_read_bool(node, "usb2-lpm-disable"); in xhci_mtk_probe()
559 of_property_read_u32(node, "mediatek,u3p-dis-msk", in xhci_mtk_probe()
560 &mtk->u3p_dis_msk); in xhci_mtk_probe()
561 of_property_read_u32(node, "mediatek,u2p-dis-msk", in xhci_mtk_probe()
562 &mtk->u2p_dis_msk); in xhci_mtk_probe()
564 of_property_read_u32(node, "rx-fifo-depth", &mtk->rxfifo_depth); in xhci_mtk_probe()
566 ret = usb_wakeup_of_property_parse(mtk, node); in xhci_mtk_probe()
578 ret = regulator_bulk_enable(BULK_VREGS_NUM, mtk->supplies); in xhci_mtk_probe()
582 ret = clk_bulk_prepare_enable(BULK_CLKS_NUM, mtk->clks); in xhci_mtk_probe()
594 ret = -ENOMEM; in xhci_mtk_probe()
600 * Swap it with mtk HCD. in xhci_mtk_probe()
602 mtk->hcd = platform_get_drvdata(pdev); in xhci_mtk_probe()
603 platform_set_drvdata(pdev, mtk); in xhci_mtk_probe()
606 hcd->regs = devm_ioremap_resource(dev, res); in xhci_mtk_probe()
607 if (IS_ERR(hcd->regs)) { in xhci_mtk_probe()
608 ret = PTR_ERR(hcd->regs); in xhci_mtk_probe()
611 hcd->rsrc_start = res->start; in xhci_mtk_probe()
612 hcd->rsrc_len = resource_size(res); in xhci_mtk_probe()
616 mtk->ippc_regs = devm_ioremap_resource(dev, res); in xhci_mtk_probe()
617 if (IS_ERR(mtk->ippc_regs)) { in xhci_mtk_probe()
618 ret = PTR_ERR(mtk->ippc_regs); in xhci_mtk_probe()
621 mtk->has_ippc = true; in xhci_mtk_probe()
627 xhci = hcd_to_xhci(hcd); in xhci_mtk_probe()
628 xhci->main_hcd = hcd; in xhci_mtk_probe()
629 xhci->allow_single_roothub = 1; in xhci_mtk_probe()
634 * the xHCI spec on MTK's controller. in xhci_mtk_probe()
636 xhci->imod_interval = 5000; in xhci_mtk_probe()
637 device_property_read_u32(dev, "imod-interval-ns", &xhci->imod_interval); in xhci_mtk_probe()
643 if (!xhci_has_one_roothub(xhci)) { in xhci_mtk_probe()
644 xhci->shared_hcd = usb_create_shared_hcd(driver, dev, in xhci_mtk_probe()
646 if (!xhci->shared_hcd) { in xhci_mtk_probe()
647 ret = -ENOMEM; in xhci_mtk_probe()
652 usb3_hcd = xhci_get_usb3_hcd(xhci); in xhci_mtk_probe()
653 if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4 && in xhci_mtk_probe()
654 !(xhci->quirks & XHCI_BROKEN_STREAMS)) in xhci_mtk_probe()
655 usb3_hcd->can_do_streams = 1; in xhci_mtk_probe()
657 if (xhci->shared_hcd) { in xhci_mtk_probe()
658 ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); in xhci_mtk_probe()
680 usb_remove_hcd(xhci->shared_hcd); in xhci_mtk_probe()
683 usb_put_hcd(xhci->shared_hcd); in xhci_mtk_probe()
686 xhci_mtk_sch_exit(mtk); in xhci_mtk_probe()
696 clk_bulk_disable_unprepare(BULK_CLKS_NUM, mtk->clks); in xhci_mtk_probe()
699 regulator_bulk_disable(BULK_VREGS_NUM, mtk->supplies); in xhci_mtk_probe()
709 struct xhci_hcd_mtk *mtk = platform_get_drvdata(pdev); in xhci_mtk_remove() local
710 struct usb_hcd *hcd = mtk->hcd; in xhci_mtk_remove()
711 struct xhci_hcd *xhci = hcd_to_xhci(hcd); in xhci_mtk_remove() local
712 struct usb_hcd *shared_hcd = xhci->shared_hcd; in xhci_mtk_remove()
713 struct device *dev = &pdev->dev; in xhci_mtk_remove()
716 xhci->xhc_state |= XHCI_STATE_REMOVING; in xhci_mtk_remove()
722 xhci->shared_hcd = NULL; in xhci_mtk_remove()
730 xhci_mtk_sch_exit(mtk); in xhci_mtk_remove()
731 clk_bulk_disable_unprepare(BULK_CLKS_NUM, mtk->clks); in xhci_mtk_remove()
732 regulator_bulk_disable(BULK_VREGS_NUM, mtk->supplies); in xhci_mtk_remove()
741 struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); in xhci_mtk_suspend() local
742 struct usb_hcd *hcd = mtk->hcd; in xhci_mtk_suspend()
743 struct xhci_hcd *xhci = hcd_to_xhci(hcd); in xhci_mtk_suspend() local
744 struct usb_hcd *shared_hcd = xhci->shared_hcd; in xhci_mtk_suspend()
747 xhci_dbg(xhci, "%s: stop port polling\n", __func__); in xhci_mtk_suspend()
748 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); in xhci_mtk_suspend()
749 del_timer_sync(&hcd->rh_timer); in xhci_mtk_suspend()
751 clear_bit(HCD_FLAG_POLL_RH, &shared_hcd->flags); in xhci_mtk_suspend()
752 del_timer_sync(&shared_hcd->rh_timer); in xhci_mtk_suspend()
755 ret = xhci_mtk_host_disable(mtk); in xhci_mtk_suspend()
759 clk_bulk_disable_unprepare(BULK_CLKS_NUM, mtk->clks); in xhci_mtk_suspend()
760 usb_wakeup_set(mtk, true); in xhci_mtk_suspend()
764 xhci_dbg(xhci, "%s: restart port polling\n", __func__); in xhci_mtk_suspend()
766 set_bit(HCD_FLAG_POLL_RH, &shared_hcd->flags); in xhci_mtk_suspend()
769 set_bit(HCD_FLAG_POLL_RH, &hcd->flags); in xhci_mtk_suspend()
776 struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); in xhci_mtk_resume() local
777 struct usb_hcd *hcd = mtk->hcd; in xhci_mtk_resume()
778 struct xhci_hcd *xhci = hcd_to_xhci(hcd); in xhci_mtk_resume() local
779 struct usb_hcd *shared_hcd = xhci->shared_hcd; in xhci_mtk_resume()
782 usb_wakeup_set(mtk, false); in xhci_mtk_resume()
783 ret = clk_bulk_prepare_enable(BULK_CLKS_NUM, mtk->clks); in xhci_mtk_resume()
787 ret = xhci_mtk_host_enable(mtk); in xhci_mtk_resume()
791 xhci_dbg(xhci, "%s: restart port polling\n", __func__); in xhci_mtk_resume()
793 set_bit(HCD_FLAG_POLL_RH, &shared_hcd->flags); in xhci_mtk_resume()
796 set_bit(HCD_FLAG_POLL_RH, &hcd->flags); in xhci_mtk_resume()
801 clk_bulk_disable_unprepare(BULK_CLKS_NUM, mtk->clks); in xhci_mtk_resume()
803 usb_wakeup_set(mtk, true); in xhci_mtk_resume()
809 struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); in xhci_mtk_runtime_suspend() local
810 struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); in xhci_mtk_runtime_suspend() local
813 if (xhci->xhc_state) in xhci_mtk_runtime_suspend()
814 return -ESHUTDOWN; in xhci_mtk_runtime_suspend()
819 /* -EBUSY: let PM automatically reschedule another autosuspend */ in xhci_mtk_runtime_suspend()
820 return ret ? -EBUSY : 0; in xhci_mtk_runtime_suspend()
825 struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); in xhci_mtk_runtime_resume() local
826 struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); in xhci_mtk_runtime_resume() local
829 if (xhci->xhc_state) in xhci_mtk_runtime_resume()
830 return -ESHUTDOWN; in xhci_mtk_runtime_resume()
847 { .compatible = "mediatek,mt8173-xhci"},
848 { .compatible = "mediatek,mt8195-xhci"},
849 { .compatible = "mediatek,mtk-xhci"},
858 .name = "xhci-mtk",
878 MODULE_DESCRIPTION("MediaTek xHCI Host Controller Driver");