Lines Matching +full:usb2 +full:- +full:device +full:- +full:4
1 // SPDX-License-Identifier: GPL-2.0
11 * - Control registers for each USB2 Ports
12 * - Control registers for the USB PHY layer
13 * - SuperSpeed PHY can be enabled only if port is used
14 * - Dynamic OTG switching with ID change interrupt
33 /* USB2 Ports Control Registers, offsets are per-port */
42 #define U2P_R0_ID_PULLUP BIT(4)
65 #define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK GENMASK(4, 2)
81 #define USB_R3_P30_SSC_REF_CLK_SEL_MASK GENMASK(12, 4)
88 #define USB_R4_P21_ONLY BIT(4)
94 #define USB_R5_ID_DIG_EN_0 BIT(4)
120 "usb2-phy0", "usb2-phy1", "usb2-phy2",
124 "usb2-phy0", "usb2-phy1", "usb3-phy0",
133 * correctly when only the "usb2-phy1" phy is specified on-par with the
137 "usb2-phy0", "usb2-phy1"
180 * USB Phy muxing between the DWC2 Device controller and the DWC3 Host
181 * controller is buggy when switching from Device to Host when USB port
185 * In order to still switch from Host to Device on an USB Type-A port,
257 struct device *dev;
275 return phy_set_mode(priv->phys[i], mode); in dwc3_meson_gxl_set_phy_mode()
281 /* On GXL PHY must be started in device mode for DWC2 init */ in dwc3_meson_gxl_usb2_init_phy()
282 return priv->drvdata->set_phy_mode(priv, i, in dwc3_meson_gxl_usb2_init_phy()
291 regmap_update_bits(priv->u2p_regmap[i], U2P_R0, in dwc3_meson_g12a_set_phy_mode()
295 regmap_update_bits(priv->u2p_regmap[i], U2P_R0, in dwc3_meson_g12a_set_phy_mode()
306 regmap_update_bits(priv->u2p_regmap[i], U2P_R0, in dwc3_meson_g12a_usb2_init_phy()
310 if (priv->drvdata->otg_switch_supported && i == USB2_OTG_PHY) { in dwc3_meson_g12a_usb2_init_phy()
311 regmap_update_bits(priv->u2p_regmap[i], U2P_R0, in dwc3_meson_g12a_usb2_init_phy()
315 ret = priv->drvdata->set_phy_mode(priv, i, mode); in dwc3_meson_g12a_usb2_init_phy()
317 ret = priv->drvdata->set_phy_mode(priv, i, in dwc3_meson_g12a_usb2_init_phy()
323 regmap_update_bits(priv->u2p_regmap[i], U2P_R0, in dwc3_meson_g12a_usb2_init_phy()
334 for (i = 0; i < priv->drvdata->num_phys; ++i) { in dwc3_meson_g12a_usb2_init()
335 if (!priv->phys[i]) in dwc3_meson_g12a_usb2_init()
338 if (!strstr(priv->drvdata->phy_names[i], "usb2")) in dwc3_meson_g12a_usb2_init()
341 ret = priv->drvdata->usb2_init_phy(priv, i, mode); in dwc3_meson_g12a_usb2_init()
351 regmap_update_bits(priv->usb_glue_regmap, USB_R3, in dwc3_meson_g12a_usb3_init()
359 regmap_update_bits(priv->usb_glue_regmap, USB_R2, in dwc3_meson_g12a_usb3_init()
363 regmap_update_bits(priv->usb_glue_regmap, USB_R2, in dwc3_meson_g12a_usb3_init()
369 regmap_update_bits(priv->usb_glue_regmap, USB_R1, in dwc3_meson_g12a_usb3_init()
373 regmap_update_bits(priv->usb_glue_regmap, USB_R1, in dwc3_meson_g12a_usb3_init()
382 if (priv->otg_mode != USB_DR_MODE_OTG && in dwc3_meson_g12a_usb_otg_apply_mode()
383 priv->drvdata->otg_phy_host_port_disable) in dwc3_meson_g12a_usb_otg_apply_mode()
385 regmap_update_bits(priv->usb_glue_regmap, USB_R1, in dwc3_meson_g12a_usb_otg_apply_mode()
390 regmap_update_bits(priv->usb_glue_regmap, USB_R0, in dwc3_meson_g12a_usb_otg_apply_mode()
392 regmap_update_bits(priv->usb_glue_regmap, USB_R0, in dwc3_meson_g12a_usb_otg_apply_mode()
394 regmap_update_bits(priv->usb_glue_regmap, USB_R4, in dwc3_meson_g12a_usb_otg_apply_mode()
397 if (priv->otg_mode != USB_DR_MODE_OTG && in dwc3_meson_g12a_usb_otg_apply_mode()
398 priv->drvdata->otg_phy_host_port_disable) { in dwc3_meson_g12a_usb_otg_apply_mode()
399 regmap_update_bits(priv->usb_glue_regmap, USB_R1, in dwc3_meson_g12a_usb_otg_apply_mode()
403 regmap_update_bits(priv->usb_glue_regmap, USB_R0, in dwc3_meson_g12a_usb_otg_apply_mode()
405 regmap_update_bits(priv->usb_glue_regmap, USB_R4, in dwc3_meson_g12a_usb_otg_apply_mode()
419 regmap_update_bits(priv->usb_glue_regmap, USB_R1, in dwc3_meson_g12a_usb_init_glue()
423 regmap_update_bits(priv->usb_glue_regmap, USB_R5, in dwc3_meson_g12a_usb_init_glue()
426 regmap_update_bits(priv->usb_glue_regmap, USB_R5, in dwc3_meson_g12a_usb_init_glue()
429 regmap_update_bits(priv->usb_glue_regmap, USB_R5, in dwc3_meson_g12a_usb_init_glue()
434 if (priv->usb3_ports) in dwc3_meson_g12a_usb_init_glue()
443 .name = "usb-glue",
446 .reg_stride = 4,
455 for (i = 0 ; i < priv->drvdata->num_phys ; ++i) { in dwc3_meson_g12a_get_phys()
456 phy_name = priv->drvdata->phy_names[i]; in dwc3_meson_g12a_get_phys()
457 priv->phys[i] = devm_phy_optional_get(priv->dev, phy_name); in dwc3_meson_g12a_get_phys()
458 if (!priv->phys[i]) in dwc3_meson_g12a_get_phys()
461 if (IS_ERR(priv->phys[i])) in dwc3_meson_g12a_get_phys()
462 return PTR_ERR(priv->phys[i]); in dwc3_meson_g12a_get_phys()
465 priv->usb3_ports++; in dwc3_meson_g12a_get_phys()
467 priv->usb2_ports++; in dwc3_meson_g12a_get_phys()
470 dev_info(priv->dev, "USB2 ports: %d\n", priv->usb2_ports); in dwc3_meson_g12a_get_phys()
471 dev_info(priv->dev, "USB3 ports: %d\n", priv->usb3_ports); in dwc3_meson_g12a_get_phys()
480 regmap_read(priv->usb_glue_regmap, USB_R5, ®); in dwc3_meson_g12a_get_id()
493 if (!priv->drvdata->otg_switch_supported || !priv->phys[USB2_OTG_PHY]) in dwc3_meson_g12a_otg_mode_set()
494 return -EINVAL; in dwc3_meson_g12a_otg_mode_set()
497 dev_info(priv->dev, "switching to Host Mode\n"); in dwc3_meson_g12a_otg_mode_set()
499 dev_info(priv->dev, "switching to Device Mode\n"); in dwc3_meson_g12a_otg_mode_set()
501 if (priv->vbus) { in dwc3_meson_g12a_otg_mode_set()
503 ret = regulator_disable(priv->vbus); in dwc3_meson_g12a_otg_mode_set()
505 ret = regulator_enable(priv->vbus); in dwc3_meson_g12a_otg_mode_set()
510 priv->otg_phy_mode = mode; in dwc3_meson_g12a_otg_mode_set()
512 ret = priv->drvdata->set_phy_mode(priv, USB2_OTG_PHY, mode); in dwc3_meson_g12a_otg_mode_set()
533 if (mode == priv->otg_phy_mode) in dwc3_meson_g12a_role_set()
536 if (priv->drvdata->otg_phy_host_port_disable) in dwc3_meson_g12a_role_set()
537 dev_warn_once(priv->dev, "Broken manual OTG switch\n"); in dwc3_meson_g12a_role_set()
546 return priv->otg_phy_mode == PHY_MODE_USB_HOST ? in dwc3_meson_g12a_role_get()
556 if (otg_id != priv->otg_phy_mode) { in dwc3_meson_g12a_irq_thread()
558 dev_warn(priv->dev, "Failed to switch OTG mode\n"); in dwc3_meson_g12a_irq_thread()
561 regmap_update_bits(priv->usb_glue_regmap, USB_R5, in dwc3_meson_g12a_irq_thread()
567 static struct device *dwc3_meson_g12_find_child(struct device *dev, in dwc3_meson_g12_find_child()
573 np = of_get_compatible_child(dev->of_node, compatible); in dwc3_meson_g12_find_child()
582 return &pdev->dev; in dwc3_meson_g12_find_child()
590 struct device *dev = &pdev->dev; in dwc3_meson_g12a_otg_init()
592 if (!priv->drvdata->otg_switch_supported) in dwc3_meson_g12a_otg_init()
595 if (priv->otg_mode == USB_DR_MODE_OTG) { in dwc3_meson_g12a_otg_init()
597 regmap_update_bits(priv->usb_glue_regmap, USB_R5, in dwc3_meson_g12a_otg_init()
603 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, in dwc3_meson_g12a_otg_init()
605 IRQF_ONESHOT, pdev->name, priv); in dwc3_meson_g12a_otg_init()
611 if (priv->otg_mode == USB_DR_MODE_OTG) { in dwc3_meson_g12a_otg_init()
613 if (otg_id != priv->otg_phy_mode) { in dwc3_meson_g12a_otg_init()
620 priv->switch_desc.usb2_port = dwc3_meson_g12_find_child(dev, in dwc3_meson_g12a_otg_init()
622 priv->switch_desc.udc = dwc3_meson_g12_find_child(dev, "snps,dwc2"); in dwc3_meson_g12a_otg_init()
623 priv->switch_desc.allow_userspace_control = true; in dwc3_meson_g12a_otg_init()
624 priv->switch_desc.set = dwc3_meson_g12a_role_set; in dwc3_meson_g12a_otg_init()
625 priv->switch_desc.get = dwc3_meson_g12a_role_get; in dwc3_meson_g12a_otg_init()
626 priv->switch_desc.driver_data = priv; in dwc3_meson_g12a_otg_init()
628 priv->role_switch = usb_role_switch_register(dev, &priv->switch_desc); in dwc3_meson_g12a_otg_init()
629 if (IS_ERR(priv->role_switch)) in dwc3_meson_g12a_otg_init()
639 priv->usb_glue_regmap = devm_regmap_init_mmio(priv->dev, base, in dwc3_meson_gxl_setup_regmaps()
641 return PTR_ERR_OR_ZERO(priv->usb_glue_regmap); in dwc3_meson_gxl_setup_regmaps()
649 priv->usb_glue_regmap = devm_regmap_init_mmio(priv->dev, in dwc3_meson_g12a_setup_regmaps()
652 if (IS_ERR(priv->usb_glue_regmap)) in dwc3_meson_g12a_setup_regmaps()
653 return PTR_ERR(priv->usb_glue_regmap); in dwc3_meson_g12a_setup_regmaps()
655 /* Create a regmap for each USB2 PHY control register set */ in dwc3_meson_g12a_setup_regmaps()
656 for (i = 0; i < priv->drvdata->num_phys; i++) { in dwc3_meson_g12a_setup_regmaps()
660 .reg_stride = 4, in dwc3_meson_g12a_setup_regmaps()
664 if (!strstr(priv->drvdata->phy_names[i], "usb2")) in dwc3_meson_g12a_setup_regmaps()
667 u2p_regmap_config.name = devm_kasprintf(priv->dev, GFP_KERNEL, in dwc3_meson_g12a_setup_regmaps()
668 "u2p-%d", i); in dwc3_meson_g12a_setup_regmaps()
670 return -ENOMEM; in dwc3_meson_g12a_setup_regmaps()
672 priv->u2p_regmap[i] = devm_regmap_init_mmio(priv->dev, in dwc3_meson_g12a_setup_regmaps()
675 if (IS_ERR(priv->u2p_regmap[i])) in dwc3_meson_g12a_setup_regmaps()
676 return PTR_ERR(priv->u2p_regmap[i]); in dwc3_meson_g12a_setup_regmaps()
684 return dwc3_meson_g12a_usb_init_glue(priv, priv->otg_phy_mode); in dwc3_meson_g12a_usb_init()
696 ret = priv->drvdata->set_phy_mode(priv, USB2_OTG_PHY, in dwc3_meson_gxl_usb_post_init()
697 priv->otg_phy_mode); in dwc3_meson_gxl_usb_post_init()
701 dwc3_meson_g12a_usb_otg_apply_mode(priv, priv->otg_phy_mode); in dwc3_meson_gxl_usb_post_init()
709 struct device *dev = &pdev->dev; in dwc3_meson_g12a_probe()
710 struct device_node *np = dev->of_node; in dwc3_meson_g12a_probe()
716 return -ENOMEM; in dwc3_meson_g12a_probe()
722 priv->drvdata = of_device_get_match_data(&pdev->dev); in dwc3_meson_g12a_probe()
723 priv->dev = dev; in dwc3_meson_g12a_probe()
725 priv->vbus = devm_regulator_get_optional(dev, "vbus"); in dwc3_meson_g12a_probe()
726 if (IS_ERR(priv->vbus)) { in dwc3_meson_g12a_probe()
727 if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) in dwc3_meson_g12a_probe()
728 return PTR_ERR(priv->vbus); in dwc3_meson_g12a_probe()
729 priv->vbus = NULL; in dwc3_meson_g12a_probe()
733 priv->drvdata->num_clks, in dwc3_meson_g12a_probe()
734 priv->drvdata->clks); in dwc3_meson_g12a_probe()
738 ret = clk_bulk_prepare_enable(priv->drvdata->num_clks, in dwc3_meson_g12a_probe()
739 priv->drvdata->clks); in dwc3_meson_g12a_probe()
745 priv->reset = devm_reset_control_get_shared(dev, NULL); in dwc3_meson_g12a_probe()
746 if (IS_ERR(priv->reset)) { in dwc3_meson_g12a_probe()
747 ret = PTR_ERR(priv->reset); in dwc3_meson_g12a_probe()
748 dev_err(dev, "failed to get device reset, err=%d\n", ret); in dwc3_meson_g12a_probe()
752 ret = reset_control_reset(priv->reset); in dwc3_meson_g12a_probe()
760 ret = priv->drvdata->setup_regmaps(priv, base); in dwc3_meson_g12a_probe()
764 if (priv->vbus) { in dwc3_meson_g12a_probe()
765 ret = regulator_enable(priv->vbus); in dwc3_meson_g12a_probe()
771 priv->otg_mode = usb_get_dr_mode(dev); in dwc3_meson_g12a_probe()
773 if (priv->otg_mode == USB_DR_MODE_PERIPHERAL) in dwc3_meson_g12a_probe()
774 priv->otg_phy_mode = PHY_MODE_USB_DEVICE; in dwc3_meson_g12a_probe()
776 priv->otg_phy_mode = PHY_MODE_USB_HOST; in dwc3_meson_g12a_probe()
778 ret = priv->drvdata->usb_init(priv); in dwc3_meson_g12a_probe()
784 ret = phy_init(priv->phys[i]); in dwc3_meson_g12a_probe()
791 ret = phy_power_on(priv->phys[i]); in dwc3_meson_g12a_probe()
796 if (priv->drvdata->usb_post_init) { in dwc3_meson_g12a_probe()
797 ret = priv->drvdata->usb_post_init(priv); in dwc3_meson_g12a_probe()
818 phy_power_off(priv->phys[i]); in dwc3_meson_g12a_probe()
822 phy_exit(priv->phys[i]); in dwc3_meson_g12a_probe()
825 if (priv->vbus) in dwc3_meson_g12a_probe()
826 regulator_disable(priv->vbus); in dwc3_meson_g12a_probe()
829 reset_control_rearm(priv->reset); in dwc3_meson_g12a_probe()
832 clk_bulk_disable_unprepare(priv->drvdata->num_clks, in dwc3_meson_g12a_probe()
833 priv->drvdata->clks); in dwc3_meson_g12a_probe()
841 struct device *dev = &pdev->dev; in dwc3_meson_g12a_remove()
844 if (priv->drvdata->otg_switch_supported) in dwc3_meson_g12a_remove()
845 usb_role_switch_unregister(priv->role_switch); in dwc3_meson_g12a_remove()
850 phy_power_off(priv->phys[i]); in dwc3_meson_g12a_remove()
851 phy_exit(priv->phys[i]); in dwc3_meson_g12a_remove()
858 reset_control_rearm(priv->reset); in dwc3_meson_g12a_remove()
860 clk_bulk_disable_unprepare(priv->drvdata->num_clks, in dwc3_meson_g12a_remove()
861 priv->drvdata->clks); in dwc3_meson_g12a_remove()
866 static int __maybe_unused dwc3_meson_g12a_runtime_suspend(struct device *dev) in dwc3_meson_g12a_runtime_suspend()
870 clk_bulk_disable_unprepare(priv->drvdata->num_clks, in dwc3_meson_g12a_runtime_suspend()
871 priv->drvdata->clks); in dwc3_meson_g12a_runtime_suspend()
876 static int __maybe_unused dwc3_meson_g12a_runtime_resume(struct device *dev) in dwc3_meson_g12a_runtime_resume()
880 return clk_bulk_prepare_enable(priv->drvdata->num_clks, in dwc3_meson_g12a_runtime_resume()
881 priv->drvdata->clks); in dwc3_meson_g12a_runtime_resume()
884 static int __maybe_unused dwc3_meson_g12a_suspend(struct device *dev) in dwc3_meson_g12a_suspend()
889 if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) { in dwc3_meson_g12a_suspend()
890 ret = regulator_disable(priv->vbus); in dwc3_meson_g12a_suspend()
896 phy_power_off(priv->phys[i]); in dwc3_meson_g12a_suspend()
897 phy_exit(priv->phys[i]); in dwc3_meson_g12a_suspend()
900 reset_control_rearm(priv->reset); in dwc3_meson_g12a_suspend()
905 static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev) in dwc3_meson_g12a_resume()
910 ret = reset_control_reset(priv->reset); in dwc3_meson_g12a_resume()
914 ret = priv->drvdata->usb_init(priv); in dwc3_meson_g12a_resume()
920 ret = phy_init(priv->phys[i]); in dwc3_meson_g12a_resume()
927 ret = phy_power_on(priv->phys[i]); in dwc3_meson_g12a_resume()
932 if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) { in dwc3_meson_g12a_resume()
933 ret = regulator_enable(priv->vbus); in dwc3_meson_g12a_resume()
949 .compatible = "amlogic,meson-gxl-usb-ctrl",
953 .compatible = "amlogic,meson-gxm-usb-ctrl",
957 .compatible = "amlogic,meson-axg-usb-ctrl",
961 .compatible = "amlogic,meson-g12a-usb-ctrl",
965 .compatible = "amlogic,meson-a1-usb-ctrl",
976 .name = "dwc3-meson-g12a",