feat(imx8m): add the anamix pll override setting

Add PLL power down override & bypass support when
system enter DSM mode.

Signed-off-by: Jacky Bai <ping.bai@nxp.com>
Change-Id: I50cd6b82151961ab849f58714a8c307d3f7f4166
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c
index 1e55f05..4ca9b02 100644
--- a/plat/imx/imx8m/gpc_common.c
+++ b/plat/imx/imx8m/gpc_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +16,8 @@
 #include <imx8m_psci.h>
 #include <plat_imx8.h>
 
+#define MAX_PLL_NUM	U(10)
+
 static uint32_t gpc_imr_offset[] = { IMR1_CORE0_A53, IMR1_CORE1_A53, IMR1_CORE2_A53, IMR1_CORE3_A53, };
 
 DEFINE_BAKERY_LOCK(gpc_lock);
@@ -250,3 +252,41 @@
 	mmio_clrbits_32(IMX_GPC_BASE + SLPCR, SLPCR_RBC_EN |
 		(0x3f << SLPCR_RBC_COUNT_SHIFT));
 }
+
+struct pll_override {
+	uint32_t reg;
+	uint32_t override_mask;
+};
+
+struct pll_override pll[MAX_PLL_NUM] = {
+	{.reg = 0x0, .override_mask = (1 << 12) | (1 << 8), },
+	{.reg = 0x14, .override_mask = (1 << 12) | (1 << 8), },
+	{.reg = 0x28, .override_mask = (1 << 12) | (1 << 8), },
+	{.reg = 0x50, .override_mask = (1 << 12) | (1 << 8), },
+	{.reg = 0x64, .override_mask = (1 << 10) | (1 << 8), },
+	{.reg = 0x74, .override_mask = (1 << 10) | (1 << 8), },
+	{.reg = 0x84, .override_mask = (1 << 10) | (1 << 8), },
+	{.reg = 0x94, .override_mask = 0x5555500, },
+	{.reg = 0x104, .override_mask = 0x5555500, },
+	{.reg = 0x114, .override_mask = 0x500, },
+};
+
+#define PLL_BYPASS	BIT(4)
+void imx_anamix_override(bool enter)
+{
+	unsigned int i;
+
+	/*
+	 * bypass all the plls & enable the override bit before
+	 * entering DSM mode.
+	 */
+	for (i = 0U; i < MAX_PLL_NUM; i++) {
+		if (enter) {
+			mmio_setbits_32(IMX_ANAMIX_BASE + pll[i].reg, PLL_BYPASS);
+			mmio_setbits_32(IMX_ANAMIX_BASE + pll[i].reg, pll[i].override_mask);
+		} else {
+			mmio_clrbits_32(IMX_ANAMIX_BASE + pll[i].reg, PLL_BYPASS);
+			mmio_clrbits_32(IMX_ANAMIX_BASE + pll[i].reg, pll[i].override_mask);
+		}
+	}
+}
diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c
index f3ff9f4..4df4f8e 100644
--- a/plat/imx/imx8m/imx8m_psci_common.c
+++ b/plat/imx/imx8m/imx8m_psci_common.c
@@ -122,6 +122,7 @@
 	if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
 		imx_set_sys_lpm(core_id, true);
 		dram_enter_retention();
+		imx_anamix_override(true);
 	}
 }
 
@@ -131,6 +132,7 @@
 	unsigned int core_id = MPIDR_AFFLVL0_VAL(mpidr);
 
 	if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
+		imx_anamix_override(false);
 		dram_exit_retention();
 		imx_set_sys_lpm(core_id, false);
 	}
diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h
index 29b8ecf..16129d1 100644
--- a/plat/imx/imx8m/include/gpc.h
+++ b/plat/imx/imx8m/include/gpc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -69,5 +69,6 @@
 void imx_set_sys_lpm(unsigned last_core, bool retention);
 void imx_set_rbc_count(void);
 void imx_clear_rbc_count(void);
+void imx_anamix_override(bool enter);
 
 #endif /*IMX8M_GPC_H */