From e8351e2994e77a72603cac7992d49cadb5f4da12 Mon Sep 17 00:00:00 2001
From: Ye Li <ye.li@nxp.com>
Date: Thu, 14 Dec 2017 19:56:40 -0600
Subject: [PATCH] MLK-17210 usb: imx8m: Add PU power on/off to USB

ATF will power off all PUs at default, so for USB, we enable
its PU power for both host and device modes in board_usb_init and
disable the power when usb is stop in board_usb_cleanup.

Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Li Jun <jun.li@nxp.com>
---
 arch/arm/mach-imx/mx8m/soc.c  | 19 +++++++++++++++++++
 drivers/usb/host/xhci-imx8m.c | 14 +++++++++++---
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-imx/mx8m/soc.c b/arch/arm/mach-imx/mx8m/soc.c
index 46873aa8ddf..593a7dfb111 100644
--- a/arch/arm/mach-imx/mx8m/soc.c
+++ b/arch/arm/mach-imx/mx8m/soc.c
@@ -224,3 +224,22 @@ void reset_cpu(ulong addr)
 		 */
 	}
 }
+
+#ifdef CONFIG_USB_XHCI_IMX8M
+#define FSL_SIP_GPC                    0xC2000000
+#define FSL_SIP_CONFIG_GPC_PM_DOMAIN   0x03
+int imx8m_usb_power(int usb_id, bool on)
+{
+	unsigned long ret;
+
+	if (usb_id > 1)
+		return -EINVAL;
+
+	ret = call_imx_sip(FSL_SIP_GPC,
+			FSL_SIP_CONFIG_GPC_PM_DOMAIN, 2 + usb_id, on, 0);
+	if (ret)
+		return -EPERM;
+
+	return 0;
+}
+#endif
diff --git a/drivers/usb/host/xhci-imx8m.c b/drivers/usb/host/xhci-imx8m.c
index 1c63550a8f6..40f0518bc5b 100644
--- a/drivers/usb/host/xhci-imx8m.c
+++ b/drivers/usb/host/xhci-imx8m.c
@@ -42,8 +42,14 @@ struct imx8m_xhci {
 	struct imx8m_usbmix *usbmix_reg;
 };
 
+struct imx8m_usbctrl_data {
+	u32 usb_id;
+	unsigned long ctr_addr;
+};
 static struct imx8m_xhci imx8m_xhci;
-unsigned long ctr_addr[] = {USB2_BASE_ADDR};
+static struct imx8m_usbctrl_data ctr_data[] = {
+	{1, USB2_BASE_ADDR},
+};
 
 static void imx8m_usb_phy_init(struct imx8m_usbmix *usbmix_reg)
 {
@@ -107,13 +113,14 @@ int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
 	struct imx8m_xhci *ctx = &imx8m_xhci;
 	int ret = 0;
 
-	ctx->hcd = (struct xhci_hccr *)ctr_addr[index];
+	ctx->hcd = (struct xhci_hccr *)(ctr_data[index].ctr_addr);
 	ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
 	ctx->usbmix_reg = (struct imx8m_usbmix *)((char *)(ctx->hcd) +
 							USBMIX_PHY_OFFSET);
 
-	ret = board_usb_init(index, USB_INIT_HOST);
+	ret = board_usb_init(ctr_data[index].usb_id, USB_INIT_HOST);
 	if (ret != 0) {
+		imx8m_usb_power(ctr_data[index].usb_id, false);
 		puts("Failed to initialize board for imx8m USB\n");
 		return ret;
 	}
@@ -137,4 +144,5 @@ int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
 
 void xhci_hcd_stop(int index)
 {
+	board_usb_cleanup(ctr_data[index].usb_id, USB_INIT_HOST);
 }
-- 
GitLab