[PATCH 3/3] arch: imx8m: Add USB power control
Angus Ainslie
angus at akkea.ca
Fri Dec 17 16:20:40 CET 2021
Enable turning on USB power for SDP mode
Signed-off-by: Angus Ainslie <angus at akkea.ca>
---
arch/arm/include/asm/arch-imx8m/sys_proto.h | 1 +
arch/arm/mach-imx/imx8m/soc.c | 57 +++++++++++++++++++++
2 files changed, 58 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..98a958166a 100644
--- a/arch/arm/include/asm/arch-imx8m/sys_proto.h
+++ b/arch/arm/include/asm/arch-imx8m/sys_proto.h
@@ -14,4 +14,5 @@ void restore_boot_params(void);
extern unsigned long rom_pointer[];
enum boot_device get_boot_device(void);
bool is_usb_boot(void);
+int imx8m_usb_power(int usb_id, bool on);
#endif
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index 863508776d..a43075e1c6 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -1203,6 +1203,63 @@ int arch_misc_init(void)
}
#endif
+#ifdef CONFIG_SPL_BUILD
+static u32 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)
+{
+ u32 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(u32 domain_id, bool on)
+{
+ u32 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)
+{
+ struct arm_smccc_res res;
+
+ if (usb_id > 1)
+ return -EINVAL;
+
+#ifdef CONFIG_SPL_BUILD
+ imx8m_usb_power_domain(2 + usb_id, on);
+#else
+ arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN,
+ 2 + usb_id, on, 0, 0, 0, 0, &res);
+ if (res.a0)
+ return -EPERM;
+#endif
+
+ return 0;
+}
+
void imx_tmu_arch_init(void *reg_base)
{
if (is_imx8mm() || is_imx8mn()) {
--
2.25.1
More information about the U-Boot
mailing list