Linux-USB Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/2] USB DWC2 support for STM32MP15 SoCs USB OTG
@ 2019-11-25 10:26 Amelie Delaunay
  2019-11-25 10:26 ` [PATCH 1/2] dt-bindings: usb: dwc2: add support for STM32MP15 SoCs USB OTG HS and FS Amelie Delaunay
  2019-11-25 10:26 ` [PATCH 2/2] " Amelie Delaunay
  0 siblings, 2 replies; 5+ messages in thread
From: Amelie Delaunay @ 2019-11-25 10:26 UTC (permalink / raw)
  To: Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman, Rob Herring,
	Mark Rutland
  Cc: linux-usb, devicetree, linux-kernel, linux-stm32,
	Fabrice Gasnier, Benjamin Gaignard, Amelie Delaunay

Adds support for STM32MP15 SoCs USB OTG HS and FS based on DWC2 IP.

STM32MP15 SoCs embeds a DWC2 IP that can be used in HS or in FS, and
uses an external Vbus and ID level detection to support OTG operations.

Amelie Delaunay (2):
  dt-bindings: usb: dwc2: add support for STM32MP15 SoCs USB OTG HS and
    FS
  usb: dwc2: add support for STM32MP15 SoCs USB OTG HS and FS

 .../devicetree/bindings/usb/dwc2.txt          |  5 +
 drivers/usb/dwc2/core.h                       |  8 ++
 drivers/usb/dwc2/hw.h                         |  8 ++
 drivers/usb/dwc2/params.c                     | 33 +++++++
 drivers/usb/dwc2/platform.c                   | 94 ++++++++++++++++++-
 5 files changed, 146 insertions(+), 2 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] dt-bindings: usb: dwc2: add support for STM32MP15 SoCs USB OTG HS and FS
  2019-11-25 10:26 [PATCH 0/2] USB DWC2 support for STM32MP15 SoCs USB OTG Amelie Delaunay
@ 2019-11-25 10:26 ` Amelie Delaunay
  2019-12-05 17:28   ` Rob Herring
  2019-11-25 10:26 ` [PATCH 2/2] " Amelie Delaunay
  1 sibling, 1 reply; 5+ messages in thread
From: Amelie Delaunay @ 2019-11-25 10:26 UTC (permalink / raw)
  To: Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman, Rob Herring,
	Mark Rutland
  Cc: linux-usb, devicetree, linux-kernel, linux-stm32,
	Fabrice Gasnier, Benjamin Gaignard, Amelie Delaunay

Add the specific compatible string for the DWC2 IP found in the STM32MP15
SoCs.
STM32MP15 SoCs uses sensing comparators to detect Vbus valid levels and
ID pin state. usb33d-supply described the regulator supplying Vbus and ID
sensing comparators.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 Documentation/devicetree/bindings/usb/dwc2.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt
index aafff3a6904d..c2c8d40076cf 100644
--- a/Documentation/devicetree/bindings/usb/dwc2.txt
+++ b/Documentation/devicetree/bindings/usb/dwc2.txt
@@ -23,6 +23,9 @@ Required properties:
   configured in HS mode;
   - "st,stm32f7-hsotg": The DWC2 USB HS controller instance in STM32F7 SoCs
     configured in HS mode;
+  - "st,stm32mp15-fsotg": The DWC2 USB controller instance in STM32MP15 SoCs,
+  configured in FS mode (using dedicated FS transceiver).
+  - "st,stm32mp15-hsotg": The DWC2 USB controller instance in STM32MP15 SoCs;
 - reg : Should contain 1 register range (address and length)
 - interrupts : Should contain 1 interrupt
 - clocks: clock provider specifier
@@ -46,6 +49,8 @@ Refer to phy/phy-bindings.txt for generic phy consumer properties
                           on for remote wakeup during suspend.
 - snps,reset-phy-on-wake: If present indicates that we need to reset the PHY when
                           we detect a wakeup.  This is due to a hardware errata.
+- usb33d-supply: external VBUS and ID sensing comparators supply, in order to
+		 perform OTG operation, used on STM32MP15 SoCs.
 
 Deprecated properties:
 - g-use-dma: gadget DMA mode is automatically detected
-- 
2.17.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/2] usb: dwc2: add support for STM32MP15 SoCs USB OTG HS and FS
  2019-11-25 10:26 [PATCH 0/2] USB DWC2 support for STM32MP15 SoCs USB OTG Amelie Delaunay
  2019-11-25 10:26 ` [PATCH 1/2] dt-bindings: usb: dwc2: add support for STM32MP15 SoCs USB OTG HS and FS Amelie Delaunay
@ 2019-11-25 10:26 ` " Amelie Delaunay
  2019-11-28 12:14   ` Minas Harutyunyan
  1 sibling, 1 reply; 5+ messages in thread
From: Amelie Delaunay @ 2019-11-25 10:26 UTC (permalink / raw)
  To: Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman, Rob Herring,
	Mark Rutland
  Cc: linux-usb, devicetree, linux-kernel, linux-stm32,
	Fabrice Gasnier, Benjamin Gaignard, Amelie Delaunay

This patch introduces a new parameter to activate external ID pin and valid
vbus level detection, required on STM32MP15 SoC to support dual role,
either in HS or FS.
The STM32MP15 SoC uses the GGPIO register to enable the level detection.
The level detector requires to be powered.
Also adds the params structures for STM32MP15 OTG HS and STM32MP1 OTG FS.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/usb/dwc2/core.h     |  8 ++++
 drivers/usb/dwc2/hw.h       |  8 ++++
 drivers/usb/dwc2/params.c   | 33 +++++++++++++
 drivers/usb/dwc2/platform.c | 94 ++++++++++++++++++++++++++++++++++++-
 4 files changed, 141 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index d08d070a0fb6..687fefcd5706 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -411,6 +411,10 @@ enum dwc2_ep0_state {
  *			register.
  *			0 - Deactivate the transceiver (default)
  *			1 - Activate the transceiver
+ * @activate_stm_id_vb_detection: Activate external ID pin and Vbus level
+ *			detection using GGPIO register.
+ *			0 - Deactivate the external level detection (default)
+ *			1 - Activate the external level detection
  * @g_dma:              Enables gadget dma usage (default: autodetect).
  * @g_dma_desc:         Enables gadget descriptor DMA (default: autodetect).
  * @g_rx_fifo_size:	The periodic rx fifo size for the device, in
@@ -481,6 +485,7 @@ struct dwc2_core_params {
 	bool service_interval;
 	u8 hird_threshold;
 	bool activate_stm_fs_transceiver;
+	bool activate_stm_id_vb_detection;
 	bool ipg_isoc_en;
 	u16 max_packet_count;
 	u32 max_transfer_size;
@@ -874,6 +879,8 @@ struct dwc2_hregs_backup {
  *                      removed once all SoCs support usb transceiver.
  * @supplies:           Definition of USB power supplies
  * @vbus_supply:        Regulator supplying vbus.
+ * @usb33d:		Optional 3.3v regulator used on some stm32 devices to
+ *			supply ID and VBUS detection hardware.
  * @lock:		Spinlock that protects all the driver data structures
  * @priv:		Stores a pointer to the struct usb_hcd
  * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth
@@ -1061,6 +1068,7 @@ struct dwc2_hsotg {
 	struct dwc2_hsotg_plat *plat;
 	struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES];
 	struct regulator *vbus_supply;
+	struct regulator *usb33d;
 
 	spinlock_t lock;
 	void *priv;
diff --git a/drivers/usb/dwc2/hw.h b/drivers/usb/dwc2/hw.h
index 510e87ec0be8..c4027bbcedec 100644
--- a/drivers/usb/dwc2/hw.h
+++ b/drivers/usb/dwc2/hw.h
@@ -54,6 +54,12 @@
 #define GOTGCTL_HSTSETHNPEN		BIT(10)
 #define GOTGCTL_HNPREQ			BIT(9)
 #define GOTGCTL_HSTNEGSCS		BIT(8)
+#define GOTGCTL_BVALOVAL		BIT(7)
+#define GOTGCTL_BVALOEN			BIT(6)
+#define GOTGCTL_AVALOVAL		BIT(5)
+#define GOTGCTL_AVALOEN			BIT(4)
+#define GOTGCTL_VBVALOVAL		BIT(3)
+#define GOTGCTL_VBVALOEN		BIT(2)
 #define GOTGCTL_SESREQ			BIT(1)
 #define GOTGCTL_SESREQSCS		BIT(0)
 
@@ -227,6 +233,8 @@
 #define GPVNDCTL			HSOTG_REG(0x0034)
 #define GGPIO				HSOTG_REG(0x0038)
 #define GGPIO_STM32_OTG_GCCFG_PWRDWN	BIT(16)
+#define GGPIO_STM32_OTG_GCCFG_VBDEN	BIT(21)
+#define GGPIO_STM32_OTG_GCCFG_IDEN	BIT(22)
 
 #define GUID				HSOTG_REG(0x003c)
 #define GSNPSID				HSOTG_REG(0x0040)
diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
index 31e090ac9f1e..8ccc83f7eb3f 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -163,6 +163,35 @@ static void dwc2_set_stm32f7_hsotg_params(struct dwc2_hsotg *hsotg)
 	p->host_perio_tx_fifo_size = 256;
 }
 
+static void dwc2_set_stm32mp15_fsotg_params(struct dwc2_hsotg *hsotg)
+{
+	struct dwc2_core_params *p = &hsotg->params;
+
+	p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
+	p->speed = DWC2_SPEED_PARAM_FULL;
+	p->host_rx_fifo_size = 128;
+	p->host_nperio_tx_fifo_size = 96;
+	p->host_perio_tx_fifo_size = 96;
+	p->max_packet_count = 256;
+	p->phy_type = DWC2_PHY_TYPE_PARAM_FS;
+	p->i2c_enable = false;
+	p->activate_stm_fs_transceiver = true;
+	p->activate_stm_id_vb_detection = true;
+	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
+}
+
+static void dwc2_set_stm32mp15_hsotg_params(struct dwc2_hsotg *hsotg)
+{
+	struct dwc2_core_params *p = &hsotg->params;
+
+	p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
+	p->activate_stm_id_vb_detection = true;
+	p->host_rx_fifo_size = 440;
+	p->host_nperio_tx_fifo_size = 256;
+	p->host_perio_tx_fifo_size = 256;
+	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
+}
+
 const struct of_device_id dwc2_of_match_table[] = {
 	{ .compatible = "brcm,bcm2835-usb", .data = dwc2_set_bcm_params },
 	{ .compatible = "hisilicon,hi6220-usb", .data = dwc2_set_his_params  },
@@ -186,6 +215,10 @@ const struct of_device_id dwc2_of_match_table[] = {
 	{ .compatible = "st,stm32f4x9-hsotg" },
 	{ .compatible = "st,stm32f7-hsotg",
 	  .data = dwc2_set_stm32f7_hsotg_params },
+	{ .compatible = "st,stm32mp15-fsotg",
+	  .data = dwc2_set_stm32mp15_fsotg_params },
+	{ .compatible = "st,stm32mp15-hsotg",
+	  .data = dwc2_set_stm32mp15_hsotg_params },
 	{},
 };
 MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 3c6ce09a6db5..8368d6d66d64 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -312,6 +312,9 @@ static int dwc2_driver_remove(struct platform_device *dev)
 	if (hsotg->gadget_enabled)
 		dwc2_hsotg_remove(hsotg);
 
+	if (hsotg->params.activate_stm_id_vb_detection)
+		regulator_disable(hsotg->usb33d);
+
 	if (hsotg->ll_hw_enabled)
 		dwc2_lowlevel_hw_disable(hsotg);
 
@@ -464,10 +467,35 @@ static int dwc2_driver_probe(struct platform_device *dev)
 	if (retval)
 		goto error;
 
+	if (hsotg->params.activate_stm_id_vb_detection) {
+		u32 ggpio;
+
+		hsotg->usb33d = devm_regulator_get(hsotg->dev, "usb33d");
+		if (IS_ERR(hsotg->usb33d)) {
+			retval = PTR_ERR(hsotg->usb33d);
+			if (retval != -EPROBE_DEFER)
+				dev_err(hsotg->dev,
+					"failed to request usb33d supply: %d\n",
+					retval);
+			goto error;
+		}
+		retval = regulator_enable(hsotg->usb33d);
+		if (retval) {
+			dev_err(hsotg->dev,
+				"failed to enable usb33d supply: %d\n", retval);
+			goto error;
+		}
+
+		ggpio = dwc2_readl(hsotg, GGPIO);
+		ggpio |= GGPIO_STM32_OTG_GCCFG_IDEN;
+		ggpio |= GGPIO_STM32_OTG_GCCFG_VBDEN;
+		dwc2_writel(hsotg, ggpio, GGPIO);
+	}
+
 	if (hsotg->dr_mode != USB_DR_MODE_HOST) {
 		retval = dwc2_gadget_init(hsotg);
 		if (retval)
-			goto error;
+			goto error_init;
 		hsotg->gadget_enabled = 1;
 	}
 
@@ -493,7 +521,7 @@ static int dwc2_driver_probe(struct platform_device *dev)
 		if (retval) {
 			if (hsotg->gadget_enabled)
 				dwc2_hsotg_remove(hsotg);
-			goto error;
+			goto error_init;
 		}
 		hsotg->hcd_enabled = 1;
 	}
@@ -509,6 +537,9 @@ static int dwc2_driver_probe(struct platform_device *dev)
 
 	return 0;
 
+error_init:
+	if (hsotg->params.activate_stm_id_vb_detection)
+		regulator_disable(hsotg->usb33d);
 error:
 	dwc2_lowlevel_hw_disable(hsotg);
 	return retval;
@@ -523,6 +554,37 @@ static int __maybe_unused dwc2_suspend(struct device *dev)
 	if (is_device_mode)
 		dwc2_hsotg_suspend(dwc2);
 
+	if (dwc2->params.activate_stm_id_vb_detection) {
+		unsigned long flags;
+		u32 ggpio, gotgctl;
+
+		/*
+		 * Need to force the mode to the current mode to avoid Mode
+		 * Mismatch Interrupt when ID detection will be disabled.
+		 */
+		dwc2_force_mode(dwc2, !is_device_mode);
+
+		spin_lock_irqsave(&dwc2->lock, flags);
+		gotgctl = dwc2_readl(dwc2, GOTGCTL);
+		/* bypass debounce filter, enable overrides */
+		gotgctl |= GOTGCTL_DBNCE_FLTR_BYPASS;
+		gotgctl |= GOTGCTL_BVALOEN | GOTGCTL_AVALOEN;
+		/* Force A / B session if needed */
+		if (gotgctl & GOTGCTL_ASESVLD)
+			gotgctl |= GOTGCTL_AVALOVAL;
+		if (gotgctl & GOTGCTL_BSESVLD)
+			gotgctl |= GOTGCTL_BVALOVAL;
+		dwc2_writel(dwc2, gotgctl, GOTGCTL);
+		spin_unlock_irqrestore(&dwc2->lock, flags);
+
+		ggpio = dwc2_readl(dwc2, GGPIO);
+		ggpio &= ~GGPIO_STM32_OTG_GCCFG_IDEN;
+		ggpio &= ~GGPIO_STM32_OTG_GCCFG_VBDEN;
+		dwc2_writel(dwc2, ggpio, GGPIO);
+
+		regulator_disable(dwc2->usb33d);
+	}
+
 	if (dwc2->ll_hw_enabled &&
 	    (is_device_mode || dwc2_host_can_poweroff_phy(dwc2))) {
 		ret = __dwc2_lowlevel_hw_disable(dwc2);
@@ -544,6 +606,34 @@ static int __maybe_unused dwc2_resume(struct device *dev)
 	}
 	dwc2->phy_off_for_suspend = false;
 
+	if (dwc2->params.activate_stm_id_vb_detection) {
+		unsigned long flags;
+		u32 ggpio, gotgctl;
+
+		ret = regulator_enable(dwc2->usb33d);
+		if (ret)
+			return ret;
+
+		ggpio = dwc2_readl(dwc2, GGPIO);
+		ggpio |= GGPIO_STM32_OTG_GCCFG_IDEN;
+		ggpio |= GGPIO_STM32_OTG_GCCFG_VBDEN;
+		dwc2_writel(dwc2, ggpio, GGPIO);
+
+		/* ID/VBUS detection startup time */
+		usleep_range(5000, 7000);
+
+		spin_lock_irqsave(&dwc2->lock, flags);
+		gotgctl = dwc2_readl(dwc2, GOTGCTL);
+		gotgctl &= ~GOTGCTL_DBNCE_FLTR_BYPASS;
+		gotgctl &= ~(GOTGCTL_BVALOEN | GOTGCTL_AVALOEN |
+			     GOTGCTL_BVALOVAL | GOTGCTL_AVALOVAL);
+		dwc2_writel(dwc2, gotgctl, GOTGCTL);
+		spin_unlock_irqrestore(&dwc2->lock, flags);
+	}
+
+	/* Need to restore FORCEDEVMODE/FORCEHOSTMODE */
+	dwc2_force_dr_mode(dwc2);
+
 	if (dwc2_is_device_mode(dwc2))
 		ret = dwc2_hsotg_resume(dwc2);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] usb: dwc2: add support for STM32MP15 SoCs USB OTG HS and FS
  2019-11-25 10:26 ` [PATCH 2/2] " Amelie Delaunay
@ 2019-11-28 12:14   ` Minas Harutyunyan
  0 siblings, 0 replies; 5+ messages in thread
From: Minas Harutyunyan @ 2019-11-28 12:14 UTC (permalink / raw)
  To: Amelie Delaunay, Felipe Balbi, Greg Kroah-Hartman, Rob Herring,
	Mark Rutland
  Cc: linux-usb, devicetree, linux-kernel, linux-stm32,
	Fabrice Gasnier, Benjamin Gaignard

Hi,

On 11/25/2019 2:26 PM, Amelie Delaunay wrote:
> This patch introduces a new parameter to activate external ID pin and valid
> vbus level detection, required on STM32MP15 SoC to support dual role,
> either in HS or FS.
> The STM32MP15 SoC uses the GGPIO register to enable the level detection.
> The level detector requires to be powered.
> Also adds the params structures for STM32MP15 OTG HS and STM32MP1 OTG FS.
> 
> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>

Acked-by: Minas Harutyunyan <hminas@synopsys.com>

> ---
>   drivers/usb/dwc2/core.h     |  8 ++++
>   drivers/usb/dwc2/hw.h       |  8 ++++
>   drivers/usb/dwc2/params.c   | 33 +++++++++++++
>   drivers/usb/dwc2/platform.c | 94 ++++++++++++++++++++++++++++++++++++-
>   4 files changed, 141 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
> index d08d070a0fb6..687fefcd5706 100644
> --- a/drivers/usb/dwc2/core.h
> +++ b/drivers/usb/dwc2/core.h
> @@ -411,6 +411,10 @@ enum dwc2_ep0_state {
>    *			register.
>    *			0 - Deactivate the transceiver (default)
>    *			1 - Activate the transceiver
> + * @activate_stm_id_vb_detection: Activate external ID pin and Vbus level
> + *			detection using GGPIO register.
> + *			0 - Deactivate the external level detection (default)
> + *			1 - Activate the external level detection
>    * @g_dma:              Enables gadget dma usage (default: autodetect).
>    * @g_dma_desc:         Enables gadget descriptor DMA (default: autodetect).
>    * @g_rx_fifo_size:	The periodic rx fifo size for the device, in
> @@ -481,6 +485,7 @@ struct dwc2_core_params {
>   	bool service_interval;
>   	u8 hird_threshold;
>   	bool activate_stm_fs_transceiver;
> +	bool activate_stm_id_vb_detection;
>   	bool ipg_isoc_en;
>   	u16 max_packet_count;
>   	u32 max_transfer_size;
> @@ -874,6 +879,8 @@ struct dwc2_hregs_backup {
>    *                      removed once all SoCs support usb transceiver.
>    * @supplies:           Definition of USB power supplies
>    * @vbus_supply:        Regulator supplying vbus.
> + * @usb33d:		Optional 3.3v regulator used on some stm32 devices to
> + *			supply ID and VBUS detection hardware.
>    * @lock:		Spinlock that protects all the driver data structures
>    * @priv:		Stores a pointer to the struct usb_hcd
>    * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth
> @@ -1061,6 +1068,7 @@ struct dwc2_hsotg {
>   	struct dwc2_hsotg_plat *plat;
>   	struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES];
>   	struct regulator *vbus_supply;
> +	struct regulator *usb33d;
>   
>   	spinlock_t lock;
>   	void *priv;
> diff --git a/drivers/usb/dwc2/hw.h b/drivers/usb/dwc2/hw.h
> index 510e87ec0be8..c4027bbcedec 100644
> --- a/drivers/usb/dwc2/hw.h
> +++ b/drivers/usb/dwc2/hw.h
> @@ -54,6 +54,12 @@
>   #define GOTGCTL_HSTSETHNPEN		BIT(10)
>   #define GOTGCTL_HNPREQ			BIT(9)
>   #define GOTGCTL_HSTNEGSCS		BIT(8)
> +#define GOTGCTL_BVALOVAL		BIT(7)
> +#define GOTGCTL_BVALOEN			BIT(6)
> +#define GOTGCTL_AVALOVAL		BIT(5)
> +#define GOTGCTL_AVALOEN			BIT(4)
> +#define GOTGCTL_VBVALOVAL		BIT(3)
> +#define GOTGCTL_VBVALOEN		BIT(2)
>   #define GOTGCTL_SESREQ			BIT(1)
>   #define GOTGCTL_SESREQSCS		BIT(0)
>   
> @@ -227,6 +233,8 @@
>   #define GPVNDCTL			HSOTG_REG(0x0034)
>   #define GGPIO				HSOTG_REG(0x0038)
>   #define GGPIO_STM32_OTG_GCCFG_PWRDWN	BIT(16)
> +#define GGPIO_STM32_OTG_GCCFG_VBDEN	BIT(21)
> +#define GGPIO_STM32_OTG_GCCFG_IDEN	BIT(22)
>   
>   #define GUID				HSOTG_REG(0x003c)
>   #define GSNPSID				HSOTG_REG(0x0040)
> diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
> index 31e090ac9f1e..8ccc83f7eb3f 100644
> --- a/drivers/usb/dwc2/params.c
> +++ b/drivers/usb/dwc2/params.c
> @@ -163,6 +163,35 @@ static void dwc2_set_stm32f7_hsotg_params(struct dwc2_hsotg *hsotg)
>   	p->host_perio_tx_fifo_size = 256;
>   }
>   
> +static void dwc2_set_stm32mp15_fsotg_params(struct dwc2_hsotg *hsotg)
> +{
> +	struct dwc2_core_params *p = &hsotg->params;
> +
> +	p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
> +	p->speed = DWC2_SPEED_PARAM_FULL;
> +	p->host_rx_fifo_size = 128;
> +	p->host_nperio_tx_fifo_size = 96;
> +	p->host_perio_tx_fifo_size = 96;
> +	p->max_packet_count = 256;
> +	p->phy_type = DWC2_PHY_TYPE_PARAM_FS;
> +	p->i2c_enable = false;
> +	p->activate_stm_fs_transceiver = true;
> +	p->activate_stm_id_vb_detection = true;
> +	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
> +}
> +
> +static void dwc2_set_stm32mp15_hsotg_params(struct dwc2_hsotg *hsotg)
> +{
> +	struct dwc2_core_params *p = &hsotg->params;
> +
> +	p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
> +	p->activate_stm_id_vb_detection = true;
> +	p->host_rx_fifo_size = 440;
> +	p->host_nperio_tx_fifo_size = 256;
> +	p->host_perio_tx_fifo_size = 256;
> +	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
> +}
> +
>   const struct of_device_id dwc2_of_match_table[] = {
>   	{ .compatible = "brcm,bcm2835-usb", .data = dwc2_set_bcm_params },
>   	{ .compatible = "hisilicon,hi6220-usb", .data = dwc2_set_his_params  },
> @@ -186,6 +215,10 @@ const struct of_device_id dwc2_of_match_table[] = {
>   	{ .compatible = "st,stm32f4x9-hsotg" },
>   	{ .compatible = "st,stm32f7-hsotg",
>   	  .data = dwc2_set_stm32f7_hsotg_params },
> +	{ .compatible = "st,stm32mp15-fsotg",
> +	  .data = dwc2_set_stm32mp15_fsotg_params },
> +	{ .compatible = "st,stm32mp15-hsotg",
> +	  .data = dwc2_set_stm32mp15_hsotg_params },
>   	{},
>   };
>   MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
> diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
> index 3c6ce09a6db5..8368d6d66d64 100644
> --- a/drivers/usb/dwc2/platform.c
> +++ b/drivers/usb/dwc2/platform.c
> @@ -312,6 +312,9 @@ static int dwc2_driver_remove(struct platform_device *dev)
>   	if (hsotg->gadget_enabled)
>   		dwc2_hsotg_remove(hsotg);
>   
> +	if (hsotg->params.activate_stm_id_vb_detection)
> +		regulator_disable(hsotg->usb33d);
> +
>   	if (hsotg->ll_hw_enabled)
>   		dwc2_lowlevel_hw_disable(hsotg);
>   
> @@ -464,10 +467,35 @@ static int dwc2_driver_probe(struct platform_device *dev)
>   	if (retval)
>   		goto error;
>   
> +	if (hsotg->params.activate_stm_id_vb_detection) {
> +		u32 ggpio;
> +
> +		hsotg->usb33d = devm_regulator_get(hsotg->dev, "usb33d");
> +		if (IS_ERR(hsotg->usb33d)) {
> +			retval = PTR_ERR(hsotg->usb33d);
> +			if (retval != -EPROBE_DEFER)
> +				dev_err(hsotg->dev,
> +					"failed to request usb33d supply: %d\n",
> +					retval);
> +			goto error;
> +		}
> +		retval = regulator_enable(hsotg->usb33d);
> +		if (retval) {
> +			dev_err(hsotg->dev,
> +				"failed to enable usb33d supply: %d\n", retval);
> +			goto error;
> +		}
> +
> +		ggpio = dwc2_readl(hsotg, GGPIO);
> +		ggpio |= GGPIO_STM32_OTG_GCCFG_IDEN;
> +		ggpio |= GGPIO_STM32_OTG_GCCFG_VBDEN;
> +		dwc2_writel(hsotg, ggpio, GGPIO);
> +	}
> +
>   	if (hsotg->dr_mode != USB_DR_MODE_HOST) {
>   		retval = dwc2_gadget_init(hsotg);
>   		if (retval)
> -			goto error;
> +			goto error_init;
>   		hsotg->gadget_enabled = 1;
>   	}
>   
> @@ -493,7 +521,7 @@ static int dwc2_driver_probe(struct platform_device *dev)
>   		if (retval) {
>   			if (hsotg->gadget_enabled)
>   				dwc2_hsotg_remove(hsotg);
> -			goto error;
> +			goto error_init;
>   		}
>   		hsotg->hcd_enabled = 1;
>   	}
> @@ -509,6 +537,9 @@ static int dwc2_driver_probe(struct platform_device *dev)
>   
>   	return 0;
>   
> +error_init:
> +	if (hsotg->params.activate_stm_id_vb_detection)
> +		regulator_disable(hsotg->usb33d);
>   error:
>   	dwc2_lowlevel_hw_disable(hsotg);
>   	return retval;
> @@ -523,6 +554,37 @@ static int __maybe_unused dwc2_suspend(struct device *dev)
>   	if (is_device_mode)
>   		dwc2_hsotg_suspend(dwc2);
>   
> +	if (dwc2->params.activate_stm_id_vb_detection) {
> +		unsigned long flags;
> +		u32 ggpio, gotgctl;
> +
> +		/*
> +		 * Need to force the mode to the current mode to avoid Mode
> +		 * Mismatch Interrupt when ID detection will be disabled.
> +		 */
> +		dwc2_force_mode(dwc2, !is_device_mode);
> +
> +		spin_lock_irqsave(&dwc2->lock, flags);
> +		gotgctl = dwc2_readl(dwc2, GOTGCTL);
> +		/* bypass debounce filter, enable overrides */
> +		gotgctl |= GOTGCTL_DBNCE_FLTR_BYPASS;
> +		gotgctl |= GOTGCTL_BVALOEN | GOTGCTL_AVALOEN;
> +		/* Force A / B session if needed */
> +		if (gotgctl & GOTGCTL_ASESVLD)
> +			gotgctl |= GOTGCTL_AVALOVAL;
> +		if (gotgctl & GOTGCTL_BSESVLD)
> +			gotgctl |= GOTGCTL_BVALOVAL;
> +		dwc2_writel(dwc2, gotgctl, GOTGCTL);
> +		spin_unlock_irqrestore(&dwc2->lock, flags);
> +
> +		ggpio = dwc2_readl(dwc2, GGPIO);
> +		ggpio &= ~GGPIO_STM32_OTG_GCCFG_IDEN;
> +		ggpio &= ~GGPIO_STM32_OTG_GCCFG_VBDEN;
> +		dwc2_writel(dwc2, ggpio, GGPIO);
> +
> +		regulator_disable(dwc2->usb33d);
> +	}
> +
>   	if (dwc2->ll_hw_enabled &&
>   	    (is_device_mode || dwc2_host_can_poweroff_phy(dwc2))) {
>   		ret = __dwc2_lowlevel_hw_disable(dwc2);
> @@ -544,6 +606,34 @@ static int __maybe_unused dwc2_resume(struct device *dev)
>   	}
>   	dwc2->phy_off_for_suspend = false;
>   
> +	if (dwc2->params.activate_stm_id_vb_detection) {
> +		unsigned long flags;
> +		u32 ggpio, gotgctl;
> +
> +		ret = regulator_enable(dwc2->usb33d);
> +		if (ret)
> +			return ret;
> +
> +		ggpio = dwc2_readl(dwc2, GGPIO);
> +		ggpio |= GGPIO_STM32_OTG_GCCFG_IDEN;
> +		ggpio |= GGPIO_STM32_OTG_GCCFG_VBDEN;
> +		dwc2_writel(dwc2, ggpio, GGPIO);
> +
> +		/* ID/VBUS detection startup time */
> +		usleep_range(5000, 7000);
> +
> +		spin_lock_irqsave(&dwc2->lock, flags);
> +		gotgctl = dwc2_readl(dwc2, GOTGCTL);
> +		gotgctl &= ~GOTGCTL_DBNCE_FLTR_BYPASS;
> +		gotgctl &= ~(GOTGCTL_BVALOEN | GOTGCTL_AVALOEN |
> +			     GOTGCTL_BVALOVAL | GOTGCTL_AVALOVAL);
> +		dwc2_writel(dwc2, gotgctl, GOTGCTL);
> +		spin_unlock_irqrestore(&dwc2->lock, flags);
> +	}
> +
> +	/* Need to restore FORCEDEVMODE/FORCEHOSTMODE */
> +	dwc2_force_dr_mode(dwc2);
> +
>   	if (dwc2_is_device_mode(dwc2))
>   		ret = dwc2_hsotg_resume(dwc2);
>   
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] dt-bindings: usb: dwc2: add support for STM32MP15 SoCs USB OTG HS and FS
  2019-11-25 10:26 ` [PATCH 1/2] dt-bindings: usb: dwc2: add support for STM32MP15 SoCs USB OTG HS and FS Amelie Delaunay
@ 2019-12-05 17:28   ` Rob Herring
  0 siblings, 0 replies; 5+ messages in thread
From: Rob Herring @ 2019-12-05 17:28 UTC (permalink / raw)
  To: Amelie Delaunay
  Cc: Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman, Rob Herring,
	Mark Rutland, linux-usb, devicetree, linux-kernel, linux-stm32,
	Fabrice Gasnier, Benjamin Gaignard, Amelie Delaunay

On Mon, 25 Nov 2019 11:26:58 +0100, Amelie Delaunay wrote:
> Add the specific compatible string for the DWC2 IP found in the STM32MP15
> SoCs.
> STM32MP15 SoCs uses sensing comparators to detect Vbus valid levels and
> ID pin state. usb33d-supply described the regulator supplying Vbus and ID
> sensing comparators.
> 
> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
> ---
>  Documentation/devicetree/bindings/usb/dwc2.txt | 5 +++++
>  1 file changed, 5 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-25 10:26 [PATCH 0/2] USB DWC2 support for STM32MP15 SoCs USB OTG Amelie Delaunay
2019-11-25 10:26 ` [PATCH 1/2] dt-bindings: usb: dwc2: add support for STM32MP15 SoCs USB OTG HS and FS Amelie Delaunay
2019-12-05 17:28   ` Rob Herring
2019-11-25 10:26 ` [PATCH 2/2] " Amelie Delaunay
2019-11-28 12:14   ` Minas Harutyunyan

Linux-USB Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-usb/0 linux-usb/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-usb linux-usb/ https://lore.kernel.org/linux-usb \
		linux-usb@vger.kernel.org
	public-inbox-index linux-usb

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-usb


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git