summaryrefslogtreecommitdiffstats
path: root/plat/mediatek/mt8183/plat_dcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'plat/mediatek/mt8183/plat_dcm.c')
-rw-r--r--plat/mediatek/mt8183/plat_dcm.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/plat/mediatek/mt8183/plat_dcm.c b/plat/mediatek/mt8183/plat_dcm.c
new file mode 100644
index 0000000..8ee77f1
--- /dev/null
+++ b/plat/mediatek/mt8183/plat_dcm.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2019, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <lib/bakery_lock.h>
+#include <drivers/console.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <plat_dcm.h>
+#include <plat_private.h>
+#include <plat_dcm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <mtk_plat_common.h>
+
+#define PWR_STATUS (SPM_BASE + 0x180)
+
+uint64_t plat_dcm_mcsi_a_addr;
+uint32_t plat_dcm_mcsi_a_val;
+static int plat_dcm_init_type;
+static unsigned int dcm_big_core_cnt;
+int plat_dcm_initiated;
+
+#define PWR_STA_BIG_MP_MASK (0x1 << 15)
+
+DEFINE_BAKERY_LOCK(dcm_lock);
+
+void dcm_lock_init(void)
+{
+ bakery_lock_init(&dcm_lock);
+}
+
+void dcm_lock_get(void)
+{
+ bakery_lock_get(&dcm_lock);
+}
+
+void dcm_lock_release(void)
+{
+ bakery_lock_release(&dcm_lock);
+}
+
+void plat_dcm_mcsi_a_backup(void)
+{
+}
+
+void plat_dcm_mcsi_a_restore(void)
+{
+}
+
+void plat_dcm_rgu_enable(void)
+{
+}
+
+void plat_dcm_big_core_sync(short on)
+{
+ /* Check if Big cluster power is existed */
+ if (!(mmio_read_32(PWR_STATUS) & PWR_STA_BIG_MP_MASK))
+ return;
+
+ if (on) {
+ mmio_write_32(MP2_SYNC_DCM,
+ (mmio_read_32(MP2_SYNC_DCM) & ~MP2_SYNC_DCM_MASK)
+ | MP2_SYNC_DCM_ON);
+ dcm_big_core_cnt++;
+ } else
+ mmio_write_32(MP2_SYNC_DCM,
+ (mmio_read_32(MP2_SYNC_DCM) & ~MP2_SYNC_DCM_MASK)
+ | MP2_SYNC_DCM_OFF);
+}
+
+void plat_dcm_restore_cluster_on(unsigned long mpidr)
+{
+ unsigned long cluster_id =
+ (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
+
+ switch (cluster_id) {
+ case 0x1:
+ dcm_lock_get();
+ if (plat_dcm_init_type & BIG_CORE_DCM_TYPE)
+ plat_dcm_big_core_sync(1);
+ else
+ plat_dcm_big_core_sync(0);
+ dcm_lock_release();
+ break;
+ default:
+ break;
+ }
+}
+
+void plat_dcm_msg_handler(uint64_t x1)
+{
+ plat_dcm_init_type = x1 & ALL_DCM_TYPE;
+}
+
+unsigned long plat_dcm_get_enabled_cnt(uint64_t type)
+{
+ switch (type) {
+ case BIG_CORE_DCM_TYPE:
+ return dcm_big_core_cnt;
+ default:
+ return 0;
+ }
+}
+
+void plat_dcm_init(void)
+{
+ dcm_lock_init();
+}