Commit 48d299a799f8e60342f10309dc3d4eb8e4b453a1
Exists in
smarc_8mq_lf_v2020.04
and in
12 other branches
Merge branch 'master' of git://git.denx.de/u-boot-usb
- DWC3 and UDC cleanup
Showing 39 changed files Side-by-side Diff
- arch/arm/Kconfig
- arch/arm/dts/omap5-u-boot.dtsi
- arch/sandbox/dts/test.dts
- board/sunxi/board.c
- board/ti/am57xx/board.c
- board/ti/dra7xx/evm.c
- cmd/fastboot.c
- cmd/rockusb.c
- cmd/thordown.c
- cmd/usb_gadget_sdp.c
- cmd/usb_mass_storage.c
- common/dfu.c
- configs/am57xx_evm_defconfig
- configs/am57xx_hs_evm_defconfig
- configs/dra7xx_evm_defconfig
- configs/dra7xx_hs_evm_defconfig
- configs/evb-rk3328_defconfig
- drivers/core/syscon-uclass.c
- drivers/phy/Kconfig
- drivers/phy/Makefile
- drivers/phy/omap-usb2-phy.c
- drivers/phy/ti-pipe3-phy.c
- drivers/usb/Kconfig
- drivers/usb/dwc3/Kconfig
- drivers/usb/dwc3/core.c
- drivers/usb/dwc3/dwc3-generic.c
- drivers/usb/dwc3/ep0.c
- drivers/usb/gadget/ether.c
- drivers/usb/gadget/udc/Makefile
- drivers/usb/gadget/udc/udc-core.c
- drivers/usb/gadget/udc/udc-uclass.c
- drivers/usb/host/xhci-dwc3.c
- drivers/usb/musb-new/omap2430.c
- drivers/usb/musb-new/sunxi.c
- include/dm/uclass-id.h
- include/dwc3-uboot.h
- include/linux/usb/gadget.h
- include/syscon.h
- test/dm/syscon.c
arch/arm/Kconfig
... | ... | @@ -932,6 +932,7 @@ |
932 | 932 | select DM_SERIAL |
933 | 933 | select OF_CONTROL |
934 | 934 | imply CMD_DM |
935 | + imply DM_USB_GADGET | |
935 | 936 | |
936 | 937 | config ARCH_ZYNQMP |
937 | 938 | bool "Xilinx ZynqMP based platform" |
... | ... | @@ -949,6 +950,7 @@ |
949 | 950 | imply CMD_DM |
950 | 951 | imply FAT_WRITE |
951 | 952 | imply MP |
953 | + imply DM_USB_GADGET | |
952 | 954 | |
953 | 955 | config TEGRA |
954 | 956 | bool "NVIDIA Tegra" |
arch/arm/dts/omap5-u-boot.dtsi
arch/sandbox/dts/test.dts
... | ... | @@ -460,6 +460,8 @@ |
460 | 460 | |
461 | 461 | test4 { |
462 | 462 | compatible = "denx,u-boot-probe-test"; |
463 | + first-syscon = <&syscon0>; | |
464 | + second-sys-ctrl = <&another_system_controller>; | |
463 | 465 | }; |
464 | 466 | }; |
465 | 467 | |
466 | 468 | |
... | ... | @@ -540,12 +542,12 @@ |
540 | 542 | }; |
541 | 543 | }; |
542 | 544 | |
543 | - syscon@0 { | |
545 | + syscon0: syscon@0 { | |
544 | 546 | compatible = "sandbox,syscon0"; |
545 | 547 | reg = <0x10 16>; |
546 | 548 | }; |
547 | 549 | |
548 | - syscon@1 { | |
550 | + another_system_controller: syscon@1 { | |
549 | 551 | compatible = "sandbox,syscon1"; |
550 | 552 | reg = <0x20 5 |
551 | 553 | 0x28 6 |
board/sunxi/board.c
... | ... | @@ -665,7 +665,7 @@ |
665 | 665 | struct phy phy; |
666 | 666 | int ret; |
667 | 667 | |
668 | - ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, 0, &dev); | |
668 | + ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev); | |
669 | 669 | if (ret) { |
670 | 670 | pr_err("%s: Cannot find USB device\n", __func__); |
671 | 671 | return ret; |
board/ti/am57xx/board.c
... | ... | @@ -675,6 +675,19 @@ |
675 | 675 | return; |
676 | 676 | } |
677 | 677 | |
678 | +#if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL) | |
679 | +static int device_okay(const char *path) | |
680 | +{ | |
681 | + int node; | |
682 | + | |
683 | + node = fdt_path_offset(gd->fdt_blob, path); | |
684 | + if (node < 0) | |
685 | + return 0; | |
686 | + | |
687 | + return fdtdec_get_is_enabled(gd->fdt_blob, node); | |
688 | +} | |
689 | +#endif | |
690 | + | |
678 | 691 | int board_late_init(void) |
679 | 692 | { |
680 | 693 | setup_board_eeprom_env(); |
... | ... | @@ -714,6 +727,12 @@ |
714 | 727 | board_ti_set_ethaddr(2); |
715 | 728 | #endif |
716 | 729 | |
730 | +#if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL) | |
731 | + if (device_okay("/ocp/omap_dwc3_1@48880000")) | |
732 | + enable_usb_clocks(0); | |
733 | + if (device_okay("/ocp/omap_dwc3_2@488c0000")) | |
734 | + enable_usb_clocks(1); | |
735 | +#endif | |
717 | 736 | return 0; |
718 | 737 | } |
719 | 738 | |
... | ... | @@ -863,93 +882,6 @@ |
863 | 882 | return 0; |
864 | 883 | } |
865 | 884 | #endif |
866 | - | |
867 | -#ifdef CONFIG_USB_DWC3 | |
868 | -static struct dwc3_device usb_otg_ss2 = { | |
869 | - .maximum_speed = USB_SPEED_HIGH, | |
870 | - .base = DRA7_USB_OTG_SS2_BASE, | |
871 | - .tx_fifo_resize = false, | |
872 | - .index = 1, | |
873 | -}; | |
874 | - | |
875 | -static struct dwc3_omap_device usb_otg_ss2_glue = { | |
876 | - .base = (void *)DRA7_USB_OTG_SS2_GLUE_BASE, | |
877 | - .utmi_mode = DWC3_OMAP_UTMI_MODE_SW, | |
878 | - .index = 1, | |
879 | -}; | |
880 | - | |
881 | -static struct ti_usb_phy_device usb_phy2_device = { | |
882 | - .usb2_phy_power = (void *)DRA7_USB2_PHY2_POWER, | |
883 | - .index = 1, | |
884 | -}; | |
885 | - | |
886 | -int usb_gadget_handle_interrupts(int index) | |
887 | -{ | |
888 | - u32 status; | |
889 | - | |
890 | - status = dwc3_omap_uboot_interrupt_status(index); | |
891 | - if (status) | |
892 | - dwc3_uboot_handle_interrupt(index); | |
893 | - | |
894 | - return 0; | |
895 | -} | |
896 | -#endif /* CONFIG_USB_DWC3 */ | |
897 | - | |
898 | -#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) | |
899 | -int board_usb_init(int index, enum usb_init_type init) | |
900 | -{ | |
901 | - enable_usb_clocks(index); | |
902 | - switch (index) { | |
903 | - case 0: | |
904 | - if (init == USB_INIT_DEVICE) { | |
905 | - printf("port %d can't be used as device\n", index); | |
906 | - disable_usb_clocks(index); | |
907 | - return -EINVAL; | |
908 | - } | |
909 | - break; | |
910 | - case 1: | |
911 | - if (init == USB_INIT_DEVICE) { | |
912 | -#ifdef CONFIG_USB_DWC3 | |
913 | - usb_otg_ss2.dr_mode = USB_DR_MODE_PERIPHERAL; | |
914 | - usb_otg_ss2_glue.vbus_id_status = OMAP_DWC3_VBUS_VALID; | |
915 | - ti_usb_phy_uboot_init(&usb_phy2_device); | |
916 | - dwc3_omap_uboot_init(&usb_otg_ss2_glue); | |
917 | - dwc3_uboot_init(&usb_otg_ss2); | |
918 | -#endif | |
919 | - } else { | |
920 | - printf("port %d can't be used as host\n", index); | |
921 | - disable_usb_clocks(index); | |
922 | - return -EINVAL; | |
923 | - } | |
924 | - | |
925 | - break; | |
926 | - default: | |
927 | - printf("Invalid Controller Index\n"); | |
928 | - } | |
929 | - | |
930 | - return 0; | |
931 | -} | |
932 | - | |
933 | -int board_usb_cleanup(int index, enum usb_init_type init) | |
934 | -{ | |
935 | -#ifdef CONFIG_USB_DWC3 | |
936 | - switch (index) { | |
937 | - case 0: | |
938 | - case 1: | |
939 | - if (init == USB_INIT_DEVICE) { | |
940 | - ti_usb_phy_uboot_exit(index); | |
941 | - dwc3_uboot_exit(index); | |
942 | - dwc3_omap_uboot_exit(index); | |
943 | - } | |
944 | - break; | |
945 | - default: | |
946 | - printf("Invalid Controller Index\n"); | |
947 | - } | |
948 | -#endif | |
949 | - disable_usb_clocks(index); | |
950 | - return 0; | |
951 | -} | |
952 | -#endif /* defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) */ | |
953 | 885 | |
954 | 886 | #ifdef CONFIG_DRIVER_TI_CPSW |
955 | 887 |
board/ti/dra7xx/evm.c
... | ... | @@ -646,6 +646,19 @@ |
646 | 646 | return 0; |
647 | 647 | } |
648 | 648 | |
649 | +#if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL) | |
650 | +static int device_okay(const char *path) | |
651 | +{ | |
652 | + int node; | |
653 | + | |
654 | + node = fdt_path_offset(gd->fdt_blob, path); | |
655 | + if (node < 0) | |
656 | + return 0; | |
657 | + | |
658 | + return fdtdec_get_is_enabled(gd->fdt_blob, node); | |
659 | +} | |
660 | +#endif | |
661 | + | |
649 | 662 | int board_late_init(void) |
650 | 663 | { |
651 | 664 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG |
... | ... | @@ -685,6 +698,12 @@ |
685 | 698 | if (board_is_dra71x_evm()) |
686 | 699 | palmas_i2c_write_u8(LP873X_I2C_SLAVE_ADDR, 0x9, 0x7); |
687 | 700 | #endif |
701 | +#if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL) | |
702 | + if (device_okay("/ocp/omap_dwc3_1@48880000")) | |
703 | + enable_usb_clocks(0); | |
704 | + if (device_okay("/ocp/omap_dwc3_2@488c0000")) | |
705 | + enable_usb_clocks(1); | |
706 | +#endif | |
688 | 707 | return 0; |
689 | 708 | } |
690 | 709 | |
... | ... | @@ -893,110 +912,6 @@ |
893 | 912 | default: |
894 | 913 | return NULL; |
895 | 914 | } |
896 | -} | |
897 | -#endif | |
898 | - | |
899 | -#ifdef CONFIG_USB_DWC3 | |
900 | -static struct dwc3_device usb_otg_ss1 = { | |
901 | - .maximum_speed = USB_SPEED_SUPER, | |
902 | - .base = DRA7_USB_OTG_SS1_BASE, | |
903 | - .tx_fifo_resize = false, | |
904 | - .index = 0, | |
905 | -}; | |
906 | - | |
907 | -static struct dwc3_omap_device usb_otg_ss1_glue = { | |
908 | - .base = (void *)DRA7_USB_OTG_SS1_GLUE_BASE, | |
909 | - .utmi_mode = DWC3_OMAP_UTMI_MODE_SW, | |
910 | - .index = 0, | |
911 | -}; | |
912 | - | |
913 | -static struct ti_usb_phy_device usb_phy1_device = { | |
914 | - .pll_ctrl_base = (void *)DRA7_USB3_PHY1_PLL_CTRL, | |
915 | - .usb2_phy_power = (void *)DRA7_USB2_PHY1_POWER, | |
916 | - .usb3_phy_power = (void *)DRA7_USB3_PHY1_POWER, | |
917 | - .index = 0, | |
918 | -}; | |
919 | - | |
920 | -static struct dwc3_device usb_otg_ss2 = { | |
921 | - .maximum_speed = USB_SPEED_SUPER, | |
922 | - .base = DRA7_USB_OTG_SS2_BASE, | |
923 | - .tx_fifo_resize = false, | |
924 | - .index = 1, | |
925 | -}; | |
926 | - | |
927 | -static struct dwc3_omap_device usb_otg_ss2_glue = { | |
928 | - .base = (void *)DRA7_USB_OTG_SS2_GLUE_BASE, | |
929 | - .utmi_mode = DWC3_OMAP_UTMI_MODE_SW, | |
930 | - .index = 1, | |
931 | -}; | |
932 | - | |
933 | -static struct ti_usb_phy_device usb_phy2_device = { | |
934 | - .usb2_phy_power = (void *)DRA7_USB2_PHY2_POWER, | |
935 | - .index = 1, | |
936 | -}; | |
937 | - | |
938 | -int board_usb_init(int index, enum usb_init_type init) | |
939 | -{ | |
940 | - enable_usb_clocks(index); | |
941 | - switch (index) { | |
942 | - case 0: | |
943 | - if (init == USB_INIT_DEVICE) { | |
944 | - usb_otg_ss1.dr_mode = USB_DR_MODE_PERIPHERAL; | |
945 | - usb_otg_ss1_glue.vbus_id_status = OMAP_DWC3_VBUS_VALID; | |
946 | - } else { | |
947 | - usb_otg_ss1.dr_mode = USB_DR_MODE_HOST; | |
948 | - usb_otg_ss1_glue.vbus_id_status = OMAP_DWC3_ID_GROUND; | |
949 | - } | |
950 | - | |
951 | - ti_usb_phy_uboot_init(&usb_phy1_device); | |
952 | - dwc3_omap_uboot_init(&usb_otg_ss1_glue); | |
953 | - dwc3_uboot_init(&usb_otg_ss1); | |
954 | - break; | |
955 | - case 1: | |
956 | - if (init == USB_INIT_DEVICE) { | |
957 | - usb_otg_ss2.dr_mode = USB_DR_MODE_PERIPHERAL; | |
958 | - usb_otg_ss2_glue.vbus_id_status = OMAP_DWC3_VBUS_VALID; | |
959 | - } else { | |
960 | - usb_otg_ss2.dr_mode = USB_DR_MODE_HOST; | |
961 | - usb_otg_ss2_glue.vbus_id_status = OMAP_DWC3_ID_GROUND; | |
962 | - } | |
963 | - | |
964 | - ti_usb_phy_uboot_init(&usb_phy2_device); | |
965 | - dwc3_omap_uboot_init(&usb_otg_ss2_glue); | |
966 | - dwc3_uboot_init(&usb_otg_ss2); | |
967 | - break; | |
968 | - default: | |
969 | - printf("Invalid Controller Index\n"); | |
970 | - } | |
971 | - | |
972 | - return 0; | |
973 | -} | |
974 | - | |
975 | -int board_usb_cleanup(int index, enum usb_init_type init) | |
976 | -{ | |
977 | - switch (index) { | |
978 | - case 0: | |
979 | - case 1: | |
980 | - ti_usb_phy_uboot_exit(index); | |
981 | - dwc3_uboot_exit(index); | |
982 | - dwc3_omap_uboot_exit(index); | |
983 | - break; | |
984 | - default: | |
985 | - printf("Invalid Controller Index\n"); | |
986 | - } | |
987 | - disable_usb_clocks(index); | |
988 | - return 0; | |
989 | -} | |
990 | - | |
991 | -int usb_gadget_handle_interrupts(int index) | |
992 | -{ | |
993 | - u32 status; | |
994 | - | |
995 | - status = dwc3_omap_uboot_interrupt_status(index); | |
996 | - if (status) | |
997 | - dwc3_uboot_handle_interrupt(index); | |
998 | - | |
999 | - return 0; | |
1000 | 915 | } |
1001 | 916 | #endif |
1002 | 917 |
cmd/fastboot.c
... | ... | @@ -51,7 +51,7 @@ |
51 | 51 | return CMD_RET_FAILURE; |
52 | 52 | } |
53 | 53 | |
54 | - ret = board_usb_init(controller_index, USB_INIT_DEVICE); | |
54 | + ret = usb_gadget_initialize(controller_index); | |
55 | 55 | if (ret) { |
56 | 56 | pr_err("USB init failed: %d\n", ret); |
57 | 57 | return CMD_RET_FAILURE; |
... | ... | @@ -82,7 +82,7 @@ |
82 | 82 | exit: |
83 | 83 | g_dnl_unregister(); |
84 | 84 | g_dnl_clear_detach(); |
85 | - board_usb_cleanup(controller_index, USB_INIT_DEVICE); | |
85 | + usb_gadget_release(controller_index); | |
86 | 86 | |
87 | 87 | return ret; |
88 | 88 | #else |
cmd/rockusb.c
... | ... | @@ -33,7 +33,7 @@ |
33 | 33 | dev_index = simple_strtoul(devnum, NULL, 0); |
34 | 34 | rockusb_dev_init(devtype, dev_index); |
35 | 35 | |
36 | - ret = board_usb_init(controller_index, USB_INIT_DEVICE); | |
36 | + ret = usb_gadget_initialize(controller_index); | |
37 | 37 | if (ret) { |
38 | 38 | printf("USB init failed: %d\n", ret); |
39 | 39 | return CMD_RET_FAILURE; |
... | ... | @@ -62,7 +62,7 @@ |
62 | 62 | exit: |
63 | 63 | g_dnl_unregister(); |
64 | 64 | g_dnl_clear_detach(); |
65 | - board_usb_cleanup(controller_index, USB_INIT_DEVICE); | |
65 | + usb_gadget_release(controller_index); | |
66 | 66 | |
67 | 67 | return ret; |
68 | 68 | } |
cmd/thordown.c
... | ... | @@ -30,7 +30,7 @@ |
30 | 30 | goto done; |
31 | 31 | |
32 | 32 | int controller_index = simple_strtoul(usb_controller, NULL, 0); |
33 | - ret = board_usb_init(controller_index, USB_INIT_DEVICE); | |
33 | + ret = usb_gadget_initialize(controller_index); | |
34 | 34 | if (ret) { |
35 | 35 | pr_err("USB init failed: %d\n", ret); |
36 | 36 | ret = CMD_RET_FAILURE; |
... | ... | @@ -55,7 +55,7 @@ |
55 | 55 | |
56 | 56 | exit: |
57 | 57 | g_dnl_unregister(); |
58 | - board_usb_cleanup(controller_index, USB_INIT_DEVICE); | |
58 | + usb_gadget_release(controller_index); | |
59 | 59 | done: |
60 | 60 | dfu_free_entities(); |
61 | 61 |
cmd/usb_gadget_sdp.c
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | |
21 | 21 | char *usb_controller = argv[1]; |
22 | 22 | int controller_index = simple_strtoul(usb_controller, NULL, 0); |
23 | - board_usb_init(controller_index, USB_INIT_DEVICE); | |
23 | + usb_gadget_initialize(controller_index); | |
24 | 24 | |
25 | 25 | g_dnl_clear_detach(); |
26 | 26 | g_dnl_register("usb_dnl_sdp"); |
... | ... | @@ -37,7 +37,7 @@ |
37 | 37 | |
38 | 38 | exit: |
39 | 39 | g_dnl_unregister(); |
40 | - board_usb_cleanup(controller_index, USB_INIT_DEVICE); | |
40 | + usb_gadget_release(controller_index); | |
41 | 41 | |
42 | 42 | return ret; |
43 | 43 | } |
cmd/usb_mass_storage.c
... | ... | @@ -160,7 +160,7 @@ |
160 | 160 | |
161 | 161 | controller_index = (unsigned int)(simple_strtoul( |
162 | 162 | usb_controller, NULL, 0)); |
163 | - if (board_usb_init(controller_index, USB_INIT_DEVICE)) { | |
163 | + if (usb_gadget_initialize(controller_index)) { | |
164 | 164 | pr_err("Couldn't init USB controller.\n"); |
165 | 165 | rc = CMD_RET_FAILURE; |
166 | 166 | goto cleanup_ums_init; |
... | ... | @@ -231,7 +231,7 @@ |
231 | 231 | cleanup_register: |
232 | 232 | g_dnl_unregister(); |
233 | 233 | cleanup_board: |
234 | - board_usb_cleanup(controller_index, USB_INIT_DEVICE); | |
234 | + usb_gadget_release(controller_index); | |
235 | 235 | cleanup_ums_init: |
236 | 236 | ums_fini(); |
237 | 237 |
common/dfu.c
... | ... | @@ -23,9 +23,9 @@ |
23 | 23 | bool dfu_reset = false; |
24 | 24 | int ret, i = 0; |
25 | 25 | |
26 | - ret = board_usb_init(usbctrl_index, USB_INIT_DEVICE); | |
26 | + ret = usb_gadget_initialize(usbctrl_index); | |
27 | 27 | if (ret) { |
28 | - pr_err("board usb init failed\n"); | |
28 | + pr_err("usb_gadget_initialize failed\n"); | |
29 | 29 | return CMD_RET_FAILURE; |
30 | 30 | } |
31 | 31 | g_dnl_clear_detach(); |
... | ... | @@ -84,7 +84,7 @@ |
84 | 84 | } |
85 | 85 | exit: |
86 | 86 | g_dnl_unregister(); |
87 | - board_usb_cleanup(usbctrl_index, USB_INIT_DEVICE); | |
87 | + usb_gadget_release(usbctrl_index); | |
88 | 88 | |
89 | 89 | if (dfu_reset) |
90 | 90 | do_reset(NULL, 0, 0, NULL); |
configs/am57xx_evm_defconfig
... | ... | @@ -50,6 +50,7 @@ |
50 | 50 | CONFIG_FASTBOOT_CMD_OEM_FORMAT=y |
51 | 51 | CONFIG_DM_GPIO=y |
52 | 52 | CONFIG_DM_I2C=y |
53 | +CONFIG_MISC=y | |
53 | 54 | CONFIG_DM_MMC=y |
54 | 55 | CONFIG_MMC_OMAP_HS=y |
55 | 56 | CONFIG_DM_SPI_FLASH=y |
... | ... | @@ -61,6 +62,9 @@ |
61 | 62 | CONFIG_DM_ETH=y |
62 | 63 | CONFIG_DRIVER_TI_CPSW=y |
63 | 64 | CONFIG_MII=y |
65 | +CONFIG_PHY=y | |
66 | +CONFIG_PIPE3_PHY=y | |
67 | +CONFIG_OMAP_USB2_PHY=y | |
64 | 68 | CONFIG_DM_PMIC=y |
65 | 69 | CONFIG_PMIC_PALMAS=y |
66 | 70 | CONFIG_DM_REGULATOR=y |
67 | 71 | |
... | ... | @@ -70,13 +74,15 @@ |
70 | 74 | CONFIG_DM_SPI=y |
71 | 75 | CONFIG_TI_QSPI=y |
72 | 76 | CONFIG_USB=y |
77 | +CONFIG_DM_USB=y | |
78 | +CONFIG_SPL_DM_USB=y | |
79 | +CONFIG_DM_USB_GADGET=y | |
80 | +CONFIG_SPL_DM_USB_GADGET=y | |
73 | 81 | CONFIG_USB_XHCI_HCD=y |
74 | 82 | CONFIG_USB_XHCI_DWC3=y |
75 | 83 | CONFIG_USB_DWC3=y |
76 | 84 | CONFIG_USB_DWC3_GADGET=y |
77 | -CONFIG_USB_DWC3_OMAP=y | |
78 | -CONFIG_USB_DWC3_PHY_OMAP=y | |
79 | -CONFIG_OMAP_USB_PHY=y | |
85 | +CONFIG_USB_DWC3_GENERIC=y | |
80 | 86 | CONFIG_USB_STORAGE=y |
81 | 87 | CONFIG_USB_GADGET=y |
82 | 88 | CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" |
configs/am57xx_hs_evm_defconfig
... | ... | @@ -53,6 +53,7 @@ |
53 | 53 | CONFIG_FASTBOOT_CMD_OEM_FORMAT=y |
54 | 54 | CONFIG_DM_GPIO=y |
55 | 55 | CONFIG_DM_I2C=y |
56 | +CONFIG_MISC=y | |
56 | 57 | CONFIG_DM_MMC=y |
57 | 58 | CONFIG_MMC_OMAP_HS=y |
58 | 59 | CONFIG_DM_SPI_FLASH=y |
... | ... | @@ -64,6 +65,9 @@ |
64 | 65 | CONFIG_DM_ETH=y |
65 | 66 | CONFIG_DRIVER_TI_CPSW=y |
66 | 67 | CONFIG_MII=y |
68 | +CONFIG_PHY=y | |
69 | +CONFIG_PIPE3_PHY=y | |
70 | +CONFIG_OMAP_USB2_PHY=y | |
67 | 71 | CONFIG_DM_PMIC=y |
68 | 72 | CONFIG_PMIC_PALMAS=y |
69 | 73 | CONFIG_DM_REGULATOR=y |
70 | 74 | |
... | ... | @@ -73,13 +77,15 @@ |
73 | 77 | CONFIG_DM_SPI=y |
74 | 78 | CONFIG_TI_QSPI=y |
75 | 79 | CONFIG_USB=y |
80 | +CONFIG_DM_USB=y | |
81 | +CONFIG_SPL_DM_USB=y | |
82 | +CONFIG_DM_USB_GADGET=y | |
83 | +CONFIG_SPL_DM_USB_GADGET=y | |
76 | 84 | CONFIG_USB_XHCI_HCD=y |
77 | 85 | CONFIG_USB_XHCI_DWC3=y |
78 | 86 | CONFIG_USB_DWC3=y |
79 | 87 | CONFIG_USB_DWC3_GADGET=y |
80 | -CONFIG_USB_DWC3_OMAP=y | |
81 | -CONFIG_USB_DWC3_PHY_OMAP=y | |
82 | -CONFIG_OMAP_USB_PHY=y | |
88 | +CONFIG_USB_DWC3_GENERIC=y | |
83 | 89 | CONFIG_USB_STORAGE=y |
84 | 90 | CONFIG_USB_GADGET=y |
85 | 91 | CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" |
configs/dra7xx_evm_defconfig
... | ... | @@ -56,6 +56,7 @@ |
56 | 56 | CONFIG_DM_GPIO=y |
57 | 57 | CONFIG_PCF8575_GPIO=y |
58 | 58 | CONFIG_DM_I2C=y |
59 | +CONFIG_MISC=y | |
59 | 60 | CONFIG_DM_MMC=y |
60 | 61 | CONFIG_MMC_IO_VOLTAGE=y |
61 | 62 | CONFIG_MMC_UHS_SUPPORT=y |
... | ... | @@ -72,6 +73,7 @@ |
72 | 73 | CONFIG_MII=y |
73 | 74 | CONFIG_SPL_PHY=y |
74 | 75 | CONFIG_PIPE3_PHY=y |
76 | +CONFIG_OMAP_USB2_PHY=y | |
75 | 77 | CONFIG_PMIC_PALMAS=y |
76 | 78 | CONFIG_PMIC_LP873X=y |
77 | 79 | CONFIG_DM_REGULATOR_FIXED=y |
78 | 80 | |
79 | 81 | |
... | ... | @@ -87,14 +89,14 @@ |
87 | 89 | CONFIG_OMAP_TIMER=y |
88 | 90 | CONFIG_USB=y |
89 | 91 | CONFIG_DM_USB=y |
92 | +CONFIG_SPL_DM_USB=y | |
93 | +CONFIG_DM_USB_GADGET=y | |
94 | +CONFIG_SPL_DM_USB_GADGET=y | |
90 | 95 | CONFIG_USB_XHCI_HCD=y |
91 | 96 | CONFIG_USB_XHCI_DWC3=y |
92 | -CONFIG_USB_XHCI_DRA7XX_INDEX=1 | |
93 | 97 | CONFIG_USB_DWC3=y |
94 | 98 | CONFIG_USB_DWC3_GADGET=y |
95 | -CONFIG_USB_DWC3_OMAP=y | |
96 | -CONFIG_USB_DWC3_PHY_OMAP=y | |
97 | -CONFIG_OMAP_USB_PHY=y | |
99 | +CONFIG_USB_DWC3_GENERIC=y | |
98 | 100 | CONFIG_USB_STORAGE=y |
99 | 101 | CONFIG_USB_GADGET=y |
100 | 102 | CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" |
configs/dra7xx_hs_evm_defconfig
... | ... | @@ -56,6 +56,7 @@ |
56 | 56 | CONFIG_DM_GPIO=y |
57 | 57 | CONFIG_PCF8575_GPIO=y |
58 | 58 | CONFIG_DM_I2C=y |
59 | +CONFIG_MISC=y | |
59 | 60 | CONFIG_DM_MMC=y |
60 | 61 | CONFIG_MMC_IO_VOLTAGE=y |
61 | 62 | CONFIG_MMC_UHS_SUPPORT=y |
... | ... | @@ -71,6 +72,7 @@ |
71 | 72 | CONFIG_MII=y |
72 | 73 | CONFIG_SPL_PHY=y |
73 | 74 | CONFIG_PIPE3_PHY=y |
75 | +CONFIG_OMAP_USB2_PHY=y | |
74 | 76 | CONFIG_PMIC_PALMAS=y |
75 | 77 | CONFIG_PMIC_LP873X=y |
76 | 78 | CONFIG_DM_REGULATOR_FIXED=y |
77 | 79 | |
78 | 80 | |
... | ... | @@ -86,14 +88,14 @@ |
86 | 88 | CONFIG_OMAP_TIMER=y |
87 | 89 | CONFIG_USB=y |
88 | 90 | CONFIG_DM_USB=y |
91 | +CONFIG_SPL_DM_USB=y | |
92 | +CONFIG_DM_USB_GADGET=y | |
93 | +CONFIG_SPL_DM_USB_GADGET=y | |
89 | 94 | CONFIG_USB_XHCI_HCD=y |
90 | 95 | CONFIG_USB_XHCI_DWC3=y |
91 | -CONFIG_USB_XHCI_DRA7XX_INDEX=1 | |
92 | 96 | CONFIG_USB_DWC3=y |
93 | 97 | CONFIG_USB_DWC3_GADGET=y |
94 | -CONFIG_USB_DWC3_OMAP=y | |
95 | -CONFIG_USB_DWC3_PHY_OMAP=y | |
96 | -CONFIG_OMAP_USB_PHY=y | |
98 | +CONFIG_USB_DWC3_GENERIC=y | |
97 | 99 | CONFIG_USB_STORAGE=y |
98 | 100 | CONFIG_USB_GADGET=y |
99 | 101 | CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" |
configs/evb-rk3328_defconfig
drivers/core/syscon-uclass.c
... | ... | @@ -53,6 +53,29 @@ |
53 | 53 | #endif |
54 | 54 | } |
55 | 55 | |
56 | +struct regmap *syscon_regmap_lookup_by_phandle(struct udevice *dev, | |
57 | + const char *name) | |
58 | +{ | |
59 | + struct udevice *syscon; | |
60 | + struct regmap *r; | |
61 | + int err; | |
62 | + | |
63 | + err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, | |
64 | + name, &syscon); | |
65 | + if (err) { | |
66 | + dev_dbg(dev, "unable to find syscon device\n"); | |
67 | + return ERR_PTR(err); | |
68 | + } | |
69 | + | |
70 | + r = syscon_get_regmap(syscon); | |
71 | + if (!r) { | |
72 | + dev_dbg(dev, "unable to find regmap\n"); | |
73 | + return ERR_PTR(-ENODEV); | |
74 | + } | |
75 | + | |
76 | + return r; | |
77 | +} | |
78 | + | |
56 | 79 | int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp) |
57 | 80 | { |
58 | 81 | struct udevice *dev; |
drivers/phy/Kconfig
... | ... | @@ -155,5 +155,14 @@ |
155 | 155 | |
156 | 156 | This PHY is found on qualcomm dragonboard410c development board. |
157 | 157 | |
158 | +config OMAP_USB2_PHY | |
159 | + bool "Support OMAP's USB2 PHY" | |
160 | + depends on PHY | |
161 | + depends on SYSCON | |
162 | + help | |
163 | + Support for the OMAP's USB2 PHY. | |
164 | + | |
165 | + This PHY is found on OMAP devices supporting USB2. | |
166 | + | |
158 | 167 | endmenu |
drivers/phy/Makefile
drivers/phy/omap-usb2-phy.c
1 | +// SPDX-License-Identifier: GPL-2.0+ | |
2 | +/* | |
3 | + * OMAP USB2 PHY LAYER | |
4 | + * | |
5 | + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com | |
6 | + * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> | |
7 | + */ | |
8 | + | |
9 | +#include <common.h> | |
10 | +#include <asm/io.h> | |
11 | +#include <dm.h> | |
12 | +#include <errno.h> | |
13 | +#include <generic-phy.h> | |
14 | +#include <regmap.h> | |
15 | +#include <syscon.h> | |
16 | + | |
17 | +#define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT BIT(0) | |
18 | + | |
19 | +#define OMAP_DEV_PHY_PD BIT(0) | |
20 | +#define OMAP_USB2_PHY_PD BIT(28) | |
21 | + | |
22 | +#define USB2PHY_DISCON_BYP_LATCH BIT(31) | |
23 | +#define USB2PHY_ANA_CONFIG1 (0x4c) | |
24 | + | |
25 | +DECLARE_GLOBAL_DATA_PTR; | |
26 | + | |
27 | +struct omap_usb2_phy { | |
28 | + struct regmap *pwr_regmap; | |
29 | + ulong flags; | |
30 | + void *phy_base; | |
31 | + u32 pwr_reg_offset; | |
32 | +}; | |
33 | + | |
34 | +struct usb_phy_data { | |
35 | + const char *label; | |
36 | + u8 flags; | |
37 | + u32 mask; | |
38 | + u32 power_on; | |
39 | + u32 power_off; | |
40 | +}; | |
41 | + | |
42 | +static const struct usb_phy_data omap5_usb2_data = { | |
43 | + .label = "omap5_usb2", | |
44 | + .flags = 0, | |
45 | + .mask = OMAP_DEV_PHY_PD, | |
46 | + .power_off = OMAP_DEV_PHY_PD, | |
47 | +}; | |
48 | + | |
49 | +static const struct usb_phy_data dra7x_usb2_data = { | |
50 | + .label = "dra7x_usb2", | |
51 | + .flags = OMAP_USB2_CALIBRATE_FALSE_DISCONNECT, | |
52 | + .mask = OMAP_DEV_PHY_PD, | |
53 | + .power_off = OMAP_DEV_PHY_PD, | |
54 | +}; | |
55 | + | |
56 | +static const struct usb_phy_data dra7x_usb2_phy2_data = { | |
57 | + .label = "dra7x_usb2_phy2", | |
58 | + .flags = OMAP_USB2_CALIBRATE_FALSE_DISCONNECT, | |
59 | + .mask = OMAP_USB2_PHY_PD, | |
60 | + .power_off = OMAP_USB2_PHY_PD, | |
61 | +}; | |
62 | + | |
63 | +static const struct udevice_id omap_usb2_id_table[] = { | |
64 | + { | |
65 | + .compatible = "ti,omap5-usb2", | |
66 | + .data = (ulong)&omap5_usb2_data, | |
67 | + }, | |
68 | + { | |
69 | + .compatible = "ti,dra7x-usb2", | |
70 | + .data = (ulong)&dra7x_usb2_data, | |
71 | + }, | |
72 | + { | |
73 | + .compatible = "ti,dra7x-usb2-phy2", | |
74 | + .data = (ulong)&dra7x_usb2_phy2_data, | |
75 | + }, | |
76 | + {}, | |
77 | +}; | |
78 | + | |
79 | +static int omap_usb_phy_power(struct phy *usb_phy, bool on) | |
80 | +{ | |
81 | + struct udevice *dev = usb_phy->dev; | |
82 | + const struct usb_phy_data *data; | |
83 | + const struct omap_usb2_phy *phy = dev_get_priv(dev); | |
84 | + u32 val; | |
85 | + int rc; | |
86 | + | |
87 | + data = (const struct usb_phy_data *)dev_get_driver_data(dev); | |
88 | + if (!data) | |
89 | + return -EINVAL; | |
90 | + | |
91 | + rc = regmap_read(phy->pwr_regmap, phy->pwr_reg_offset, &val); | |
92 | + if (rc) | |
93 | + return rc; | |
94 | + val &= ~data->mask; | |
95 | + if (on) | |
96 | + val |= data->power_on; | |
97 | + else | |
98 | + val |= data->power_off; | |
99 | + rc = regmap_write(phy->pwr_regmap, phy->pwr_reg_offset, val); | |
100 | + if (rc) | |
101 | + return rc; | |
102 | + | |
103 | + return 0; | |
104 | +} | |
105 | + | |
106 | +static int omap_usb2_phy_init(struct phy *usb_phy) | |
107 | +{ | |
108 | + struct udevice *dev = usb_phy->dev; | |
109 | + struct omap_usb2_phy *priv = dev_get_priv(dev); | |
110 | + u32 val; | |
111 | + | |
112 | + if (priv->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { | |
113 | + /* | |
114 | + * | |
115 | + * Reduce the sensitivity of internal PHY by enabling the | |
116 | + * DISCON_BYP_LATCH of the USB2PHY_ANA_CONFIG1 register. This | |
117 | + * resolves issues with certain devices which can otherwise | |
118 | + * be prone to false disconnects. | |
119 | + * | |
120 | + */ | |
121 | + val = readl(priv->phy_base + USB2PHY_ANA_CONFIG1); | |
122 | + val |= USB2PHY_DISCON_BYP_LATCH; | |
123 | + writel(val, priv->phy_base + USB2PHY_ANA_CONFIG1); | |
124 | + } | |
125 | + | |
126 | + return 0; | |
127 | +} | |
128 | + | |
129 | +static int omap_usb2_phy_power_on(struct phy *usb_phy) | |
130 | +{ | |
131 | + return omap_usb_phy_power(usb_phy, true); | |
132 | +} | |
133 | + | |
134 | +static int omap_usb2_phy_power_off(struct phy *usb_phy) | |
135 | +{ | |
136 | + return omap_usb_phy_power(usb_phy, false); | |
137 | +} | |
138 | + | |
139 | +static int omap_usb2_phy_exit(struct phy *usb_phy) | |
140 | +{ | |
141 | + return omap_usb_phy_power(usb_phy, false); | |
142 | +} | |
143 | + | |
144 | +struct phy_ops omap_usb2_phy_ops = { | |
145 | + .init = omap_usb2_phy_init, | |
146 | + .power_on = omap_usb2_phy_power_on, | |
147 | + .power_off = omap_usb2_phy_power_off, | |
148 | + .exit = omap_usb2_phy_exit, | |
149 | +}; | |
150 | + | |
151 | +int omap_usb2_phy_probe(struct udevice *dev) | |
152 | +{ | |
153 | + int rc; | |
154 | + struct regmap *regmap; | |
155 | + struct omap_usb2_phy *priv = dev_get_priv(dev); | |
156 | + const struct usb_phy_data *data; | |
157 | + u32 tmp[2]; | |
158 | + | |
159 | + data = (const struct usb_phy_data *)dev_get_driver_data(dev); | |
160 | + if (!data) | |
161 | + return -EINVAL; | |
162 | + | |
163 | + if (data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { | |
164 | + u32 base = dev_read_addr(dev); | |
165 | + | |
166 | + if (base == FDT_ADDR_T_NONE) | |
167 | + return -EINVAL; | |
168 | + priv->phy_base = (void *)base; | |
169 | + priv->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT; | |
170 | + } | |
171 | + | |
172 | + regmap = syscon_regmap_lookup_by_phandle(dev, "syscon-phy-power"); | |
173 | + if (IS_ERR(regmap)) { | |
174 | + printf("can't get regmap (err %ld)\n", PTR_ERR(regmap)); | |
175 | + return PTR_ERR(regmap); | |
176 | + } | |
177 | + priv->pwr_regmap = regmap; | |
178 | + | |
179 | + rc = dev_read_u32_array(dev, "syscon-phy-power", tmp, 2); | |
180 | + if (rc) { | |
181 | + printf("couldn't get power reg. offset (err %d)\n", rc); | |
182 | + return rc; | |
183 | + } | |
184 | + priv->pwr_reg_offset = tmp[1]; | |
185 | + | |
186 | + return 0; | |
187 | +} | |
188 | + | |
189 | +U_BOOT_DRIVER(omap_usb2_phy) = { | |
190 | + .name = "omap_usb2_phy", | |
191 | + .id = UCLASS_PHY, | |
192 | + .of_match = omap_usb2_id_table, | |
193 | + .probe = omap_usb2_phy_probe, | |
194 | + .ops = &omap_usb2_phy_ops, | |
195 | + .priv_auto_alloc_size = sizeof(struct omap_usb2_phy), | |
196 | +}; |
drivers/phy/ti-pipe3-phy.c
... | ... | @@ -141,7 +141,7 @@ |
141 | 141 | omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_CONFIGURATION1, val); |
142 | 142 | |
143 | 143 | val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_CONFIGURATION2); |
144 | - val &= ~PLL_SELFREQDCO_MASK; | |
144 | + val &= ~(PLL_SELFREQDCO_MASK | PLL_IDLE); | |
145 | 145 | val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; |
146 | 146 | omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_CONFIGURATION2, val); |
147 | 147 | |
... | ... | @@ -265,10 +265,13 @@ |
265 | 265 | return -EBUSY; |
266 | 266 | } |
267 | 267 | |
268 | - val = readl(pipe3->pll_reset_reg); | |
269 | - writel(val | SATA_PLL_SOFT_RESET, pipe3->pll_reset_reg); | |
270 | - mdelay(1); | |
271 | - writel(val & ~SATA_PLL_SOFT_RESET, pipe3->pll_reset_reg); | |
268 | + if (pipe3->pll_reset_reg) { | |
269 | + val = readl(pipe3->pll_reset_reg); | |
270 | + writel(val | SATA_PLL_SOFT_RESET, pipe3->pll_reset_reg); | |
271 | + mdelay(1); | |
272 | + writel(val & ~SATA_PLL_SOFT_RESET, pipe3->pll_reset_reg); | |
273 | + } | |
274 | + | |
272 | 275 | return 0; |
273 | 276 | } |
274 | 277 | |
... | ... | @@ -331,9 +334,11 @@ |
331 | 334 | if (!pipe3->power_reg) |
332 | 335 | return -EINVAL; |
333 | 336 | |
334 | - pipe3->pll_reset_reg = get_reg(dev, "syscon-pllreset"); | |
335 | - if (!pipe3->pll_reset_reg) | |
336 | - return -EINVAL; | |
337 | + if (device_is_compatible(dev, "ti,phy-pipe3-sata")) { | |
338 | + pipe3->pll_reset_reg = get_reg(dev, "syscon-pllreset"); | |
339 | + if (!pipe3->pll_reset_reg) | |
340 | + return -EINVAL; | |
341 | + } | |
337 | 342 | |
338 | 343 | pipe3->dpll_map = (struct pipe3_dpll_map *)dev_get_driver_data(dev); |
339 | 344 | |
340 | 345 | |
... | ... | @@ -350,8 +355,19 @@ |
350 | 355 | { }, /* Terminator */ |
351 | 356 | }; |
352 | 357 | |
358 | +static struct pipe3_dpll_map dpll_map_usb[] = { | |
359 | + {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */ | |
360 | + {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */ | |
361 | + {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */ | |
362 | + {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */ | |
363 | + {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */ | |
364 | + {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */ | |
365 | + { }, /* Terminator */ | |
366 | +}; | |
367 | + | |
353 | 368 | static const struct udevice_id pipe3_phy_ids[] = { |
354 | 369 | { .compatible = "ti,phy-pipe3-sata", .data = (ulong)&dpll_map_sata }, |
370 | + { .compatible = "ti,omap-usb3", .data = (ulong)&dpll_map_usb}, | |
355 | 371 | { } |
356 | 372 | }; |
357 | 373 |
drivers/usb/Kconfig
... | ... | @@ -52,6 +52,20 @@ |
52 | 52 | depends on DM_USB |
53 | 53 | default y |
54 | 54 | |
55 | +config DM_USB_GADGET | |
56 | + bool "Enable driver model for USB Gadget" | |
57 | + depends on DM_USB | |
58 | + help | |
59 | + Enable driver model for USB Gadget (Peripheral | |
60 | + mode) | |
61 | + | |
62 | +config SPL_DM_USB_GADGET | |
63 | + bool "Enable driver model for USB Gadget in sPL" | |
64 | + depends on SPL_DM_USB | |
65 | + help | |
66 | + Enable driver model for USB Gadget in SPL | |
67 | + (Peripheral mode) | |
68 | + | |
55 | 69 | source "drivers/usb/host/Kconfig" |
56 | 70 | |
57 | 71 | source "drivers/usb/dwc3/Kconfig" |
drivers/usb/dwc3/Kconfig
... | ... | @@ -38,10 +38,11 @@ |
38 | 38 | Say 'Y' here if you have one such device |
39 | 39 | |
40 | 40 | config USB_DWC3_GENERIC |
41 | - bool "Xilinx ZynqMP and similar Platforms" | |
42 | - depends on DM_USB && USB_DWC3 | |
41 | + bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)" | |
42 | + depends on DM_USB && USB_DWC3 && MISC | |
43 | 43 | help |
44 | - Some platforms can reuse this DWC3 generic implementation. | |
44 | + Select this for Xilinx ZynqMP and similar Platforms. | |
45 | + This wrapper supports Host and Peripheral operation modes. | |
45 | 46 | |
46 | 47 | config USB_DWC3_UNIPHIER |
47 | 48 | bool "DesignWare USB3 Host Support on UniPhier Platforms" |
drivers/usb/dwc3/core.c
... | ... | @@ -19,7 +19,7 @@ |
19 | 19 | #include <asm/dma-mapping.h> |
20 | 20 | #include <linux/ioport.h> |
21 | 21 | #include <dm.h> |
22 | - | |
22 | +#include <generic-phy.h> | |
23 | 23 | #include <linux/usb/ch9.h> |
24 | 24 | #include <linux/usb/gadget.h> |
25 | 25 | |
26 | 26 | |
... | ... | @@ -789,8 +789,92 @@ |
789 | 789 | MODULE_LICENSE("GPL v2"); |
790 | 790 | MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver"); |
791 | 791 | |
792 | -#if CONFIG_IS_ENABLED(DM_USB) | |
792 | +#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB) | |
793 | +int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys) | |
794 | +{ | |
795 | + int i, ret, count; | |
796 | + struct phy *usb_phys; | |
793 | 797 | |
798 | + /* Return if no phy declared */ | |
799 | + if (!dev_read_prop(dev, "phys", NULL)) | |
800 | + return 0; | |
801 | + count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); | |
802 | + if (count <= 0) | |
803 | + return count; | |
804 | + | |
805 | + usb_phys = devm_kcalloc(dev, count, sizeof(struct phy), | |
806 | + GFP_KERNEL); | |
807 | + if (!usb_phys) | |
808 | + return -ENOMEM; | |
809 | + | |
810 | + for (i = 0; i < count; i++) { | |
811 | + ret = generic_phy_get_by_index(dev, i, &usb_phys[i]); | |
812 | + if (ret && ret != -ENOENT) { | |
813 | + pr_err("Failed to get USB PHY%d for %s\n", | |
814 | + i, dev->name); | |
815 | + return ret; | |
816 | + } | |
817 | + } | |
818 | + | |
819 | + for (i = 0; i < count; i++) { | |
820 | + ret = generic_phy_init(&usb_phys[i]); | |
821 | + if (ret) { | |
822 | + pr_err("Can't init USB PHY%d for %s\n", | |
823 | + i, dev->name); | |
824 | + goto phys_init_err; | |
825 | + } | |
826 | + } | |
827 | + | |
828 | + for (i = 0; i < count; i++) { | |
829 | + ret = generic_phy_power_on(&usb_phys[i]); | |
830 | + if (ret) { | |
831 | + pr_err("Can't power USB PHY%d for %s\n", | |
832 | + i, dev->name); | |
833 | + goto phys_poweron_err; | |
834 | + } | |
835 | + } | |
836 | + | |
837 | + *array = usb_phys; | |
838 | + *num_phys = count; | |
839 | + return 0; | |
840 | + | |
841 | +phys_poweron_err: | |
842 | + for (i = count - 1; i >= 0; i--) | |
843 | + generic_phy_power_off(&usb_phys[i]); | |
844 | + | |
845 | + for (i = 0; i < count; i++) | |
846 | + generic_phy_exit(&usb_phys[i]); | |
847 | + | |
848 | + return ret; | |
849 | + | |
850 | +phys_init_err: | |
851 | + for (; i >= 0; i--) | |
852 | + generic_phy_exit(&usb_phys[i]); | |
853 | + | |
854 | + return ret; | |
855 | +} | |
856 | + | |
857 | +int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys) | |
858 | +{ | |
859 | + int i, ret; | |
860 | + | |
861 | + for (i = 0; i < num_phys; i++) { | |
862 | + if (!generic_phy_valid(&usb_phys[i])) | |
863 | + continue; | |
864 | + | |
865 | + ret = generic_phy_power_off(&usb_phys[i]); | |
866 | + ret |= generic_phy_exit(&usb_phys[i]); | |
867 | + if (ret) { | |
868 | + pr_err("Can't shutdown USB PHY%d for %s\n", | |
869 | + i, dev->name); | |
870 | + } | |
871 | + } | |
872 | + | |
873 | + return 0; | |
874 | +} | |
875 | +#endif | |
876 | + | |
877 | +#if CONFIG_IS_ENABLED(DM_USB_GADGET) | |
794 | 878 | int dwc3_init(struct dwc3 *dwc) |
795 | 879 | { |
796 | 880 | int ret; |
... | ... | @@ -841,6 +925,5 @@ |
841 | 925 | dwc3_core_exit(dwc); |
842 | 926 | kfree(dwc->mem); |
843 | 927 | } |
844 | - | |
845 | 928 | #endif |
drivers/usb/dwc3/dwc3-generic.c
... | ... | @@ -8,72 +8,89 @@ |
8 | 8 | */ |
9 | 9 | |
10 | 10 | #include <common.h> |
11 | +#include <asm-generic/io.h> | |
11 | 12 | #include <dm.h> |
12 | 13 | #include <dm/device-internal.h> |
13 | 14 | #include <dm/lists.h> |
14 | -#include <linux/usb/otg.h> | |
15 | -#include <linux/compat.h> | |
15 | +#include <dwc3-uboot.h> | |
16 | 16 | #include <linux/usb/ch9.h> |
17 | 17 | #include <linux/usb/gadget.h> |
18 | 18 | #include <malloc.h> |
19 | 19 | #include <usb.h> |
20 | 20 | #include "core.h" |
21 | 21 | #include "gadget.h" |
22 | -#include "linux-compat.h" | |
22 | +#include <reset.h> | |
23 | +#include <clk.h> | |
23 | 24 | |
24 | -DECLARE_GLOBAL_DATA_PTR; | |
25 | +#if CONFIG_IS_ENABLED(DM_USB_GADGET) | |
26 | +struct dwc3_generic_peripheral { | |
27 | + struct dwc3 dwc3; | |
28 | + struct phy *phys; | |
29 | + int num_phys; | |
30 | + fdt_addr_t base; | |
31 | +}; | |
25 | 32 | |
26 | -int usb_gadget_handle_interrupts(int index) | |
33 | +int dm_usb_gadget_handle_interrupts(struct udevice *dev) | |
27 | 34 | { |
28 | - struct dwc3 *priv; | |
29 | - struct udevice *dev; | |
30 | - int ret; | |
35 | + struct dwc3_generic_peripheral *priv = dev_get_priv(dev); | |
36 | + struct dwc3 *dwc3 = &priv->dwc3; | |
31 | 37 | |
32 | - ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &dev); | |
33 | - if (!dev || ret) { | |
34 | - pr_err("No USB device found\n"); | |
35 | - return -ENODEV; | |
36 | - } | |
38 | + dwc3_gadget_uboot_handle_interrupt(dwc3); | |
37 | 39 | |
38 | - priv = dev_get_priv(dev); | |
39 | - | |
40 | - dwc3_gadget_uboot_handle_interrupt(priv); | |
41 | - | |
42 | 40 | return 0; |
43 | 41 | } |
44 | 42 | |
45 | 43 | static int dwc3_generic_peripheral_probe(struct udevice *dev) |
46 | 44 | { |
47 | - struct dwc3 *priv = dev_get_priv(dev); | |
45 | + int rc; | |
46 | + struct dwc3_generic_peripheral *priv = dev_get_priv(dev); | |
47 | + struct dwc3 *dwc3 = &priv->dwc3; | |
48 | 48 | |
49 | - return dwc3_init(priv); | |
49 | + rc = dwc3_setup_phy(dev, &priv->phys, &priv->num_phys); | |
50 | + if (rc) | |
51 | + return rc; | |
52 | + | |
53 | + dwc3->regs = map_physmem(priv->base, DWC3_OTG_REGS_END, MAP_NOCACHE); | |
54 | + dwc3->regs += DWC3_GLOBALS_REGS_START; | |
55 | + dwc3->dev = dev; | |
56 | + | |
57 | + rc = dwc3_init(dwc3); | |
58 | + if (rc) { | |
59 | + unmap_physmem(dwc3->regs, MAP_NOCACHE); | |
60 | + return rc; | |
61 | + } | |
62 | + | |
63 | + return 0; | |
50 | 64 | } |
51 | 65 | |
52 | 66 | static int dwc3_generic_peripheral_remove(struct udevice *dev) |
53 | 67 | { |
54 | - struct dwc3 *priv = dev_get_priv(dev); | |
68 | + struct dwc3_generic_peripheral *priv = dev_get_priv(dev); | |
69 | + struct dwc3 *dwc3 = &priv->dwc3; | |
55 | 70 | |
56 | - dwc3_remove(priv); | |
71 | + dwc3_remove(dwc3); | |
72 | + dwc3_shutdown_phy(dev, priv->phys, priv->num_phys); | |
73 | + unmap_physmem(dwc3->regs, MAP_NOCACHE); | |
57 | 74 | |
58 | 75 | return 0; |
59 | 76 | } |
60 | 77 | |
61 | 78 | static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev) |
62 | 79 | { |
63 | - struct dwc3 *priv = dev_get_priv(dev); | |
80 | + struct dwc3_generic_peripheral *priv = dev_get_priv(dev); | |
81 | + struct dwc3 *dwc3 = &priv->dwc3; | |
64 | 82 | int node = dev_of_offset(dev); |
65 | 83 | |
66 | - priv->regs = (void *)devfdt_get_addr(dev); | |
67 | - priv->regs += DWC3_GLOBALS_REGS_START; | |
84 | + priv->base = devfdt_get_addr(dev); | |
68 | 85 | |
69 | - priv->maximum_speed = usb_get_maximum_speed(node); | |
70 | - if (priv->maximum_speed == USB_SPEED_UNKNOWN) { | |
86 | + dwc3->maximum_speed = usb_get_maximum_speed(node); | |
87 | + if (dwc3->maximum_speed == USB_SPEED_UNKNOWN) { | |
71 | 88 | pr_err("Invalid usb maximum speed\n"); |
72 | 89 | return -ENODEV; |
73 | 90 | } |
74 | 91 | |
75 | - priv->dr_mode = usb_get_dr_mode(node); | |
76 | - if (priv->dr_mode == USB_DR_MODE_UNKNOWN) { | |
92 | + dwc3->dr_mode = usb_get_dr_mode(node); | |
93 | + if (dwc3->dr_mode == USB_DR_MODE_UNKNOWN) { | |
77 | 94 | pr_err("Invalid usb mode setup\n"); |
78 | 95 | return -ENODEV; |
79 | 96 | } |
80 | 97 | |
81 | 98 | |
82 | 99 | |
83 | 100 | |
84 | 101 | |
... | ... | @@ -81,25 +98,113 @@ |
81 | 98 | return 0; |
82 | 99 | } |
83 | 100 | |
84 | -static int dwc3_generic_peripheral_bind(struct udevice *dev) | |
85 | -{ | |
86 | - return device_probe(dev); | |
87 | -} | |
88 | - | |
89 | 101 | U_BOOT_DRIVER(dwc3_generic_peripheral) = { |
90 | 102 | .name = "dwc3-generic-peripheral", |
91 | - .id = UCLASS_USB_DEV_GENERIC, | |
103 | + .id = UCLASS_USB_GADGET_GENERIC, | |
92 | 104 | .ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata, |
93 | 105 | .probe = dwc3_generic_peripheral_probe, |
94 | 106 | .remove = dwc3_generic_peripheral_remove, |
95 | - .bind = dwc3_generic_peripheral_bind, | |
96 | - .platdata_auto_alloc_size = sizeof(struct usb_platdata), | |
97 | - .priv_auto_alloc_size = sizeof(struct dwc3), | |
98 | - .flags = DM_FLAG_ALLOC_PRIV_DMA, | |
107 | + .priv_auto_alloc_size = sizeof(struct dwc3_generic_peripheral), | |
99 | 108 | }; |
109 | +#endif | |
100 | 110 | |
101 | -static int dwc3_generic_bind(struct udevice *parent) | |
111 | +struct dwc3_glue_data { | |
112 | + struct clk_bulk clks; | |
113 | + struct reset_ctl_bulk resets; | |
114 | + fdt_addr_t regs; | |
115 | +}; | |
116 | + | |
117 | +struct dwc3_glue_ops { | |
118 | + void (*select_dr_mode)(struct udevice *dev, int index, | |
119 | + enum usb_dr_mode mode); | |
120 | +}; | |
121 | + | |
122 | +void dwc3_ti_select_dr_mode(struct udevice *dev, int index, | |
123 | + enum usb_dr_mode mode) | |
102 | 124 | { |
125 | +#define USBOTGSS_UTMI_OTG_STATUS 0x0084 | |
126 | +#define USBOTGSS_UTMI_OTG_OFFSET 0x0480 | |
127 | + | |
128 | +/* UTMI_OTG_STATUS REGISTER */ | |
129 | +#define USBOTGSS_UTMI_OTG_STATUS_SW_MODE BIT(31) | |
130 | +#define USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT BIT(9) | |
131 | +#define USBOTGSS_UTMI_OTG_STATUS_TXBITSTUFFENABLE BIT(8) | |
132 | +#define USBOTGSS_UTMI_OTG_STATUS_IDDIG BIT(4) | |
133 | +#define USBOTGSS_UTMI_OTG_STATUS_SESSEND BIT(3) | |
134 | +#define USBOTGSS_UTMI_OTG_STATUS_SESSVALID BIT(2) | |
135 | +#define USBOTGSS_UTMI_OTG_STATUS_VBUSVALID BIT(1) | |
136 | +enum dwc3_omap_utmi_mode { | |
137 | + DWC3_OMAP_UTMI_MODE_UNKNOWN = 0, | |
138 | + DWC3_OMAP_UTMI_MODE_HW, | |
139 | + DWC3_OMAP_UTMI_MODE_SW, | |
140 | +}; | |
141 | + | |
142 | + u32 use_id_pin; | |
143 | + u32 host_mode; | |
144 | + u32 reg; | |
145 | + u32 utmi_mode; | |
146 | + u32 utmi_status_offset = USBOTGSS_UTMI_OTG_STATUS; | |
147 | + | |
148 | + struct dwc3_glue_data *glue = dev_get_platdata(dev); | |
149 | + void *base = map_physmem(glue->regs, 0x10000, MAP_NOCACHE); | |
150 | + | |
151 | + if (device_is_compatible(dev, "ti,am437x-dwc3")) | |
152 | + utmi_status_offset += USBOTGSS_UTMI_OTG_OFFSET; | |
153 | + | |
154 | + utmi_mode = dev_read_u32_default(dev, "utmi-mode", | |
155 | + DWC3_OMAP_UTMI_MODE_UNKNOWN); | |
156 | + if (utmi_mode != DWC3_OMAP_UTMI_MODE_HW) { | |
157 | + debug("%s: OTG is not supported. defaulting to PERIPHERAL\n", | |
158 | + dev->name); | |
159 | + mode = USB_DR_MODE_PERIPHERAL; | |
160 | + } | |
161 | + | |
162 | + switch (mode) { | |
163 | + case USB_DR_MODE_PERIPHERAL: | |
164 | + use_id_pin = 0; | |
165 | + host_mode = 0; | |
166 | + break; | |
167 | + case USB_DR_MODE_HOST: | |
168 | + use_id_pin = 0; | |
169 | + host_mode = 1; | |
170 | + break; | |
171 | + case USB_DR_MODE_OTG: | |
172 | + default: | |
173 | + use_id_pin = 1; | |
174 | + host_mode = 0; | |
175 | + break; | |
176 | + } | |
177 | + | |
178 | + reg = readl(base + utmi_status_offset); | |
179 | + | |
180 | + reg &= ~(USBOTGSS_UTMI_OTG_STATUS_SW_MODE); | |
181 | + if (!use_id_pin) | |
182 | + reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | |
183 | + | |
184 | + writel(reg, base + utmi_status_offset); | |
185 | + | |
186 | + reg &= ~(USBOTGSS_UTMI_OTG_STATUS_SESSEND | | |
187 | + USBOTGSS_UTMI_OTG_STATUS_VBUSVALID | | |
188 | + USBOTGSS_UTMI_OTG_STATUS_IDDIG); | |
189 | + | |
190 | + reg |= USBOTGSS_UTMI_OTG_STATUS_SESSVALID | | |
191 | + USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT; | |
192 | + | |
193 | + if (!host_mode) | |
194 | + reg |= USBOTGSS_UTMI_OTG_STATUS_IDDIG | | |
195 | + USBOTGSS_UTMI_OTG_STATUS_VBUSVALID; | |
196 | + | |
197 | + writel(reg, base + utmi_status_offset); | |
198 | + | |
199 | + unmap_physmem(base, MAP_NOCACHE); | |
200 | +} | |
201 | + | |
202 | +struct dwc3_glue_ops ti_ops = { | |
203 | + .select_dr_mode = dwc3_ti_select_dr_mode, | |
204 | +}; | |
205 | + | |
206 | +static int dwc3_glue_bind(struct udevice *parent) | |
207 | +{ | |
103 | 208 | const void *fdt = gd->fdt_blob; |
104 | 209 | int node; |
105 | 210 | int ret; |
106 | 211 | |
107 | 212 | |
108 | 213 | |
109 | 214 | |
110 | 215 | |
... | ... | @@ -109,29 +214,32 @@ |
109 | 214 | const char *name = fdt_get_name(fdt, node, NULL); |
110 | 215 | enum usb_dr_mode dr_mode; |
111 | 216 | struct udevice *dev; |
112 | - const char *driver; | |
217 | + const char *driver = NULL; | |
113 | 218 | |
114 | 219 | debug("%s: subnode name: %s\n", __func__, name); |
115 | - if (strncmp(name, "dwc3@", 4)) | |
116 | - continue; | |
117 | 220 | |
118 | 221 | dr_mode = usb_get_dr_mode(node); |
119 | 222 | |
120 | 223 | switch (dr_mode) { |
121 | 224 | case USB_DR_MODE_PERIPHERAL: |
122 | 225 | case USB_DR_MODE_OTG: |
226 | +#if CONFIG_IS_ENABLED(DM_USB_GADGET) | |
123 | 227 | debug("%s: dr_mode: OTG or Peripheral\n", __func__); |
124 | 228 | driver = "dwc3-generic-peripheral"; |
229 | +#endif | |
125 | 230 | break; |
126 | 231 | case USB_DR_MODE_HOST: |
127 | 232 | debug("%s: dr_mode: HOST\n", __func__); |
128 | - driver = "dwc3-generic-host"; | |
233 | + driver = "xhci-dwc3"; | |
129 | 234 | break; |
130 | 235 | default: |
131 | 236 | debug("%s: unsupported dr_mode\n", __func__); |
132 | 237 | return -ENODEV; |
133 | 238 | }; |
134 | 239 | |
240 | + if (!driver) | |
241 | + continue; | |
242 | + | |
135 | 243 | ret = device_bind_driver_to_node(parent, driver, name, |
136 | 244 | offset_to_ofnode(node), &dev); |
137 | 245 | if (ret) { |
138 | 246 | |
139 | 247 | |
... | ... | @@ -144,15 +252,108 @@ |
144 | 252 | return 0; |
145 | 253 | } |
146 | 254 | |
147 | -static const struct udevice_id dwc3_generic_ids[] = { | |
255 | +static int dwc3_glue_reset_init(struct udevice *dev, | |
256 | + struct dwc3_glue_data *glue) | |
257 | +{ | |
258 | + int ret; | |
259 | + | |
260 | + ret = reset_get_bulk(dev, &glue->resets); | |
261 | + if (ret == -ENOTSUPP) | |
262 | + return 0; | |
263 | + else if (ret) | |
264 | + return ret; | |
265 | + | |
266 | + ret = reset_deassert_bulk(&glue->resets); | |
267 | + if (ret) { | |
268 | + reset_release_bulk(&glue->resets); | |
269 | + return ret; | |
270 | + } | |
271 | + | |
272 | + return 0; | |
273 | +} | |
274 | + | |
275 | +static int dwc3_glue_clk_init(struct udevice *dev, | |
276 | + struct dwc3_glue_data *glue) | |
277 | +{ | |
278 | + int ret; | |
279 | + | |
280 | + ret = clk_get_bulk(dev, &glue->clks); | |
281 | + if (ret == -ENOSYS) | |
282 | + return 0; | |
283 | + if (ret) | |
284 | + return ret; | |
285 | + | |
286 | +#if CONFIG_IS_ENABLED(CLK) | |
287 | + ret = clk_enable_bulk(&glue->clks); | |
288 | + if (ret) { | |
289 | + clk_release_bulk(&glue->clks); | |
290 | + return ret; | |
291 | + } | |
292 | +#endif | |
293 | + | |
294 | + return 0; | |
295 | +} | |
296 | + | |
297 | +static int dwc3_glue_probe(struct udevice *dev) | |
298 | +{ | |
299 | + struct dwc3_glue_ops *ops = (struct dwc3_glue_ops *)dev_get_driver_data(dev); | |
300 | + struct dwc3_glue_data *glue = dev_get_platdata(dev); | |
301 | + struct udevice *child = NULL; | |
302 | + int index = 0; | |
303 | + int ret; | |
304 | + | |
305 | + glue->regs = dev_read_addr(dev); | |
306 | + | |
307 | + ret = dwc3_glue_clk_init(dev, glue); | |
308 | + if (ret) | |
309 | + return ret; | |
310 | + | |
311 | + ret = dwc3_glue_reset_init(dev, glue); | |
312 | + if (ret) | |
313 | + return ret; | |
314 | + | |
315 | + ret = device_find_first_child(dev, &child); | |
316 | + if (ret) | |
317 | + return ret; | |
318 | + | |
319 | + while (child) { | |
320 | + enum usb_dr_mode dr_mode; | |
321 | + | |
322 | + dr_mode = usb_get_dr_mode(dev_of_offset(child)); | |
323 | + device_find_next_child(&child); | |
324 | + if (ops && ops->select_dr_mode) | |
325 | + ops->select_dr_mode(dev, index, dr_mode); | |
326 | + index++; | |
327 | + } | |
328 | + | |
329 | + return 0; | |
330 | +} | |
331 | + | |
332 | +static int dwc3_glue_remove(struct udevice *dev) | |
333 | +{ | |
334 | + struct dwc3_glue_data *glue = dev_get_platdata(dev); | |
335 | + | |
336 | + reset_release_bulk(&glue->resets); | |
337 | + | |
338 | + clk_release_bulk(&glue->clks); | |
339 | + | |
340 | + return dm_scan_fdt_dev(dev); | |
341 | +} | |
342 | + | |
343 | +static const struct udevice_id dwc3_glue_ids[] = { | |
148 | 344 | { .compatible = "xlnx,zynqmp-dwc3" }, |
345 | + { .compatible = "ti,dwc3", .data = (ulong)&ti_ops }, | |
149 | 346 | { } |
150 | 347 | }; |
151 | 348 | |
152 | 349 | U_BOOT_DRIVER(dwc3_generic_wrapper) = { |
153 | 350 | .name = "dwc3-generic-wrapper", |
154 | 351 | .id = UCLASS_MISC, |
155 | - .of_match = dwc3_generic_ids, | |
156 | - .bind = dwc3_generic_bind, | |
352 | + .of_match = dwc3_glue_ids, | |
353 | + .bind = dwc3_glue_bind, | |
354 | + .probe = dwc3_glue_probe, | |
355 | + .remove = dwc3_glue_remove, | |
356 | + .platdata_auto_alloc_size = sizeof(struct dwc3_glue_data), | |
357 | + | |
157 | 358 | }; |
drivers/usb/dwc3/ep0.c
drivers/usb/gadget/ether.c
... | ... | @@ -100,9 +100,6 @@ |
100 | 100 | struct usb_gadget *gadget; |
101 | 101 | struct usb_request *req; /* for control responses */ |
102 | 102 | struct usb_request *stat_req; /* for cdc & rndis status */ |
103 | -#if CONFIG_IS_ENABLED(DM_USB) | |
104 | - struct udevice *usb_udev; | |
105 | -#endif | |
106 | 103 | |
107 | 104 | u8 config; |
108 | 105 | struct usb_ep *in_ep, *out_ep, *status_ep; |
109 | 106 | |
110 | 107 | |
... | ... | @@ -2336,40 +2333,17 @@ |
2336 | 2333 | } |
2337 | 2334 | |
2338 | 2335 | /*-------------------------------------------------------------------------*/ |
2339 | - | |
2340 | -#if CONFIG_IS_ENABLED(DM_USB) | |
2341 | -int dm_usb_init(struct eth_dev *e_dev) | |
2342 | -{ | |
2343 | - struct udevice *dev = NULL; | |
2344 | - int ret; | |
2345 | - | |
2346 | - ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &dev); | |
2347 | - if (!dev || ret) { | |
2348 | - pr_err("No USB device found\n"); | |
2349 | - return -ENODEV; | |
2350 | - } | |
2351 | - | |
2352 | - e_dev->usb_udev = dev; | |
2353 | - | |
2354 | - return ret; | |
2355 | -} | |
2356 | -#endif | |
2357 | - | |
2358 | 2336 | static int _usb_eth_init(struct ether_priv *priv) |
2359 | 2337 | { |
2360 | 2338 | struct eth_dev *dev = &priv->ethdev; |
2361 | 2339 | struct usb_gadget *gadget; |
2362 | 2340 | unsigned long ts; |
2341 | + int ret; | |
2363 | 2342 | unsigned long timeout = USB_CONNECT_TIMEOUT; |
2364 | 2343 | |
2365 | -#if CONFIG_IS_ENABLED(DM_USB) | |
2366 | - if (dm_usb_init(dev)) { | |
2367 | - pr_err("USB ether not found\n"); | |
2368 | - return -ENODEV; | |
2369 | - } | |
2370 | -#else | |
2371 | - board_usb_init(0, USB_INIT_DEVICE); | |
2372 | -#endif | |
2344 | + ret = usb_gadget_initialize(0); | |
2345 | + if (ret) | |
2346 | + return ret; | |
2373 | 2347 | |
2374 | 2348 | /* Configure default mac-addresses for the USB ethernet device */ |
2375 | 2349 | #ifdef CONFIG_USBNET_DEV_ADDR |
... | ... | @@ -2541,9 +2515,7 @@ |
2541 | 2515 | } |
2542 | 2516 | |
2543 | 2517 | usb_gadget_unregister_driver(&priv->eth_driver); |
2544 | -#if !CONFIG_IS_ENABLED(DM_USB) | |
2545 | - board_usb_cleanup(0, USB_INIT_DEVICE); | |
2546 | -#endif | |
2518 | + usb_gadget_release(0); | |
2547 | 2519 | } |
2548 | 2520 | |
2549 | 2521 | #ifndef CONFIG_DM_ETH |
... | ... | @@ -2699,7 +2671,7 @@ |
2699 | 2671 | struct udevice *usb_dev; |
2700 | 2672 | int ret; |
2701 | 2673 | |
2702 | - ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &usb_dev); | |
2674 | + ret = uclass_first_device(UCLASS_USB_GADGET_GENERIC, &usb_dev); | |
2703 | 2675 | if (!usb_dev || ret) { |
2704 | 2676 | pr_err("No USB device found\n"); |
2705 | 2677 | return ret; |
drivers/usb/gadget/udc/Makefile
drivers/usb/gadget/udc/udc-core.c
drivers/usb/gadget/udc/udc-uclass.c
1 | +// SPDX-License-Identifier: GPL-2.0+ | |
2 | +/* | |
3 | + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com | |
4 | + * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <dm.h> | |
9 | +#include <dm/device-internal.h> | |
10 | +#include <linux/usb/gadget.h> | |
11 | + | |
12 | +#define MAX_UDC_DEVICES 4 | |
13 | +static struct udevice *dev_array[MAX_UDC_DEVICES]; | |
14 | +int usb_gadget_initialize(int index) | |
15 | +{ | |
16 | + int ret; | |
17 | + struct udevice *dev = NULL; | |
18 | + | |
19 | + if (index < 0 || index >= ARRAY_SIZE(dev_array)) | |
20 | + return -EINVAL; | |
21 | + if (dev_array[index]) | |
22 | + return 0; | |
23 | + ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, index, &dev); | |
24 | + if (!dev || ret) { | |
25 | + pr_err("No USB device found\n"); | |
26 | + return -ENODEV; | |
27 | + } | |
28 | + dev_array[index] = dev; | |
29 | + return 0; | |
30 | +} | |
31 | + | |
32 | +int usb_gadget_release(int index) | |
33 | +{ | |
34 | +#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) | |
35 | + int ret; | |
36 | + if (index < 0 || index >= ARRAY_SIZE(dev_array)) | |
37 | + return -EINVAL; | |
38 | + | |
39 | + ret = device_remove(dev_array[index], DM_REMOVE_NORMAL); | |
40 | + if (!ret) | |
41 | + dev_array[index] = NULL; | |
42 | + return ret; | |
43 | +#else | |
44 | + return -ENOTSUPP; | |
45 | +#endif | |
46 | +} | |
47 | + | |
48 | +int usb_gadget_handle_interrupts(int index) | |
49 | +{ | |
50 | + if (index < 0 || index >= ARRAY_SIZE(dev_array)) | |
51 | + return -EINVAL; | |
52 | + return dm_usb_gadget_handle_interrupts(dev_array[index]); | |
53 | +} | |
54 | + | |
55 | +UCLASS_DRIVER(usb_gadget_generic) = { | |
56 | + .id = UCLASS_USB_GADGET_GENERIC, | |
57 | + .name = "usb_gadget_generic", | |
58 | +}; |
drivers/usb/host/xhci-dwc3.c
... | ... | @@ -12,6 +12,7 @@ |
12 | 12 | #include <fdtdec.h> |
13 | 13 | #include <generic-phy.h> |
14 | 14 | #include <usb.h> |
15 | +#include <dwc3-uboot.h> | |
15 | 16 | |
16 | 17 | #include "xhci.h" |
17 | 18 | #include <asm/io.h> |
18 | 19 | |
19 | 20 | |
... | ... | @@ -110,105 +111,21 @@ |
110 | 111 | } |
111 | 112 | |
112 | 113 | #if CONFIG_IS_ENABLED(DM_USB) |
113 | -static int xhci_dwc3_setup_phy(struct udevice *dev) | |
114 | -{ | |
115 | - struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); | |
116 | - int i, ret, count; | |
117 | - | |
118 | - /* Return if no phy declared */ | |
119 | - if (!dev_read_prop(dev, "phys", NULL)) | |
120 | - return 0; | |
121 | - | |
122 | - count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); | |
123 | - if (count <= 0) | |
124 | - return count; | |
125 | - | |
126 | - plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy), | |
127 | - GFP_KERNEL); | |
128 | - if (!plat->usb_phys) | |
129 | - return -ENOMEM; | |
130 | - | |
131 | - for (i = 0; i < count; i++) { | |
132 | - ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]); | |
133 | - if (ret && ret != -ENOENT) { | |
134 | - pr_err("Failed to get USB PHY%d for %s\n", | |
135 | - i, dev->name); | |
136 | - return ret; | |
137 | - } | |
138 | - | |
139 | - ++plat->num_phys; | |
140 | - } | |
141 | - | |
142 | - for (i = 0; i < plat->num_phys; i++) { | |
143 | - ret = generic_phy_init(&plat->usb_phys[i]); | |
144 | - if (ret) { | |
145 | - pr_err("Can't init USB PHY%d for %s\n", | |
146 | - i, dev->name); | |
147 | - goto phys_init_err; | |
148 | - } | |
149 | - } | |
150 | - | |
151 | - for (i = 0; i < plat->num_phys; i++) { | |
152 | - ret = generic_phy_power_on(&plat->usb_phys[i]); | |
153 | - if (ret) { | |
154 | - pr_err("Can't power USB PHY%d for %s\n", | |
155 | - i, dev->name); | |
156 | - goto phys_poweron_err; | |
157 | - } | |
158 | - } | |
159 | - | |
160 | - return 0; | |
161 | - | |
162 | -phys_poweron_err: | |
163 | - for (; i >= 0; i--) | |
164 | - generic_phy_power_off(&plat->usb_phys[i]); | |
165 | - | |
166 | - for (i = 0; i < plat->num_phys; i++) | |
167 | - generic_phy_exit(&plat->usb_phys[i]); | |
168 | - | |
169 | - return ret; | |
170 | - | |
171 | -phys_init_err: | |
172 | - for (; i >= 0; i--) | |
173 | - generic_phy_exit(&plat->usb_phys[i]); | |
174 | - | |
175 | - return ret; | |
176 | -} | |
177 | - | |
178 | -static int xhci_dwc3_shutdown_phy(struct udevice *dev) | |
179 | -{ | |
180 | - struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); | |
181 | - int i, ret; | |
182 | - | |
183 | - for (i = 0; i < plat->num_phys; i++) { | |
184 | - if (!generic_phy_valid(&plat->usb_phys[i])) | |
185 | - continue; | |
186 | - | |
187 | - ret = generic_phy_power_off(&plat->usb_phys[i]); | |
188 | - ret |= generic_phy_exit(&plat->usb_phys[i]); | |
189 | - if (ret) { | |
190 | - pr_err("Can't shutdown USB PHY%d for %s\n", | |
191 | - i, dev->name); | |
192 | - } | |
193 | - } | |
194 | - | |
195 | - return 0; | |
196 | -} | |
197 | - | |
198 | 114 | static int xhci_dwc3_probe(struct udevice *dev) |
199 | 115 | { |
200 | 116 | struct xhci_hcor *hcor; |
201 | 117 | struct xhci_hccr *hccr; |
202 | 118 | struct dwc3 *dwc3_reg; |
203 | 119 | enum usb_dr_mode dr_mode; |
120 | + struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); | |
204 | 121 | int ret; |
205 | 122 | |
206 | 123 | hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev)); |
207 | 124 | hcor = (struct xhci_hcor *)((uintptr_t)hccr + |
208 | 125 | HC_LENGTH(xhci_readl(&(hccr)->cr_capbase))); |
209 | 126 | |
210 | - ret = xhci_dwc3_setup_phy(dev); | |
211 | - if (ret) | |
127 | + ret = dwc3_setup_phy(dev, &plat->usb_phys, &plat->num_phys); | |
128 | + if (ret && (ret != -ENOTSUPP)) | |
212 | 129 | return ret; |
213 | 130 | |
214 | 131 | dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); |
... | ... | @@ -227,7 +144,9 @@ |
227 | 144 | |
228 | 145 | static int xhci_dwc3_remove(struct udevice *dev) |
229 | 146 | { |
230 | - xhci_dwc3_shutdown_phy(dev); | |
147 | + struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); | |
148 | + | |
149 | + dwc3_shutdown_phy(dev, plat->usb_phys, plat->num_phys); | |
231 | 150 | |
232 | 151 | return xhci_deregister(dev); |
233 | 152 | } |
drivers/usb/musb-new/omap2430.c
drivers/usb/musb-new/sunxi.c
include/dm/uclass-id.h
... | ... | @@ -94,6 +94,7 @@ |
94 | 94 | UCLASS_USB, /* USB bus */ |
95 | 95 | UCLASS_USB_DEV_GENERIC, /* USB generic device */ |
96 | 96 | UCLASS_USB_HUB, /* USB hub */ |
97 | + UCLASS_USB_GADGET_GENERIC, /* USB generic device */ | |
97 | 98 | UCLASS_VIDEO, /* Video or LCD device */ |
98 | 99 | UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */ |
99 | 100 | UCLASS_VIDEO_CONSOLE, /* Text console driver for video device */ |
include/dwc3-uboot.h
... | ... | @@ -38,5 +38,24 @@ |
38 | 38 | int dwc3_uboot_init(struct dwc3_device *dev); |
39 | 39 | void dwc3_uboot_exit(int index); |
40 | 40 | void dwc3_uboot_handle_interrupt(int index); |
41 | + | |
42 | +struct phy; | |
43 | +#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB) | |
44 | +int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys); | |
45 | +int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys); | |
46 | +#else | |
47 | +static inline int dwc3_setup_phy(struct udevice *dev, struct phy **array, | |
48 | + int *num_phys) | |
49 | +{ | |
50 | + return -ENOTSUPP; | |
51 | +} | |
52 | + | |
53 | +static inline int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, | |
54 | + int num_phys) | |
55 | +{ | |
56 | + return -ENOTSUPP; | |
57 | +} | |
58 | +#endif | |
59 | + | |
41 | 60 | #endif /* __DWC3_UBOOT_H_ */ |
include/linux/usb/gadget.h
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | #define __LINUX_USB_GADGET_H |
20 | 20 | |
21 | 21 | #include <errno.h> |
22 | +#include <usb.h> | |
22 | 23 | #include <linux/compat.h> |
23 | 24 | #include <linux/list.h> |
24 | 25 | |
... | ... | @@ -925,6 +926,23 @@ |
925 | 926 | extern void usb_ep_autoconfig_reset(struct usb_gadget *); |
926 | 927 | |
927 | 928 | extern int usb_gadget_handle_interrupts(int index); |
929 | + | |
930 | +#if CONFIG_IS_ENABLED(DM_USB_GADGET) | |
931 | +int usb_gadget_initialize(int index); | |
932 | +int usb_gadget_release(int index); | |
933 | +int dm_usb_gadget_handle_interrupts(struct udevice *dev); | |
934 | +#else | |
935 | +#include <usb.h> | |
936 | +static inline int usb_gadget_initialize(int index) | |
937 | +{ | |
938 | + return board_usb_init(index, USB_INIT_DEVICE); | |
939 | +} | |
940 | + | |
941 | +static inline int usb_gadget_release(int index) | |
942 | +{ | |
943 | + return board_usb_cleanup(index, USB_INIT_DEVICE); | |
944 | +} | |
945 | +#endif | |
928 | 946 | |
929 | 947 | #endif /* __LINUX_USB_GADGET_H */ |
include/syscon.h
... | ... | @@ -74,6 +74,19 @@ |
74 | 74 | struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data); |
75 | 75 | |
76 | 76 | /** |
77 | + * syscon_regmap_lookup_by_phandle() - Look up a controller by a phandle | |
78 | + * | |
79 | + * This operates by looking up the given name in the device (device | |
80 | + * tree property) of the device using the system controller. | |
81 | + * | |
82 | + * @dev: Device using the system controller | |
83 | + * @name: Name of property referring to the system controller | |
84 | + * @return A pointer to the regmap if found, ERR_PTR(-ve) on error | |
85 | + */ | |
86 | +struct regmap *syscon_regmap_lookup_by_phandle(struct udevice *dev, | |
87 | + const char *name); | |
88 | + | |
89 | +/** | |
77 | 90 | * syscon_get_first_range() - get the first memory range from a syscon regmap |
78 | 91 | * |
79 | 92 | * @driver_data: Driver data value to look up |
test/dm/syscon.c
... | ... | @@ -6,6 +6,7 @@ |
6 | 6 | #include <common.h> |
7 | 7 | #include <dm.h> |
8 | 8 | #include <syscon.h> |
9 | +#include <regmap.h> | |
9 | 10 | #include <asm/test.h> |
10 | 11 | #include <dm/test.h> |
11 | 12 | #include <test/ut.h> |
... | ... | @@ -43,4 +44,32 @@ |
43 | 44 | return 0; |
44 | 45 | } |
45 | 46 | DM_TEST(dm_test_syscon_by_driver_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |
47 | + | |
48 | +/* Test system controller by phandle */ | |
49 | +static int dm_test_syscon_by_phandle(struct unit_test_state *uts) | |
50 | +{ | |
51 | + struct udevice *dev; | |
52 | + struct regmap *map; | |
53 | + | |
54 | + ut_assertok(uclass_get_device_by_name(UCLASS_TEST_PROBE, "test4", | |
55 | + &dev)); | |
56 | + | |
57 | + ut_assertok_ptr(syscon_regmap_lookup_by_phandle(dev, "first-syscon")); | |
58 | + map = syscon_regmap_lookup_by_phandle(dev, "first-syscon"); | |
59 | + ut_assert(map); | |
60 | + ut_assert(!IS_ERR(map)); | |
61 | + ut_asserteq(1, map->range_count); | |
62 | + | |
63 | + ut_assertok_ptr(syscon_regmap_lookup_by_phandle(dev, | |
64 | + "second-sys-ctrl")); | |
65 | + map = syscon_regmap_lookup_by_phandle(dev, "second-sys-ctrl"); | |
66 | + ut_assert(map); | |
67 | + ut_assert(!IS_ERR(map)); | |
68 | + ut_asserteq(4, map->range_count); | |
69 | + | |
70 | + ut_assert(IS_ERR(syscon_regmap_lookup_by_phandle(dev, "not-present"))); | |
71 | + | |
72 | + return 0; | |
73 | +} | |
74 | +DM_TEST(dm_test_syscon_by_phandle, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |