diff mbox series

[11/16] usb: gadget: udc: renesas_usb3: Add role switch support for RZ/V2M

Message ID 20221212172804.1277751-12-biju.das.jz@bp.renesas.com
State New
Headers show
Series ADD USB3.1 HOST, Peri and DRD support | expand

Commit Message

Biju Das Dec. 12, 2022, 5:27 p.m. UTC
As RZ/V2M has both HOST and PERI reset module, we need to do reset release
before accessing registers in respective IP module.

This patch adds role switch support for RZ/V2M.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/usb/gadget/udc/Kconfig        |  1 +
 drivers/usb/gadget/udc/renesas_usb3.c | 38 ++++++++++++++++++++++-----
 2 files changed, 32 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
index 578a3f209ef6..d7278d67b146 100644
--- a/drivers/usb/gadget/udc/Kconfig
+++ b/drivers/usb/gadget/udc/Kconfig
@@ -201,6 +201,7 @@  config USB_RENESAS_USB3
 	tristate 'Renesas USB3.0 Peripheral controller'
 	depends on ARCH_RENESAS || COMPILE_TEST
 	depends on EXTCON
+	select USB_RZV2M_USB3DRD if ARCH_R9A09G011
 	select USB_ROLE_SWITCH
 	help
 	   Renesas USB3.0 Peripheral controller is a USB peripheral controller
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
index af29de32e08b..9ca40b41aa36 100644
--- a/drivers/usb/gadget/udc/renesas_usb3.c
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
@@ -2318,6 +2318,9 @@  static int renesas_usb3_start(struct usb_gadget *gadget,
 
 	usb3 = gadget_to_renesas_usb3(gadget);
 
+	if (usb3->is_rzv2m && usb3_is_a_device(usb3))
+		return -EBUSY;
+
 	/* hook up the driver */
 	usb3->driver = driver;
 
@@ -2326,6 +2329,10 @@  static int renesas_usb3_start(struct usb_gadget *gadget,
 
 	pm_runtime_get_sync(usb3_to_dev(usb3));
 
+	/* Peripheral Reset */
+	if (usb3->is_rzv2m)
+		rzv2m_usb3drd_reset(usb3_to_dev(usb3)->parent, false);
+
 	renesas_usb3_init_controller(usb3);
 
 	return 0;
@@ -2338,8 +2345,10 @@  static int renesas_usb3_stop(struct usb_gadget *gadget)
 	usb3->softconnect = false;
 	usb3->gadget.speed = USB_SPEED_UNKNOWN;
 	usb3->driver = NULL;
-	renesas_usb3_stop_controller(usb3);
+	if (usb3->is_rzv2m)
+		rzv2m_usb3drd_reset(usb3_to_dev(usb3)->parent, false);
 
+	renesas_usb3_stop_controller(usb3);
 	if (usb3->phy)
 		phy_exit(usb3->phy);
 
@@ -2401,16 +2410,22 @@  static void handle_ext_role_switch_states(struct device *dev,
 		usb3->connection_state = USB_ROLE_NONE;
 		if (cur_role == USB_ROLE_HOST)
 			device_release_driver(host);
-		if (usb3->driver)
+		if (usb3->driver) {
+			if (usb3->is_rzv2m)
+				rzv2m_usb3drd_reset(dev->parent, false);
 			usb3_disconnect(usb3);
+		}
 		usb3_vbus_out(usb3, false);
 		break;
 	case USB_ROLE_DEVICE:
 		if (usb3->connection_state == USB_ROLE_NONE) {
 			usb3->connection_state = USB_ROLE_DEVICE;
 			usb3_set_mode(usb3, false);
-			if (usb3->driver)
+			if (usb3->driver) {
+				if (usb3->is_rzv2m)
+					renesas_usb3_init_controller(usb3);
 				usb3_connect(usb3);
+			}
 		} else if (cur_role == USB_ROLE_HOST)  {
 			device_release_driver(host);
 			usb3_set_mode(usb3, false);
@@ -2421,8 +2436,11 @@  static void handle_ext_role_switch_states(struct device *dev,
 		break;
 	case USB_ROLE_HOST:
 		if (usb3->connection_state == USB_ROLE_NONE) {
-			if (usb3->driver)
+			if (usb3->driver) {
+				if (usb3->is_rzv2m)
+					rzv2m_usb3drd_reset(dev->parent, false);
 				usb3_disconnect(usb3);
+			}
 
 			usb3->connection_state = USB_ROLE_HOST;
 			usb3_set_mode(usb3, true);
@@ -2806,9 +2824,15 @@  static int renesas_usb3_probe(struct platform_device *pdev)
 
 	usb3->is_rzv2m = priv->is_rzv2m;
 
-	usb3->reg = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(usb3->reg))
-		return PTR_ERR(usb3->reg);
+	if (usb3->is_rzv2m) {
+		struct rzv2m_usb3drd *ddata = dev_get_drvdata(pdev->dev.parent);
+
+		usb3->reg = ddata->reg;
+	} else {
+		usb3->reg = devm_platform_ioremap_resource(pdev, 0);
+		if (IS_ERR(usb3->reg))
+			return PTR_ERR(usb3->reg);
+	}
 
 	platform_set_drvdata(pdev, usb3);
 	spin_lock_init(&usb3->lock);