usb: gadget: ci13xxx_msm: Allow BAM enable and disable

There are scenarios where the USB BAM has to be reset.
For example, when the peer BAM is being reset, the USB BAM
must be reset as well, otherwise the BAM-BAM connection will
go out of sync.

In order to reset the USB BAM, the USB controller has to disable
the BAM first. After the USB BAM reset is completed, the USB
controller has to re-enable the USB BAM.

So this change adds the support for USB BAM enable/disable.
This is done by adding an API to ci13xxx_msm. A function driver can
ask for BAM enable/disable by calling this API.

This change doesn't add the support for the USB BAM reset sequence.

CRs-Fixed: 424867
Change-Id: Ib5518fafe3765f86bb09d1ce10723ec733543b35
Signed-off-by: Amit Blay <ablay@codeaurora.org>
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c
index e3c1216..9ecfaaf 100644
--- a/drivers/usb/gadget/ci13xxx_msm.c
+++ b/drivers/usb/gadget/ci13xxx_msm.c
@@ -233,6 +233,19 @@
 	return 0;
 }
 
+void msm_hw_bam_disable(bool bam_disable)
+{
+	u32 val;
+	struct ci13xxx *udc = _udc;
+
+	if (bam_disable)
+		val = readl_relaxed(USB_GENCONFIG) | GENCONFIG_BAM_DISABLE;
+	else
+		val = readl_relaxed(USB_GENCONFIG) & ~GENCONFIG_BAM_DISABLE;
+
+	writel_relaxed(val, USB_GENCONFIG);
+}
+
 static struct platform_driver ci13xxx_msm_driver = {
 	.probe = ci13xxx_msm_probe,
 	.driver = { .name = "msm_hsusb", },
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index bcbdec4..279b72f 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -504,6 +504,15 @@
 	void *ctxt;
 };
 
+#ifdef CONFIG_USB_CI13XXX_MSM
+void msm_hw_bam_disable(bool bam_disable);
+
+#else
+static inline void msm_hw_bam_disable(bool bam_disable)
+{
+}
+#endif
+
 #ifdef CONFIG_USB_DWC3_MSM
 int msm_ep_config(struct usb_ep *ep);
 int msm_ep_unconfig(struct usb_ep *ep);
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h
index c8c2ed1..6e36f56 100644
--- a/include/linux/usb/msm_hsusb_hw.h
+++ b/include/linux/usb/msm_hsusb_hw.h
@@ -18,6 +18,7 @@
 
 #define USB_AHBBURST         (MSM_USB_BASE + 0x0090)
 #define USB_AHBMODE          (MSM_USB_BASE + 0x0098)
+#define USB_GENCONFIG        (MSM_USB_BASE + 0x009C)
 #define USB_CAPLENGTH        (MSM_USB_BASE + 0x0100) /* 8 bit */
 #define USB_HS_GPTIMER_BASE  (MSM_USB_BASE + 0x80)
 
@@ -49,6 +50,8 @@
 #define ULPI_DATA(n)          ((n) & 255)
 #define ULPI_DATA_READ(n)     (((n) >> 8) & 255)
 
+#define GENCONFIG_BAM_DISABLE (1 << 13)
+
 /* synopsys 28nm phy registers */
 #define ULPI_PWR_CLK_MNG_REG	0x88
 #define OTG_COMP_DISABLE	BIT(0)