diff mbox series

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

Message ID 20200428062747.8349-4-frank.wang@rock-chips.com
State Superseded
Headers show
Series Add Rockchip RK3399 USB3.0 Host support | expand

Commit Message

Frank Wang April 28, 2020, 6:27 a.m. UTC
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>
---
 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(-)

Comments

Kever Yang April 28, 2020, 2:16 p.m. UTC | #1
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 */
diff mbox series

Patch

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 */