From 0bf7e91882d7ae7ecef1acb59a17158f99b9e616 Mon Sep 17 00:00:00 2001 From: Ye Li 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 Reviewed-by: Li Jun --- arch/arm/cpu/armv8/imx8m/soc.c | 19 +++++++++++++++++++ board/freescale/imx8mq_evk/imx8m_evk.c | 19 ++++++++++++++++--- drivers/usb/host/xhci-imx8m.c | 14 +++++++++++--- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/arch/arm/cpu/armv8/imx8m/soc.c b/arch/arm/cpu/armv8/imx8m/soc.c index 28ecd59d4f..80531f1e6b 100644 --- a/arch/arm/cpu/armv8/imx8m/soc.c +++ b/arch/arm/cpu/armv8/imx8m/soc.c @@ -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 diff --git a/board/freescale/imx8mq_evk/imx8m_evk.c b/board/freescale/imx8mq_evk/imx8m_evk.c index ed71d42ab2..618f77c605 100644 --- a/board/freescale/imx8mq_evk/imx8m_evk.c +++ b/board/freescale/imx8mq_evk/imx8m_evk.c @@ -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 diff --git a/drivers/usb/host/xhci-imx8m.c b/drivers/usb/host/xhci-imx8m.c index 1c63550a8f..40f0518bc5 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); } -- 2.17.1