From 2508827652f6c4eefc0bb3806130ad7b7ce2fbee Mon Sep 17 00:00:00 2001 From: Minda Chen Date: Mon, 28 Aug 2023 18:16:24 +0800 Subject: usb: cdns: Add USB device support Add USB device support. Add dr_num_mode for changing the dr mode number, For changing the strings cause issues. For devkits, If using device, need to changed starfive,usb2-only to 1 and dr_num_mode to 2. Signed-off-by: Minda Chen --- drivers/usb/cdns3/cdns3-starfive.c | 57 ++++++++++++++++++++++++++++++++++++-- drivers/usb/cdns3/core.c | 6 ++++ 2 files changed, 61 insertions(+), 2 deletions(-) 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 -- cgit v1.2.3