diff options
author | andy.hu <andy.hu@starfivetech.com> | 2023-09-06 12:59:31 +0300 |
---|---|---|
committer | andy.hu <andy.hu@starfivetech.com> | 2023-09-06 12:59:31 +0300 |
commit | 3e6f524ed4d35695de2318351aeab81f7171087c (patch) | |
tree | a0d5d9e2f93590fbcca8aac38cd9ae727101cabf | |
parent | eec56304c34fabd95031f7524c51decf6dc82042 (diff) | |
parent | 24be5cb7ec4985e69cc2d50b40723b7e9c3ad358 (diff) | |
download | u-boot-3e6f524ed4d35695de2318351aeab81f7171087c.tar.xz |
Merge branch 'CR_7250_add_usb_device_in_u_boot_minda' into 'jh7110-master'
CR_7250 usb: cdns: Add USB device support
See merge request sdk/u-boot!67
-rw-r--r-- | arch/riscv/dts/starfive_evb.dts | 1 | ||||
-rw-r--r-- | drivers/usb/cdns3/cdns3-starfive.c | 57 | ||||
-rw-r--r-- | drivers/usb/cdns3/core.c | 6 |
3 files changed, 62 insertions, 2 deletions
diff --git a/arch/riscv/dts/starfive_evb.dts b/arch/riscv/dts/starfive_evb.dts index 0ce86ad8bd..b62f79b362 100644 --- a/arch/riscv/dts/starfive_evb.dts +++ b/arch/riscv/dts/starfive_evb.dts @@ -312,6 +312,7 @@ <&rstgen RSTN_U0_CDN_USB_UTMI_APB>, <&rstgen RSTN_U0_PLDA_PCIE_APB>; reset-names = "pwrup","apb","axi","utmi", "phy"; + starfive,usb2-only = <0>; status = "okay"; }; diff --git a/drivers/usb/cdns3/cdns3-starfive.c b/drivers/usb/cdns3/cdns3-starfive.c index a7682c2fbf..631fae21cd 100644 --- a/drivers/usb/cdns3/cdns3-starfive.c +++ b/drivers/usb/cdns3/cdns3-starfive.c @@ -79,6 +79,7 @@ struct cdns_starfive { static int cdns_mode_init(struct cdns_starfive *data) { enum usb_dr_mode mode; + int ret; /* Init usb 2.0 utmi phy */ regmap_update_bits(data->stg_map, data->stg_offset_4, @@ -115,6 +116,11 @@ static int cdns_mode_init(struct cdns_starfive *data) } mode = usb_get_dr_mode(dev_read_first_subnode(data->dev)); + if (mode == USB_DR_MODE_UNKNOWN) { + ret = ofnode_read_u32(dev_read_first_subnode(data->dev), "dr_num_mode" , &mode); + if (ret) + return ret; + } data->mode = mode; switch (mode) { @@ -211,6 +217,51 @@ static void cdns_starfive_set_phy(struct cdns_starfive *data) } } +int cdns3_starfive_bind(struct udevice *parent) +{ + enum usb_dr_mode dr_mode; + struct udevice *dev; + const char *driver; + const char *name; + ofnode node; + int ret; + + node = ofnode_by_compatible(dev_ofnode(parent), "cdns,usb3"); + if (!ofnode_valid(node)) { + printf("%s: failed to get usb node\n", + __func__); + goto fail; + } + + dr_mode = usb_get_dr_mode(node); + if (dr_mode != USB_DR_MODE_UNKNOWN) + return cdns3_bind(parent); + + name = ofnode_get_name(node); + +#if defined(CONFIG_SPL_USB_HOST) || \ + (!defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_HOST)) + ret = device_bind_driver_to_node(parent, "cdns-usb3-host", name, node, &dev); + if (ret) { + printf("%s: not able to bind usb host mode\n", + __func__); + goto fail; + } +#endif +#if CONFIG_IS_ENABLED(DM_USB_GADGET) + ret = device_bind_driver_to_node(parent, "cdns-usb3-peripheral", name, node, &dev); + if (ret) { + printf("%s: not able to bind usb device mode\n", + __func__); + goto fail; + } + +#endif +fail: + /* do not return an error: failing to bind would hang the board */ + return 0; +} + static int cdns_starfive_probe(struct udevice *dev) { struct cdns_starfive *data = dev_get_plat(dev); @@ -230,7 +281,9 @@ static int cdns_starfive_probe(struct udevice *dev) return -EINVAL; } - data->usb2_only = dev_read_bool(dev, "starfive,usb2-only"); + ret = dev_read_u32(dev, "starfive,usb2-only", &data->usb2_only); + if (ret) + return ret; ret = dev_read_phandle_with_args(dev, "starfive,stg-syscon", NULL, 4, 0, &args); if (ret) @@ -286,7 +339,7 @@ U_BOOT_DRIVER(cdns_starfive) = { .name = "cdns-starfive", .id = UCLASS_NOP, .of_match = cdns_starfive_of_match, - .bind = cdns3_bind, + .bind = cdns3_starfive_bind, .probe = cdns_starfive_probe, .remove = cdns_starfive_remove, .plat_auto = sizeof(struct cdns_starfive), diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 644a9791b9..b1ae3c7e65 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -113,6 +113,12 @@ static int cdns3_core_init_role(struct cdns3 *cdns) dr_mode = usb_get_dr_mode(dev_ofnode(dev)); cdns->role = USB_ROLE_NONE; + if (dr_mode == USB_DR_MODE_UNKNOWN) { + ret = ofnode_read_u32(dev_ofnode(dev), "dr_num_mode" , &dr_mode); + if (ret) + return ret; + } + /* * If driver can't read mode by means of usb_get_dr_mode function then * chooses mode according with Kernel configuration. This setting |