[PATCH 5/8] imx8m: enable usb power domain

Peng Fan
2020-10-12T06:23:51Z

Enable usb power domain, we are not using a power domain driver now.
Currently NXP use a ARM SIP based power domain driver, but this has been
rejected by Linux Kernel, so we are thinking SCMI, however kernel stuff
still not settle down, to make uboot feature work, we directly use SIP
call for U-Boot and MMIO for SPL.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm/include/asm/arch-imx8m/sys_proto.h | 1 +
arch/arm/mach-imx/imx8m/soc.c | 55 +++++++++++++++++++++
2 files changed, 56 insertions(+)

diff --git a/arch/arm/include/asm/arch-imx8m/sys_proto.h b/arch/arm/include/asm/arch-imx8m/sys_proto.h
index d328542ece..3e54f9b676 100644
--- a/arch/arm/include/asm/arch-imx8m/sys_proto.h
+++ b/arch/arm/include/asm/arch-imx8m/sys_proto.h
@@ -11,6 +11,7 @@
void set_wdog_reset(struct wdog_regs *wdog);
void enable_tzc380(void);
void restore_boot_params(void);
+int imx8m_usb_power(int usb_id, bool on);
extern unsigned long rom_pointer[];
enum boot_device get_boot_device(void);
bool is_usb_boot(void);
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index 9bca5bf972..830d1ac901 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -1112,3 +1112,58 @@ long long env_get_offset(long long defautl_offset)
}
#endif
#endif
+
+#ifdef CONFIG_SPL_BUILD
+static uint32_t gpc_pu_m_core_offset[11] = {
+ 0xc00, 0xc40, 0xc80, 0xcc0,
+ 0xdc0, 0xe00, 0xe40, 0xe80,
+ 0xec0, 0xf00, 0xf40,
+};
+
+#define PGC_PCR 0
+
+void imx_gpc_set_m_core_pgc(unsigned int offset, bool pdn)
+{
+ uint32_t val;
+ uintptr_t reg = GPC_BASE_ADDR + offset;
+
+ val = readl(reg);
+ val &= ~(0x1 << PGC_PCR);
+
+ if(pdn)
+ val |= 0x1 << PGC_PCR;
+ writel(val, reg);
+}
+
+void imx8m_usb_power_domain(uint32_t domain_id, bool on)
+{
+ uint32_t val;
+ uintptr_t reg;
+
+ imx_gpc_set_m_core_pgc(gpc_pu_m_core_offset[domain_id], true);
+
+ reg = GPC_BASE_ADDR + (on ? 0xf8 : 0x104);
+ val = 1 << (domain_id > 3 ? (domain_id + 3) : domain_id);
+ writel(val, reg);
+ while (readl(reg) & val)
+ ;
+ imx_gpc_set_m_core_pgc(gpc_pu_m_core_offset[domain_id], false);
+}
+#endif
+
+int imx8m_usb_power(int usb_id, bool on)
+{
+ if (usb_id > 1)
+ return -EINVAL;
+
+#ifdef CONFIG_SPL_BUILD
+ imx8m_usb_power_domain(2 + usb_id, on);
+#else
+ struct arm_smccc_res res;
+
+ /* Get ARM Trusted Firmware commit id */
+ arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, 2 + usb_id, on, 0, 0, 0, 0, &res);
+#endif
+
+ return 0;
+}
--
2.28.0