|
|
@@ -778,6 +778,98 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
|
|
|
static int dwc3_core_get_phy(struct dwc3 *dwc);
|
|
|
static int dwc3_core_ulpi_init(struct dwc3 *dwc);
|
|
|
|
|
|
+/* set global incr burst type configuration registers */
|
|
|
+static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
|
|
|
+{
|
|
|
+ struct device *dev = dwc->dev;
|
|
|
+ /* incrx_mode : for INCR burst type. */
|
|
|
+ bool incrx_mode;
|
|
|
+ /* incrx_size : for size of INCRX burst. */
|
|
|
+ u32 incrx_size;
|
|
|
+ u32 *vals;
|
|
|
+ u32 cfg;
|
|
|
+ int ntype;
|
|
|
+ int ret;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ cfg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Handle property "snps,incr-burst-type-adjustment".
|
|
|
+ * Get the number of value from this property:
|
|
|
+ * result <= 0, means this property is not supported.
|
|
|
+ * result = 1, means INCRx burst mode supported.
|
|
|
+ * result > 1, means undefined length burst mode supported.
|
|
|
+ */
|
|
|
+ ntype = device_property_read_u32_array(dev,
|
|
|
+ "snps,incr-burst-type-adjustment", NULL, 0);
|
|
|
+ if (ntype <= 0)
|
|
|
+ return;
|
|
|
+
|
|
|
+ vals = kcalloc(ntype, sizeof(u32), GFP_KERNEL);
|
|
|
+ if (!vals) {
|
|
|
+ dev_err(dev, "Error to get memory\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Get INCR burst type, and parse it */
|
|
|
+ ret = device_property_read_u32_array(dev,
|
|
|
+ "snps,incr-burst-type-adjustment", vals, ntype);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(dev, "Error to get property\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ incrx_size = *vals;
|
|
|
+
|
|
|
+ if (ntype > 1) {
|
|
|
+ /* INCRX (undefined length) burst mode */
|
|
|
+ incrx_mode = INCRX_UNDEF_LENGTH_BURST_MODE;
|
|
|
+ for (i = 1; i < ntype; i++) {
|
|
|
+ if (vals[i] > incrx_size)
|
|
|
+ incrx_size = vals[i];
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ /* INCRX burst mode */
|
|
|
+ incrx_mode = INCRX_BURST_MODE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Enable Undefined Length INCR Burst and Enable INCRx Burst */
|
|
|
+ cfg &= ~DWC3_GSBUSCFG0_INCRBRST_MASK;
|
|
|
+ if (incrx_mode)
|
|
|
+ cfg |= DWC3_GSBUSCFG0_INCRBRSTENA;
|
|
|
+ switch (incrx_size) {
|
|
|
+ case 256:
|
|
|
+ cfg |= DWC3_GSBUSCFG0_INCR256BRSTENA;
|
|
|
+ break;
|
|
|
+ case 128:
|
|
|
+ cfg |= DWC3_GSBUSCFG0_INCR128BRSTENA;
|
|
|
+ break;
|
|
|
+ case 64:
|
|
|
+ cfg |= DWC3_GSBUSCFG0_INCR64BRSTENA;
|
|
|
+ break;
|
|
|
+ case 32:
|
|
|
+ cfg |= DWC3_GSBUSCFG0_INCR32BRSTENA;
|
|
|
+ break;
|
|
|
+ case 16:
|
|
|
+ cfg |= DWC3_GSBUSCFG0_INCR16BRSTENA;
|
|
|
+ break;
|
|
|
+ case 8:
|
|
|
+ cfg |= DWC3_GSBUSCFG0_INCR8BRSTENA;
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ cfg |= DWC3_GSBUSCFG0_INCR4BRSTENA;
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ dev_err(dev, "Invalid property\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* dwc3_core_init - Low-level initialization of DWC3 Core
|
|
|
* @dwc: Pointer to our controller context structure
|
|
|
@@ -840,6 +932,8 @@ static int dwc3_core_init(struct dwc3 *dwc)
|
|
|
/* Adjust Frame Length */
|
|
|
dwc3_frame_length_adjustment(dwc);
|
|
|
|
|
|
+ dwc3_set_incr_burst_type(dwc);
|
|
|
+
|
|
|
usb_phy_set_suspend(dwc->usb2_phy, 0);
|
|
|
usb_phy_set_suspend(dwc->usb3_phy, 0);
|
|
|
ret = phy_power_on(dwc->usb2_generic_phy);
|