feat(mt8188): add backup/restore function when power on/off
Add APU backup/restore function when power on/off.
Change-Id: Id0451bd12f402e1acabeb5c12266a2e01836e9dd
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
index 150f404..1c53aca 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
@@ -19,6 +19,10 @@
#define UP_CORE0_MVABASE0 (APU_REVISER + 0x0010)
#define UP_CORE0_VABASE1 (APU_REVISER + 0x0014)
#define UP_CORE0_MVABASE1 (APU_REVISER + 0x0018)
+#define UP_CORE0_VABASE2 (APU_REVISER + 0x001c)
+#define UP_CORE0_MVABASE2 (APU_REVISER + 0x0020)
+#define UP_CORE0_VABASE3 (APU_REVISER + 0x0024)
+#define UP_CORE0_MVABASE3 (APU_REVISER + 0x0028)
#define USERFW_CTXT (APU_REVISER + 0x1000)
#define SECUREFW_CTXT (APU_REVISER + 0x1004)
#define UP_NORMAL_DOMAIN (7)
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
index ac62f2f..cdfc133 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
@@ -17,6 +17,7 @@
/* Vendor header */
#include "apusys.h"
#include "apusys_power.h"
+#include "apusys_rv.h"
#include <mtk_mmap_pool.h>
static spinlock_t apu_lock;
@@ -47,6 +48,43 @@
return -1;
}
+static void apu_backup_restore(enum APU_BACKUP_RESTORE_CTRL ctrl)
+{
+ int i;
+ static struct apu_restore_data apu_restore_data[] = {
+ { UP_NORMAL_DOMAIN_NS, 0 },
+ { UP_PRI_DOMAIN_NS, 0 },
+ { UP_IOMMU_CTRL, 0 },
+ { UP_CORE0_VABASE0, 0 },
+ { UP_CORE0_MVABASE0, 0 },
+ { UP_CORE0_VABASE1, 0 },
+ { UP_CORE0_MVABASE1, 0 },
+ { UP_CORE0_VABASE2, 0 },
+ { UP_CORE0_MVABASE2, 0 },
+ { UP_CORE0_VABASE3, 0 },
+ { UP_CORE0_MVABASE3, 0 },
+ { MD32_SYS_CTRL, 0 },
+ { MD32_CLK_CTRL, 0 },
+ { UP_WAKE_HOST_MASK0, 0 }
+ };
+
+ switch (ctrl) {
+ case APU_CTRL_BACKUP:
+ for (i = 0; i < ARRAY_SIZE(apu_restore_data); i++) {
+ apu_restore_data[i].data = mmio_read_32(apu_restore_data[i].reg);
+ }
+ break;
+ case APU_CTRL_RESTORE:
+ for (i = 0; i < ARRAY_SIZE(apu_restore_data); i++) {
+ mmio_write_32(apu_restore_data[i].reg, apu_restore_data[i].data);
+ }
+ break;
+ default:
+ ERROR(MODULE_TAG "%s invalid op: %d\n", __func__, ctrl);
+ break;
+ }
+}
+
static void apu_xpu2apusys_d4_slv_en(enum APU_D4_SLV_CTRL en)
{
switch (en) {
@@ -120,6 +158,8 @@
apu_xpu2apusys_d4_slv_en(D4_SLV_OFF);
+ apu_backup_restore(APU_CTRL_RESTORE);
+
apusys_top_on = true;
spin_unlock(&apu_lock);
@@ -153,6 +193,8 @@
return 0;
}
+ apu_backup_restore(APU_CTRL_BACKUP);
+
apu_xpu2apusys_d4_slv_en(D4_SLV_ON);
if (mmio_read_32(APU_MBOX0_BASE + PWR_FLOW_SYNC_REG) == 0) {
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.h b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
index b4968d6..460cc50 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
@@ -29,6 +29,16 @@
D4_SLV_ON,
};
+enum APU_BACKUP_RESTORE_CTRL {
+ APU_CTRL_BACKUP = 0,
+ APU_CTRL_RESTORE = 1,
+};
+
+struct apu_restore_data {
+ uint32_t reg;
+ uint32_t data;
+};
+
#define APU_POLL_STEP_US (5)
#define OUT_CLK_FREQ_MIN (1500)