Commit ca05b382 authored by Piyush Mehta's avatar Piyush Mehta Committed by Greg Kroah-Hartman
Browse files

usb: dwc3: xilinx: Add gpio-reset support



This patch adds a USB GPIO based reset for dwc3-xilinx driver. The PHY
needs to be reset after the completion of phy initialization. As part
of the reset, check for gpio-reset binding before toggling the pin.
This feature is advantageous when the user toggle GPIO to trigger the
ULPI-PHY reset.

Delay of milliseconds is added in between low and high to meet the setup
and hold time requirement of the reset. The reset-gpio error handling is
added for error notification.

Some GPIO controllers must be accessed using message-based buses, like
I2C or SPI, to address this problem, updates GPIO access with sleep API.

This reset is specific to the zynqMp.

Signed-off-by: default avatarPiyush Mehta <piyush.mehta@xilinx.com>
Link: https://lore.kernel.org/r/20220504075309.6244-3-piyush.mehta@xilinx.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1cda12b1
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/of.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/dma-mapping.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/reset.h>
@@ -98,6 +99,7 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
{
{
	struct device		*dev = priv_data->dev;
	struct device		*dev = priv_data->dev;
	struct reset_control	*crst, *hibrst, *apbrst;
	struct reset_control	*crst, *hibrst, *apbrst;
	struct gpio_desc	*reset_gpio;
	struct phy		*usb3_phy;
	struct phy		*usb3_phy;
	int			ret = 0;
	int			ret = 0;
	u32			reg;
	u32			reg;
@@ -201,6 +203,21 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
	}
	}


skip_usb3_phy:
skip_usb3_phy:
	/* ulpi reset via gpio-modepin or gpio-framework driver */
	reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(reset_gpio)) {
		return dev_err_probe(dev, PTR_ERR(reset_gpio),
				     "Failed to request reset GPIO\n");
	}

	if (reset_gpio) {
		/* Toggle ulpi to reset the phy. */
		gpiod_set_value_cansleep(reset_gpio, 1);
		usleep_range(5000, 10000);
		gpiod_set_value_cansleep(reset_gpio, 0);
		usleep_range(5000, 10000);
	}

	/*
	/*
	 * This routes the USB DMA traffic to go through FPD path instead
	 * This routes the USB DMA traffic to go through FPD path instead
	 * of reaching DDR directly. This traffic routing is needed to
	 * of reaching DDR directly. This traffic routing is needed to