feat(imx8mq): add anamix pll override setting for DSM mode

Add the anamix PLL override setting for DSM mode support,
so that the PLL can be power down in DSM mode to save power.

Signed-off-by: Jacky Bai <ping.bai@nxp.com>
Change-Id: Ibe954bc7c4a7b453ace13f8e4b6a335e6d4856c3
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c
index 1cc8f6e..2beb35d 100644
--- a/plat/imx/imx8m/gpc_common.c
+++ b/plat/imx/imx8m/gpc_common.c
@@ -32,6 +32,7 @@
 #pragma weak imx_set_sys_wakeup
 #pragma weak imx_noc_slot_config
 #pragma weak imx_gpc_handler
+#pragma weak imx_anamix_override
 
 void imx_set_cpu_secure_entry(unsigned int core_id, uintptr_t sec_entrypoint)
 {
@@ -258,11 +259,6 @@
 		(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), },
diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c
index 329841c..c036e13 100644
--- a/plat/imx/imx8m/imx8mq/gpc.c
+++ b/plat/imx/imx8m/imx8mq/gpc.c
@@ -320,6 +320,39 @@
 	}
 }
 
+#define MAX_PLL_NUM	U(12)
+
+static const struct pll_override imx8mq_pll[MAX_PLL_NUM] = {
+	{.reg = 0x0, .override_mask = 0x140000, },
+	{.reg = 0x8, .override_mask = 0x140000, },
+	{.reg = 0x10, .override_mask = 0x140000, },
+	{.reg = 0x18, .override_mask = 0x140000, },
+	{.reg = 0x20, .override_mask = 0x140000, },
+	{.reg = 0x28, .override_mask = 0x140000, },
+	{.reg = 0x30, .override_mask = 0x1555540, },
+	{.reg = 0x3c, .override_mask = 0x1555540, },
+	{.reg = 0x48, .override_mask = 0x140, },
+	{.reg = 0x54, .override_mask = 0x140, },
+	{.reg = 0x60, .override_mask = 0x140, },
+	{.reg = 0x70, .override_mask = 0xa, },
+};
+
+void imx_anamix_override(bool enter)
+{
+	unsigned int i;
+
+	/* enable the pll override bit before entering DSM mode */
+	for (i = 0; i < MAX_PLL_NUM; i++) {
+		if (enter) {
+			mmio_setbits_32(IMX_ANAMIX_BASE + imx8mq_pll[i].reg,
+				imx8mq_pll[i].override_mask);
+		} else {
+			mmio_clrbits_32(IMX_ANAMIX_BASE + imx8mq_pll[i].reg,
+				imx8mq_pll[i].override_mask);
+		}
+	}
+}
+
 int imx_gpc_handler(uint32_t smc_fid,
 			  u_register_t x1,
 			  u_register_t x2,
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_psci.c b/plat/imx/imx8m/imx8mq/imx8mq_psci.c
index 8b4a6d5..3375ce7 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_psci.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_psci.c
@@ -74,13 +74,14 @@
 	}
 
 	if (is_local_state_off(CLUSTER_PWR_STATE(target_state)))
-		imx_set_cluster_powerdown(core_id, true);
+		imx_set_cluster_powerdown(core_id, CLUSTER_PWR_STATE(target_state));
 	else
 		imx_set_cluster_standby(true);
 
 	if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
 		imx_set_sys_lpm(core_id, true);
 		dram_enter_retention();
+		imx_anamix_override(true);
 	}
 }
 
@@ -91,6 +92,7 @@
 
 	/* check the system level status */
 	if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
+		imx_anamix_override(false);
 		dram_exit_retention();
 		imx_set_sys_lpm(core_id, false);
 		imx_clear_rbc_count();
@@ -98,7 +100,7 @@
 
 	/* check the cluster level power status */
 	if (is_local_state_off(CLUSTER_PWR_STATE(target_state)))
-		imx_set_cluster_powerdown(core_id, false);
+		imx_set_cluster_powerdown(core_id, PSCI_LOCAL_STATE_RUN);
 	else
 		imx_set_cluster_standby(false);
 
diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h
index 2cbcdf9..e5af4b4 100644
--- a/plat/imx/imx8m/include/gpc.h
+++ b/plat/imx/imx8m/include/gpc.h
@@ -54,6 +54,11 @@
 	bool always_on;
 };
 
+struct pll_override {
+	uint32_t reg;
+	uint32_t override_mask;
+};
+
 DECLARE_BAKERY_LOCK(gpc_lock);
 
 /* function declare */