mediatek: mt8183: refine GIC driver for low power scenarios
Implement rdist save/resore functions to support low power scenarios.
Signed-off-by: kenny liang <kenny.liang@mediatek.com>
Change-Id: I9ddc077a04f843275fbe2e868cdd0bd00d622de7
diff --git a/plat/mediatek/mt8183/plat_pm.c b/plat/mediatek/mt8183/plat_pm.c
index 555b389..efa30f6 100644
--- a/plat/mediatek/mt8183/plat_pm.c
+++ b/plat/mediatek/mt8183/plat_pm.c
@@ -152,6 +152,21 @@
return !(on_stat & (cpu_mask[cluster] & ~BIT(my_idx)));
}
+static void plat_cpu_pwrdwn_common(void)
+{
+ /* Prevent interrupts from spuriously waking up this cpu */
+ mt_gic_rdistif_save();
+ mt_gic_cpuif_disable();
+}
+
+static void plat_cpu_pwron_common(void)
+{
+ /* Enable the gic cpu interface */
+ mt_gic_cpuif_enable();
+ mt_gic_rdistif_init();
+ mt_gic_rdistif_restore();
+}
+
static void plat_cluster_pwrdwn_common(uint64_t mpidr, int cluster)
{
if (cluster > 0)
@@ -312,7 +327,7 @@
bool cluster_off = (HP_CLUSTER_OFF && afflvl1 &&
clst_single_on(cluster, cpu));
- mt_gic_cpuif_disable();
+ plat_cpu_pwrdwn_common();
if (cluster_off)
plat_cluster_pwrdwn_common(mpidr, cluster);
@@ -332,8 +347,7 @@
if (afflvl1)
plat_cluster_pwron_common(mpidr, cluster);
- mt_gic_pcpu_init();
- mt_gic_cpuif_enable();
+ plat_cpu_pwron_common();
hotplug_ctrl_cpu_on_finish(cluster, cpu);
}
@@ -352,8 +366,8 @@
mcucfg_init_archstate(cluster, cpu, 1);
mcucfg_set_bootaddr(cluster, cpu, secure_entrypoint);
- mt_gic_cpuif_disable();
- mt_gic_irq_save();
+ plat_cpu_pwrdwn_common();
+
plat_dcm_mcsi_a_backup();
if (cluster_off || afflvl2)
@@ -376,6 +390,8 @@
if (MCDI_SSPM)
while (sspm_ipi_recv_non_blocking(IPI_ID_SUSPEND, d, l))
;
+
+ mt_gic_distif_save();
} else {
mcdi_ctrl_cluster_cpu_off(cluster, cpu, cluster_off);
}
@@ -394,7 +410,9 @@
uint32_t l = sizeof(spm_d) / sizeof(uint32_t);
mt_gic_init();
- mt_gic_irq_restore();
+ mt_gic_distif_restore();
+ mt_gic_rdistif_restore();
+
mmio_write_32(EMI_WFIFO, 0xf);
if (MCDI_SSPM)
@@ -407,6 +425,8 @@
;
mcdi_ctrl_resume();
+ } else {
+ plat_cpu_pwron_common();
}
plat_cluster_pwron_common(mpidr, cluster);