summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinda Chen <minda.chen@starfivetech.com>2023-08-28 13:16:24 +0300
committerMinda Chen <minda.chen@starfivetech.com>2023-08-31 11:02:51 +0300
commit2508827652f6c4eefc0bb3806130ad7b7ce2fbee (patch)
treee4c6fa9d85e86e14d9fd013e7298a1e388d66e29
parenteec56304c34fabd95031f7524c51decf6dc82042 (diff)
downloadu-boot-2508827652f6c4eefc0bb3806130ad7b7ce2fbee.tar.xz
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 <minda.chen@starfivetech.com>
-rw-r--r--drivers/usb/cdns3/cdns3-starfive.c57
-rw-r--r--drivers/usb/cdns3/core.c6
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