diff options
| author | Tom Rini <trini@konsulko.com> | 2023-04-03 16:45:41 -0400 | 
|---|---|---|
| committer | Tom Rini <trini@konsulko.com> | 2023-04-03 16:45:41 -0400 | 
| commit | 288fe30a2367b8d0e3f416493150a38ebaa88459 (patch) | |
| tree | 1f841eb95d9ceeda4aa3255fb1132a0342f9b19a /drivers/usb/dwc3/dwc3-generic.c | |
| parent | fd4ed6b7e83ec3aea9a2ce21baea8ca9676f40dd (diff) | |
| parent | 9876c8c147144db2c120fcc9ffa6de27f6894441 (diff) | |
Merge branch 'next'
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers/usb/dwc3/dwc3-generic.c')
| -rw-r--r-- | drivers/usb/dwc3/dwc3-generic.c | 132 | 
1 files changed, 83 insertions, 49 deletions
| diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index ed1b9b630eb..66da5a8d6f8 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -28,11 +28,7 @@  #include <usb/xhci.h>  #include <asm/gpio.h> -struct dwc3_glue_data { -	struct clk_bulk		clks; -	struct reset_ctl_bulk	resets; -	fdt_addr_t regs; -}; +#include "dwc3-generic.h"  struct dwc3_generic_plat {  	fdt_addr_t base; @@ -68,10 +64,27 @@ static int dwc3_generic_probe(struct udevice *dev,  #if CONFIG_IS_ENABLED(OF_CONTROL)  	dwc3_of_parse(dwc3); +	/* +	 * There are currently four disparate placement possibilities of DWC3 +	 * reference clock phandle in SoC DTs: +	 * - in top level glue node, with generic subnode without clock (ZynqMP) +	 * - in top level generic node, with no subnode (i.MX8MQ) +	 * - in generic subnode, with other clock in top level node (i.MX8MP) +	 * - in both top level node and generic subnode (Rockchip) +	 * Cover all the possibilities here by looking into both nodes, start +	 * with the top level node as that seems to be used in majority of DTs +	 * to reference the clock. +	 */  	node = dev_ofnode(dev->parent);  	index = ofnode_stringlist_search(node, "clock-names", "ref");  	if (index < 0)  		index = ofnode_stringlist_search(node, "clock-names", "ref_clk"); +	if (index < 0) { +		node = dev_ofnode(dev); +		index = ofnode_stringlist_search(node, "clock-names", "ref"); +		if (index < 0) +			index = ofnode_stringlist_search(node, "clock-names", "ref_clk"); +	}  	if (index >= 0)  		dwc3->ref_clk = &glue->clks.clks[index];  #endif @@ -258,11 +271,6 @@ U_BOOT_DRIVER(dwc3_generic_host) = {  };  #endif -struct dwc3_glue_ops { -	void (*glue_configure)(struct udevice *dev, int index, -			       enum usb_dr_mode mode); -}; -  void dwc3_imx8mp_glue_configure(struct udevice *dev, int index,  				enum usb_dr_mode mode)  { @@ -398,54 +406,74 @@ struct dwc3_glue_ops ti_ops = {  	.glue_configure = dwc3_ti_glue_configure,  }; -static int dwc3_glue_bind(struct udevice *parent) +static int dwc3_glue_bind_common(struct udevice *parent, ofnode node)  { -	ofnode node; -	int ret; +	const char *name = ofnode_get_name(node); +	const char *driver = NULL;  	enum usb_dr_mode dr_mode; +	struct udevice *dev; +	int ret; -	dr_mode = usb_get_dr_mode(dev_ofnode(parent)); - -	ofnode_for_each_subnode(node, dev_ofnode(parent)) { -		const char *name = ofnode_get_name(node); -		struct udevice *dev; -		const char *driver = NULL; - -		debug("%s: subnode name: %s\n", __func__, name); +	debug("%s: subnode name: %s\n", __func__, name); -		/* if the parent node doesn't have a mode check the leaf */ -		if (!dr_mode) -			dr_mode = usb_get_dr_mode(node); +	/* if the parent node doesn't have a mode check the leaf */ +	dr_mode = usb_get_dr_mode(dev_ofnode(parent)); +	if (!dr_mode) +		dr_mode = usb_get_dr_mode(node); -		switch (dr_mode) { -		case USB_DR_MODE_PERIPHERAL: -		case USB_DR_MODE_OTG: +	switch (dr_mode) { +	case USB_DR_MODE_PERIPHERAL: +	case USB_DR_MODE_OTG:  #if CONFIG_IS_ENABLED(DM_USB_GADGET) -			debug("%s: dr_mode: OTG or Peripheral\n", __func__); -			driver = "dwc3-generic-peripheral"; +		debug("%s: dr_mode: OTG or Peripheral\n", __func__); +		driver = "dwc3-generic-peripheral";  #endif -			break; +		break;  #if defined(CONFIG_SPL_USB_HOST) || !defined(CONFIG_SPL_BUILD) -		case USB_DR_MODE_HOST: -			debug("%s: dr_mode: HOST\n", __func__); -			driver = "dwc3-generic-host"; -			break; +	case USB_DR_MODE_HOST: +		debug("%s: dr_mode: HOST\n", __func__); +		driver = "dwc3-generic-host"; +		break;  #endif -		default: -			debug("%s: unsupported dr_mode\n", __func__); -			return -ENODEV; -		}; +	default: +		debug("%s: unsupported dr_mode\n", __func__); +		return -ENODEV; +	}; -		if (!driver) -			continue; +	if (!driver) +		return -ENXIO; + +	ret = device_bind_driver_to_node(parent, driver, name, +					 node, &dev); +	if (ret) { +		debug("%s: not able to bind usb device mode\n", +		      __func__); +		return ret; +	} + +	return 0; +} -		ret = device_bind_driver_to_node(parent, driver, name, -						 node, &dev); -		if (ret) { -			debug("%s: not able to bind usb device mode\n", -			      __func__); +int dwc3_glue_bind(struct udevice *parent) +{ +	struct dwc3_glue_ops *ops = (struct dwc3_glue_ops *)dev_get_driver_data(parent); +	ofnode node; +	int ret; + +	if (ops && ops->glue_get_ctrl_dev) { +		ret = ops->glue_get_ctrl_dev(parent, &node); +		if (ret) +			return ret; + +		return dwc3_glue_bind_common(parent, node); +	} + +	ofnode_for_each_subnode(node, dev_ofnode(parent)) { +		ret = dwc3_glue_bind_common(parent, node); +		if (ret == -ENXIO) +			continue; +		if (ret)  			return ret; -		}  	}  	return 0; @@ -493,7 +521,7 @@ static int dwc3_glue_clk_init(struct udevice *dev,  	return 0;  } -static int dwc3_glue_probe(struct udevice *dev) +int dwc3_glue_probe(struct udevice *dev)  {  	struct dwc3_glue_ops *ops = (struct dwc3_glue_ops *)dev_get_driver_data(dev);  	struct dwc3_glue_data *glue = dev_get_plat(dev); @@ -514,7 +542,7 @@ static int dwc3_glue_probe(struct udevice *dev)  		phy.dev = NULL;  	} -	glue->regs = dev_read_addr(dev); +	glue->regs = dev_read_addr_size_index(dev, 0, &glue->size);  	ret = dwc3_glue_clk_init(dev, glue);  	if (ret) @@ -534,6 +562,12 @@ static int dwc3_glue_probe(struct udevice *dev)  	if (ret)  		return ret; +	if (glue->clks.count == 0) { +		ret = dwc3_glue_clk_init(child, glue); +		if (ret) +			return ret; +	} +  	if (glue->resets.count == 0) {  		ret = dwc3_glue_reset_init(child, glue);  		if (ret) @@ -553,7 +587,7 @@ static int dwc3_glue_probe(struct udevice *dev)  	return 0;  } -static int dwc3_glue_remove(struct udevice *dev) +int dwc3_glue_remove(struct udevice *dev)  {  	struct dwc3_glue_data *glue = dev_get_plat(dev); | 
