Skip to content
Permalink
Browse files
usb: dwc3: Add support for masking phy reset signal
Versal usb controller drives phy reset signal during
Soft Reset or Core Reset to issue reset to the ULPI
phy. The ULPI phy needs to be resetted only at the time
of intialization. This patch updates the code to provide
a function for masking the phy reset signal from reaching
the ULPI phy. This function is called only after the phy
initialization is done.

Signed-off-by: Anurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
  • Loading branch information
Anurag Kumar Vulisha authored and Michal Simek committed Aug 30, 2019
1 parent 20a4daf commit 31d7800cc8d815f78d1bfa30655799f5733a4f59
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
@@ -1002,6 +1002,9 @@ int dwc3_core_init(struct dwc3 *dwc)
if (ret)
goto err0a;

if (dwc->mask_phy_rst)
dwc3_mask_phy_reset(dwc->dev, TRUE);

dwc3_core_setup_global_control(dwc);
dwc3_core_num_eps(dwc);

@@ -1440,6 +1443,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
"snps,enable_guctl1_ipd_quirk");
dwc->dis_metastability_quirk = device_property_read_bool(dev,
"snps,dis_metastability_quirk");
dwc->mask_phy_rst = device_property_read_bool(dev,
"snps,mask_phy_reset");

dwc->lpm_nyet_threshold = lpm_nyet_threshold;
dwc->tx_de_emphasis = tx_de_emphasis;
@@ -1217,6 +1217,7 @@ struct dwc3 {
unsigned is_hibernated:1;

unsigned dis_metastability_quirk:1;
unsigned mask_phy_rst:1;

u16 imod_interval;
bool is_d3;
@@ -1405,6 +1406,7 @@ void dwc3_simple_wakeup_capable(struct device *dev, bool wakeup);
void dwc3_set_simple_data(struct dwc3 *dwc);
void dwc3_simple_check_quirks(struct dwc3 *dwc);
int dwc3_set_usb_core_power(struct dwc3 *dwc, bool on);
void dwc3_mask_phy_reset(struct device *dev, bool mask);
#else
static inline int dwc3_enable_hw_coherency(struct device *dev)
{ return 1; }
@@ -1416,6 +1418,8 @@ void dwc3_simple_check_quirks(struct dwc3 *dwc)
{ ; }
int dwc3_set_usb_core_power(struct dwc3 *dwc, bool on)
{ ; }
void dwc3_mask_phy_reset(struct device *dev, bool mask)
{ ; }
#endif

bool dwc3_has_imod(struct dwc3 *dwc);
@@ -29,6 +29,10 @@

#include "core.h"

/* USB phy reset mask register */
#define XLNX_USB_PHY_RST 0x001C
#define XLNX_PHY_RST_MASK 0x1

/* Xilinx USB 3.0 IP Register */
#define XLNX_USB_COHERENCY 0x005C
#define XLNX_USB_COHERENCY_ENABLE 0x1
@@ -95,6 +99,41 @@ int dwc3_enable_hw_coherency(struct device *dev)
}
EXPORT_SYMBOL(dwc3_enable_hw_coherency);

void dwc3_mask_phy_reset(struct device *dev, bool mask)
{
struct device_node *node = of_get_parent(dev->of_node);

/* This is only valid for versal platforms */
if (of_device_is_compatible(node, "xlnx,versal-dwc3")) {
struct platform_device *pdev_parent;
struct dwc3_of_simple *simple;
u32 reg;

pdev_parent = of_find_device_by_node(node);
simple = platform_get_drvdata(pdev_parent);

reg = readl(simple->regs + XLNX_USB_PHY_RST);

if (mask)
/*
* Mask the phy reset signal from comtroller
* reaching ULPI phy. This can be done by
* writing 0 into usb2_phy_reset register
*/
reg &= ~XLNX_PHY_RST_MASK;
else
/*
* Allow phy reset signal from controller to
* reset ULPI phy. This can be done by writing
* 0x1 into usb2_phy_reset register
*/
reg |= XLNX_PHY_RST_MASK;

writel(reg, simple->regs + XLNX_USB_PHY_RST);
}
}
EXPORT_SYMBOL(dwc3_mask_phy_reset);

void dwc3_set_simple_data(struct dwc3 *dwc)
{
struct device_node *node = of_get_parent(dwc->dev->of_node);

0 comments on commit 31d7800

Please sign in to comment.