[PATCH 3/4] usb: dwc3: make usb2 phy interface configurable in DT

William Wu
2016-05-09T11:54:10Z

Add snps,phyif_utmi_16_bits devicetree property. USB2 phy
interface is hardware property, and it's platform dependent,
so we need to configure it in devicetree to set the core to
support a UTMI+ PHY with an 8- or 16-bit interface.

And refer to the dwc3 databook, the GUSB2PHYCFG.USBTRDTIM
must set to the corresponding value according to the usb2
phy interface.

Signed-off-by: William Wu <william.wu@rock-chips.com>
---
Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++
drivers/usb/dwc3/core.c | 13 +++++++++++++
drivers/usb/dwc3/core.h | 8 ++++++++
drivers/usb/dwc3/platform_data.h | 1 +
4 files changed, 24 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index 1ada121..c5e72c8 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -19,6 +19,8 @@ Optional properties:
Only really useful for FPGA builds.
- snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled
- snps,lpm-nyet-threshold: LPM NYET threshold
+ - snps,phyif_utmi_16_bits: true when configure the core to support
+ UTMI+ PHY with an 16-bit interface.
- snps,u2exit_lfps_quirk: set if we want to enable u2exit lfps quirk
- snps,u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk
- snps,req_p1p2p3_quirk: when set, the core will always request for
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 8bcd3cc..0205196 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -410,6 +410,7 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
static int dwc3_phy_setup(struct dwc3 *dwc)
{
u32 reg;
+ u32 usbtrdtim;
int ret;

reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
@@ -505,6 +506,15 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_u2_freeclk_exists_quirk)
reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;

+ if (dwc->phyif_utmi_16_bits)
+ reg |= DWC3_GUSB2PHYCFG_PHYIF;
+
+ usbtrdtim = (reg & DWC3_GUSB2PHYCFG_PHYIF) ?
+ USBTRDTIM_UTMI_16_BIT : USBTRDTIM_UTMI_8_BIT;
+
+ reg &= ~DWC3_GUSB2PHYCFG_USBTRDTIM_MASK;
+ reg |= (usbtrdtim << DWC3_GUSB2PHYCFG_USBTRDTIM_SHIFT);
+
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);

return 0;
@@ -879,6 +889,8 @@ static int dwc3_probe(struct platform_device *pdev)
&hird_threshold);
dwc->usb3_lpm_capable = device_property_read_bool(dev,
"snps,usb3_lpm_capable");
+ dwc->phyif_utmi_16_bits = device_property_read_bool(dev,
+ "snps,phyif_utmi_16_bits");

dwc->disable_scramble_quirk = device_property_read_bool(dev,
"snps,disable_scramble_quirk");
@@ -926,6 +938,7 @@ static int dwc3_probe(struct platform_device *pdev)
hird_threshold = pdata->hird_threshold;

dwc->usb3_lpm_capable = pdata->usb3_lpm_capable;
+ dwc->phyif_utmi_16_bits = pdata->phyif_utmi_16_bits;
dwc->dr_mode = pdata->dr_mode;

dwc->disable_scramble_quirk = pdata->disable_scramble_quirk;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index ac2e6b5..1736f87 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -200,6 +200,11 @@
#define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6)
#define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4)
#define DWC3_GUSB2PHYCFG_ENBLSLPM (1 << 8)
+#define DWC3_GUSB2PHYCFG_PHYIF (1 << 3)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM_MASK (0xf << 10)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM_SHIFT 10
+#define USBTRDTIM_UTMI_8_BIT 9
+#define USBTRDTIM_UTMI_16_BIT 5

/* Global USB2 PHY Vendor Control Register */
#define DWC3_GUSB2PHYACC_NEWREGREQ (1 << 25)
@@ -759,6 +764,8 @@ struct dwc3_scratchpad_array {
* @start_config_issued: true when StartConfig command has been issued
* @three_stage_setup: set if we perform a three phase setup
* @usb3_lpm_capable: set if hadrware supports Link Power Management
+ * @phyif_utmi_16_bits: set if configure the core to support UTMI+ PHY
+ * with an 16-bit interface
* @disable_scramble_quirk: set if we enable the disable scramble quirk
* @u2exit_lfps_quirk: set if we enable u2exit lfps quirk
* @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk
@@ -904,6 +911,7 @@ struct dwc3 {
unsigned setup_packet_pending:1;
unsigned three_stage_setup:1;
unsigned usb3_lpm_capable:1;
+ unsigned phyif_utmi_16_bits:1;

unsigned disable_scramble_quirk:1;
unsigned u2exit_lfps_quirk:1;
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
index e1a1631..2ce5e2f 100644
--- a/drivers/usb/dwc3/platform_data.h
+++ b/drivers/usb/dwc3/platform_data.h
@@ -24,6 +24,7 @@ struct dwc3_platform_data {
enum usb_device_speed maximum_speed;
enum usb_dr_mode dr_mode;
bool usb3_lpm_capable;
+ bool phyif_utmi_16_bits;

unsigned is_utmi_l1_suspend:1;
u8 hird_threshold;
--
1.9.1