usb: xhci: fsl: Add workaround for USB erratum A008751

This patch is doing the following:
1. Implementing the errata for LS2080.
2. Adding fixup for fdt for LS2080.

Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
diff --git a/drivers/usb/common/fsl-dt-fixup.c b/drivers/usb/common/fsl-dt-fixup.c
index 930ca1d..9c48852 100644
--- a/drivers/usb/common/fsl-dt-fixup.c
+++ b/drivers/usb/common/fsl-dt-fixup.c
@@ -139,6 +139,7 @@
 	int usb_erratum_a007075_off = -1;
 	int usb_erratum_a007792_off = -1;
 	int usb_erratum_a005697_off = -1;
+	int usb_erratum_a008751_off = -1;
 	int usb_mode_off = -1;
 	int usb_phy_off = -1;
 	char str[5];
@@ -217,5 +218,11 @@
 					has_erratum_a005697);
 		if (ret == -ENOSPC)
 			return;
+		ret = fdt_fixup_erratum(&usb_erratum_a008751_off, blob,
+					SNPS_DWC3, "a008751",
+					has_erratum_a008751);
+		if (ret == -ENOSPC)
+			return;
+
 	}
 }
diff --git a/drivers/usb/common/fsl-errata.c b/drivers/usb/common/fsl-errata.c
index 95918fc..ebe60a8 100644
--- a/drivers/usb/common/fsl-errata.c
+++ b/drivers/usb/common/fsl-errata.c
@@ -175,4 +175,19 @@
 	return false;
 }
 
+bool has_erratum_a008751(void)
+{
+	u32 svr = get_svr();
+	u32 soc = SVR_SOC_VER(svr);
+
+	switch (soc) {
+#ifdef CONFIG_ARM64
+	case SVR_LS2080:
+	case SVR_LS2085:
+		return IS_SVR_REV(svr, 1, 0);
+#endif
+	}
+	return false;
+}
+
 #endif
diff --git a/drivers/usb/host/xhci-fsl.c b/drivers/usb/host/xhci-fsl.c
index 05f09d7..c12a189 100644
--- a/drivers/usb/host/xhci-fsl.c
+++ b/drivers/usb/host/xhci-fsl.c
@@ -15,6 +15,8 @@
 #include <linux/usb/xhci-fsl.h>
 #include <linux/usb/dwc3.h>
 #include "xhci.h"
+#include <fsl_errata.h>
+#include <fsl_usb.h>
 
 /* Declare global data pointer */
 DECLARE_GLOBAL_DATA_PTR;
@@ -27,6 +29,26 @@
 	return 0;
 }
 
+static int erratum_a008751(void)
+{
+#if defined(CONFIG_TARGET_LS2080AQDS) || defined(CONFIG_TARGET_LS2080ARDB)
+	u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
+	writel(SCFG_USB3PRM1CR_INIT, scfg + SCFG_USB3PRM1CR / 4);
+	return 0;
+#endif
+	return 1;
+}
+
+static void fsl_apply_xhci_errata(void)
+{
+	int ret;
+	if (has_erratum_a008751()) {
+		ret = erratum_a008751();
+		if (ret != 0)
+			puts("Failed to apply erratum a008751\n");
+	}
+}
+
 static int fsl_xhci_core_init(struct fsl_xhci *fsl_xhci)
 {
 	int ret = 0;
@@ -69,6 +91,8 @@
 		return ret;
 	}
 
+	fsl_apply_xhci_errata();
+
 	ret = fsl_xhci_core_init(ctx);
 	if (ret < 0) {
 		puts("Failed to initialize xhci\n");