Lines Matching +full:usb3 +full:- +full:phy0

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 */
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"
185 * In order to still switch from Host to Device on an USB Type-A port,
275 return phy_set_mode(priv->phys[i], mode); in dwc3_meson_gxl_set_phy_mode()
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",
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()
464 if (strstr(phy_name, "usb3")) 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, &reg); 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()
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()
601 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, in dwc3_meson_g12a_otg_init()
603 IRQF_ONESHOT, pdev->name, priv); in dwc3_meson_g12a_otg_init()
609 if (priv->otg_mode == USB_DR_MODE_OTG) { in dwc3_meson_g12a_otg_init()
611 if (otg_id != priv->otg_phy_mode) { in dwc3_meson_g12a_otg_init()
618 priv->switch_desc.usb2_port = dwc3_meson_g12_find_child(dev, in dwc3_meson_g12a_otg_init()
620 priv->switch_desc.udc = dwc3_meson_g12_find_child(dev, "snps,dwc2"); in dwc3_meson_g12a_otg_init()
621 priv->switch_desc.allow_userspace_control = true; in dwc3_meson_g12a_otg_init()
622 priv->switch_desc.set = dwc3_meson_g12a_role_set; in dwc3_meson_g12a_otg_init()
623 priv->switch_desc.get = dwc3_meson_g12a_role_get; in dwc3_meson_g12a_otg_init()
624 priv->switch_desc.driver_data = priv; in dwc3_meson_g12a_otg_init()
626 priv->role_switch = usb_role_switch_register(dev, &priv->switch_desc); in dwc3_meson_g12a_otg_init()
627 if (IS_ERR(priv->role_switch)) in dwc3_meson_g12a_otg_init()
637 priv->usb_glue_regmap = devm_regmap_init_mmio(priv->dev, base, in dwc3_meson_gxl_setup_regmaps()
639 return PTR_ERR_OR_ZERO(priv->usb_glue_regmap); in dwc3_meson_gxl_setup_regmaps()
647 priv->usb_glue_regmap = devm_regmap_init_mmio(priv->dev, in dwc3_meson_g12a_setup_regmaps()
650 if (IS_ERR(priv->usb_glue_regmap)) in dwc3_meson_g12a_setup_regmaps()
651 return PTR_ERR(priv->usb_glue_regmap); in dwc3_meson_g12a_setup_regmaps()
654 for (i = 0; i < priv->usb2_ports; i++) { in dwc3_meson_g12a_setup_regmaps()
662 u2p_regmap_config.name = devm_kasprintf(priv->dev, GFP_KERNEL, in dwc3_meson_g12a_setup_regmaps()
663 "u2p-%d", i); in dwc3_meson_g12a_setup_regmaps()
665 return -ENOMEM; in dwc3_meson_g12a_setup_regmaps()
667 priv->u2p_regmap[i] = devm_regmap_init_mmio(priv->dev, in dwc3_meson_g12a_setup_regmaps()
670 if (IS_ERR(priv->u2p_regmap[i])) in dwc3_meson_g12a_setup_regmaps()
671 return PTR_ERR(priv->u2p_regmap[i]); in dwc3_meson_g12a_setup_regmaps()
679 return dwc3_meson_g12a_usb_init_glue(priv, priv->otg_phy_mode); in dwc3_meson_g12a_usb_init()
691 ret = priv->drvdata->set_phy_mode(priv, USB2_OTG_PHY, in dwc3_meson_gxl_usb_post_init()
692 priv->otg_phy_mode); in dwc3_meson_gxl_usb_post_init()
696 dwc3_meson_g12a_usb_otg_apply_mode(priv, priv->otg_phy_mode); in dwc3_meson_gxl_usb_post_init()
704 struct device *dev = &pdev->dev; in dwc3_meson_g12a_probe()
705 struct device_node *np = dev->of_node; in dwc3_meson_g12a_probe()
711 return -ENOMEM; in dwc3_meson_g12a_probe()
717 priv->drvdata = of_device_get_match_data(&pdev->dev); in dwc3_meson_g12a_probe()
718 priv->dev = dev; in dwc3_meson_g12a_probe()
720 priv->vbus = devm_regulator_get_optional(dev, "vbus"); in dwc3_meson_g12a_probe()
721 if (IS_ERR(priv->vbus)) { in dwc3_meson_g12a_probe()
722 if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) in dwc3_meson_g12a_probe()
723 return PTR_ERR(priv->vbus); in dwc3_meson_g12a_probe()
724 priv->vbus = NULL; in dwc3_meson_g12a_probe()
728 priv->drvdata->num_clks, in dwc3_meson_g12a_probe()
729 priv->drvdata->clks); in dwc3_meson_g12a_probe()
733 ret = clk_bulk_prepare_enable(priv->drvdata->num_clks, in dwc3_meson_g12a_probe()
734 priv->drvdata->clks); in dwc3_meson_g12a_probe()
740 priv->reset = devm_reset_control_get_shared(dev, NULL); in dwc3_meson_g12a_probe()
741 if (IS_ERR(priv->reset)) { in dwc3_meson_g12a_probe()
742 ret = PTR_ERR(priv->reset); in dwc3_meson_g12a_probe()
747 ret = reset_control_reset(priv->reset); in dwc3_meson_g12a_probe()
755 ret = priv->drvdata->setup_regmaps(priv, base); in dwc3_meson_g12a_probe()
759 if (priv->vbus) { in dwc3_meson_g12a_probe()
760 ret = regulator_enable(priv->vbus); in dwc3_meson_g12a_probe()
766 priv->otg_mode = usb_get_dr_mode(dev); in dwc3_meson_g12a_probe()
768 if (priv->otg_mode == USB_DR_MODE_PERIPHERAL) in dwc3_meson_g12a_probe()
769 priv->otg_phy_mode = PHY_MODE_USB_DEVICE; in dwc3_meson_g12a_probe()
771 priv->otg_phy_mode = PHY_MODE_USB_HOST; in dwc3_meson_g12a_probe()
773 ret = priv->drvdata->usb_init(priv); in dwc3_meson_g12a_probe()
779 ret = phy_init(priv->phys[i]); in dwc3_meson_g12a_probe()
786 ret = phy_power_on(priv->phys[i]); in dwc3_meson_g12a_probe()
791 if (priv->drvdata->usb_post_init) { in dwc3_meson_g12a_probe()
792 ret = priv->drvdata->usb_post_init(priv); in dwc3_meson_g12a_probe()
813 phy_power_off(priv->phys[i]); in dwc3_meson_g12a_probe()
817 phy_exit(priv->phys[i]); in dwc3_meson_g12a_probe()
820 clk_bulk_disable_unprepare(priv->drvdata->num_clks, in dwc3_meson_g12a_probe()
821 priv->drvdata->clks); in dwc3_meson_g12a_probe()
829 struct device *dev = &pdev->dev; in dwc3_meson_g12a_remove()
832 if (priv->drvdata->otg_switch_supported) in dwc3_meson_g12a_remove()
833 usb_role_switch_unregister(priv->role_switch); in dwc3_meson_g12a_remove()
838 phy_power_off(priv->phys[i]); in dwc3_meson_g12a_remove()
839 phy_exit(priv->phys[i]); in dwc3_meson_g12a_remove()
846 clk_bulk_disable_unprepare(priv->drvdata->num_clks, in dwc3_meson_g12a_remove()
847 priv->drvdata->clks); in dwc3_meson_g12a_remove()
856 clk_bulk_disable_unprepare(priv->drvdata->num_clks, in dwc3_meson_g12a_runtime_suspend()
857 priv->drvdata->clks); in dwc3_meson_g12a_runtime_suspend()
866 return clk_bulk_prepare_enable(priv->drvdata->num_clks, in dwc3_meson_g12a_runtime_resume()
867 priv->drvdata->clks); in dwc3_meson_g12a_runtime_resume()
875 if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) { in dwc3_meson_g12a_suspend()
876 ret = regulator_disable(priv->vbus); in dwc3_meson_g12a_suspend()
882 phy_power_off(priv->phys[i]); in dwc3_meson_g12a_suspend()
883 phy_exit(priv->phys[i]); in dwc3_meson_g12a_suspend()
886 reset_control_assert(priv->reset); in dwc3_meson_g12a_suspend()
896 reset_control_deassert(priv->reset); in dwc3_meson_g12a_resume()
898 ret = priv->drvdata->usb_init(priv); in dwc3_meson_g12a_resume()
904 ret = phy_init(priv->phys[i]); in dwc3_meson_g12a_resume()
911 ret = phy_power_on(priv->phys[i]); in dwc3_meson_g12a_resume()
916 if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) { in dwc3_meson_g12a_resume()
917 ret = regulator_enable(priv->vbus); in dwc3_meson_g12a_resume()
933 .compatible = "amlogic,meson-gxl-usb-ctrl",
937 .compatible = "amlogic,meson-gxm-usb-ctrl",
941 .compatible = "amlogic,meson-axg-usb-ctrl",
945 .compatible = "amlogic,meson-g12a-usb-ctrl",
949 .compatible = "amlogic,meson-a1-usb-ctrl",
960 .name = "dwc3-meson-g12a",