MLK-17210 usb: imx8m: Add PU power on/off to USB
authorYe Li <ye.li@nxp.com>
Fri, 15 Dec 2017 01:56:40 +0000 (19:56 -0600)
committerYe Li <ye.li@nxp.com>
Fri, 15 Dec 2017 03:08:03 +0000 (21:08 -0600)
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/cpu/armv8/imx8m/soc.c
board/freescale/imx8mq_evk/imx8m_evk.c
drivers/usb/host/xhci-imx8m.c

index 28ecd59..80531f1 100644 (file)
@@ -579,3 +579,22 @@ int arch_misc_init(void)
        return 0;
 }
 #endif
+
+#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
index ed71d42..618f77c 100644 (file)
@@ -197,16 +197,29 @@ static void dwc3_nxp_usb_phy_init(struct dwc3_device *dwc3)
        RegData &= ~(USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET);
        writel(RegData, dwc3->base + USB_PHY_CTRL1);
 }
+#endif
 
+#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_IMX8M)
 int board_usb_init(int index, enum usb_init_type init)
 {
-       dwc3_nxp_usb_phy_init(&dwc3_device_data);
-       return dwc3_uboot_init(&dwc3_device_data);
+       imx8m_usb_power(index, true);
+
+       if (index == 0 && init == USB_INIT_DEVICE) {
+               dwc3_nxp_usb_phy_init(&dwc3_device_data);
+               return dwc3_uboot_init(&dwc3_device_data);
+       }
+
+       return 0;
 }
 
 int board_usb_cleanup(int index, enum usb_init_type init)
 {
-       dwc3_uboot_exit(index);
+       if (index == 0 && init == USB_INIT_DEVICE) {
+               dwc3_uboot_exit(index);
+       }
+
+       imx8m_usb_power(index, false);
+
        return 0;
 }
 #endif
index 1c63550..40f0518 100644 (file)
@@ -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);
 }