[PATCH 3/8] usb: dwc3: amend UTMI/UTMIW phy interface setup

Kever Yang kever.yang at rock-chips.com
Tue Apr 28 16:16:07 CEST 2020


On 2020/4/28 下午2:27, Frank Wang wrote:
> Let move 8/16-bit UTMI+ interface initialization into DWC3 core init
> that is convenient for both DM_USB and u-boot traditional process.
>
> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>


Reviewed-by: Kever Yang <kever.yang at rock-chips.com>

Thanks,
- Kever
> ---
>   drivers/usb/common/common.c | 25 ++++++++++++++
>   drivers/usb/dwc3/core.c     | 65 +++++++++++++++++++------------------
>   drivers/usb/dwc3/core.h     |  5 +++
>   include/linux/usb/phy.h     | 18 ++++++++++
>   4 files changed, 82 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
> index 0db281b970..48b0a9a5f1 100644
> --- a/drivers/usb/common/common.c
> +++ b/drivers/usb/common/common.c
> @@ -10,6 +10,7 @@
>   #include <dm.h>
>   #include <linux/usb/otg.h>
>   #include <linux/usb/ch9.h>
> +#include <linux/usb/phy.h>
>   
>   DECLARE_GLOBAL_DATA_PTR;
>   
> @@ -64,3 +65,27 @@ enum usb_device_speed usb_get_maximum_speed(ofnode node)
>   
>   	return USB_SPEED_UNKNOWN;
>   }
> +
> +#if CONFIG_IS_ENABLED(OF_LIVE) && CONFIG_IS_ENABLED(DM_USB)
> +static const char *const usbphy_modes[] = {
> +	[USBPHY_INTERFACE_MODE_UNKNOWN]	= "",
> +	[USBPHY_INTERFACE_MODE_UTMI]	= "utmi",
> +	[USBPHY_INTERFACE_MODE_UTMIW]	= "utmi_wide",
> +};
> +
> +enum usb_phy_interface usb_get_phy_mode(ofnode node)
> +{
> +	const char *phy_type;
> +	int i;
> +
> +	phy_type = ofnode_get_property(node, "phy_type", NULL);
> +	if (!phy_type)
> +		return USBPHY_INTERFACE_MODE_UNKNOWN;
> +
> +	for (i = 0; i < ARRAY_SIZE(usbphy_modes); i++)
> +		if (!strcmp(phy_type, usbphy_modes[i]))
> +			return i;
> +
> +	return USBPHY_INTERFACE_MODE_UNKNOWN;
> +}
> +#endif
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 3c81a07dad..487be1f3b0 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -334,6 +334,34 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
>   	parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
>   }
>   
> +static void dwc3_hsphy_mode_setup(struct dwc3 *dwc)
> +{
> +	enum usb_phy_interface hsphy_mode = dwc->hsphy_mode;
> +	u32 reg;
> +
> +	/* Set dwc3 usb2 phy config */
> +	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
> +
> +	switch (hsphy_mode) {
> +	case USBPHY_INTERFACE_MODE_UTMI:
> +		reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
> +			DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
> +		reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
> +			DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
> +		break;
> +	case USBPHY_INTERFACE_MODE_UTMIW:
> +		reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
> +			DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
> +		reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
> +			DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
> +}
> +
>   /**
>    * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
>    * @dwc: Pointer to our controller context structure
> @@ -379,6 +407,8 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
>   
>   	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
>   
> +	dwc3_hsphy_mode_setup(dwc);
> +
>   	mdelay(100);
>   
>   	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
> @@ -623,35 +653,6 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
>   	dwc3_gadget_run(dwc);
>   }
>   
> -static void dwc3_uboot_hsphy_mode(struct dwc3_device *dwc3_dev,
> -				  struct dwc3 *dwc)
> -{
> -	enum usb_phy_interface hsphy_mode = dwc3_dev->hsphy_mode;
> -	u32 reg;
> -
> -	/* Set dwc3 usb2 phy config */
> -	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
> -
> -	switch (hsphy_mode) {
> -	case USBPHY_INTERFACE_MODE_UTMI:
> -		reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
> -			DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
> -		reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
> -			DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
> -		break;
> -	case USBPHY_INTERFACE_MODE_UTMIW:
> -		reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
> -			DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
> -		reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
> -			DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
> -		break;
> -	default:
> -		break;
> -	}
> -
> -	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
> -}
> -
>   #define DWC3_ALIGN_MASK		(16 - 1)
>   
>   /**
> @@ -738,6 +739,8 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
>   	dwc->hird_threshold = hird_threshold
>   		| (dwc->is_utmi_l1_suspend << 4);
>   
> +	dwc->hsphy_mode = dwc3_dev->hsphy_mode;
> +
>   	dwc->index = dwc3_dev->index;
>   
>   	dwc3_cache_hwparams(dwc);
> @@ -762,8 +765,6 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
>   		goto err0;
>   	}
>   
> -	dwc3_uboot_hsphy_mode(dwc3_dev, dwc);
> -
>   	ret = dwc3_event_buffers_setup(dwc);
>   	if (ret) {
>   		dev_err(dwc->dev, "failed to setup event buffers\n");
> @@ -951,6 +952,8 @@ void dwc3_of_parse(struct dwc3 *dwc)
>   	 */
>   	hird_threshold = 12;
>   
> +	dwc->hsphy_mode = usb_get_phy_mode(dev->node);
> +
>   	dwc->has_lpm_erratum = dev_read_bool(dev,
>   				"snps,has-lpm-erratum");
>   	tmp = dev_read_u8_array_ptr(dev, "snps,lpm-nyet-threshold", 1);
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 86a697d1bd..8552f80344 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -21,6 +21,7 @@
>   
>   #include <linux/usb/ch9.h>
>   #include <linux/usb/otg.h>
> +#include <linux/usb/phy.h>
>   
>   #define DWC3_MSG_MAX	500
>   
> @@ -649,6 +650,9 @@ struct dwc3_scratchpad_array {
>    * @maximum_speed: maximum speed requested (mainly for testing purposes)
>    * @revision: revision register contents
>    * @dr_mode: requested mode of operation
> + * @hsphy_mode: UTMI phy mode, one of following:
> + *		- USBPHY_INTERFACE_MODE_UTMI
> + *		- USBPHY_INTERFACE_MODE_UTMIW
>    * @dcfg: saved contents of DCFG register
>    * @gctl: saved contents of GCTL register
>    * @isoch_delay: wValue from Set Isochronous Delay request;
> @@ -740,6 +744,7 @@ struct dwc3 {
>   	size_t			regs_size;
>   
>   	enum usb_dr_mode	dr_mode;
> +	enum usb_phy_interface	hsphy_mode;
>   
>   	/* used for suspend/resume */
>   	u32			dcfg;
> diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
> index 158ca9cd85..e4924ffe68 100644
> --- a/include/linux/usb/phy.h
> +++ b/include/linux/usb/phy.h
> @@ -10,10 +10,28 @@
>   #ifndef __LINUX_USB_PHY_H
>   #define __LINUX_USB_PHY_H
>   
> +#include <dm/ofnode.h>
> +
>   enum usb_phy_interface {
>   	USBPHY_INTERFACE_MODE_UNKNOWN,
>   	USBPHY_INTERFACE_MODE_UTMI,
>   	USBPHY_INTERFACE_MODE_UTMIW,
>   };
>   
> +#if CONFIG_IS_ENABLED(OF_LIVE) && CONFIG_IS_ENABLED(DM_USB)
> +/**
> + * usb_get_phy_mode - Get phy mode for given device_node
> + * @np:	Pointer to the given device_node
> + *
> + * The function gets phy interface string from property 'phy_type',
> + * and returns the corresponding enum usb_phy_interface
> + */
> +enum usb_phy_interface usb_get_phy_mode(ofnode node);
> +#else
> +static inline enum usb_phy_interface usb_get_phy_mode(ofnode node)
> +{
> +	return USBPHY_INTERFACE_MODE_UNKNOWN;
> +}
> +#endif
> +
>   #endif /* __LINUX_USB_PHY_H */




More information about the U-Boot mailing list