aboutsummaryrefslogtreecommitdiff
path: root/plat/mediatek
diff options
context:
space:
mode:
authorRoger Lu <roger.lu@mediatek.com>2020-12-14 16:53:22 +0800
committerYidi Lin <yidi.lin@mediatek.com>2021-03-03 19:04:43 +0800
commitcab4919955af17eb594c2e2e8de0e54b221854e2 (patch)
treef9d90dab1462de1aed36cf7c043c4abd5ff9e092 /plat/mediatek
parentc0f0ab53b4b61d2e83d589d4c10722bd6596c073 (diff)
downloadtrusted-firmware-a-cab4919955af17eb594c2e2e8de0e54b221854e2.tar.gz
mediatek: mt8192: Add lpm driver
Low Power Management (LPM) helps find a suitable configuration for letting system entering idle or suspend with the most resources off. Change-Id: Ie6a7063b666cf338cff5bc972c9025b26de482eb Signed-off-by: Roger Lu <roger.lu@mediatek.com>
Diffstat (limited to 'plat/mediatek')
-rw-r--r--plat/mediatek/common/lpm/mt_lp_rm.c110
-rw-r--r--plat/mediatek/common/lpm/mt_lp_rm.h42
-rw-r--r--plat/mediatek/mt8192/platform.mk2
3 files changed, 154 insertions, 0 deletions
diff --git a/plat/mediatek/common/lpm/mt_lp_rm.c b/plat/mediatek/common/lpm/mt_lp_rm.c
new file mode 100644
index 0000000000..f3148fe744
--- /dev/null
+++ b/plat/mediatek/common/lpm/mt_lp_rm.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mt_lp_rm.h>
+#include <stddef.h>
+
+struct platform_mt_resource_manager {
+ unsigned int count;
+ struct mt_resource_manager *plat_rm;
+};
+
+static struct platform_mt_resource_manager plat_mt_rm;
+
+int mt_lp_rm_register(struct mt_resource_manager *rm)
+{
+ unsigned int i;
+ struct mt_resource_constraint *const *rc;
+
+ if ((rm == NULL) || (rm->consts == NULL) ||
+ (plat_mt_rm.plat_rm != NULL)) {
+ return MT_RM_STATUS_BAD;
+ }
+
+ for (i = 0U, rc = rm->consts; *rc != NULL; i++, rc++) {
+ if ((*rc)->init != NULL) {
+ (*rc)->init();
+ }
+ }
+
+ plat_mt_rm.plat_rm = rm;
+ plat_mt_rm.count = i;
+
+ return MT_RM_STATUS_OK;
+}
+
+int mt_lp_rm_reset_constraint(int idx, unsigned int cpuid, int stateid)
+{
+ struct mt_resource_constraint const *rc = NULL;
+
+ if ((plat_mt_rm.plat_rm == NULL) || (idx < 0) ||
+ (idx >= plat_mt_rm.count)) {
+ return MT_RM_STATUS_BAD;
+ }
+
+ rc = plat_mt_rm.plat_rm->consts[idx];
+
+ if ((rc == NULL) || (rc->reset == NULL)) {
+ return MT_RM_STATUS_BAD;
+ }
+
+ return rc->reset(cpuid, stateid);
+}
+
+int mt_lp_rm_find_and_run_constraint(int idx, unsigned int cpuid,
+ int stateid, void *priv)
+{
+ int i, res = MT_RM_STATUS_BAD;
+ struct mt_resource_constraint *const *rc;
+ struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
+
+ if ((rm == NULL) || (idx < 0) || (idx >= plat_mt_rm.count)) {
+ return res;
+ }
+
+ /* If subsys clk/mtcmos is on, add block-resource-off flag */
+ if (rm->update != NULL) {
+ res = rm->update(rm->consts, stateid, priv);
+ if (res != 0) {
+ return res;
+ }
+ }
+
+ for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) {
+ if (((*rc)->is_valid != NULL) &&
+ ((*rc)->is_valid(cpuid, stateid))) {
+ if (((*rc)->run != NULL) &&
+ ((*rc)->run(cpuid, stateid) == 0)) {
+ res = i;
+ break;
+ }
+ }
+ }
+
+ return res;
+}
+
+int mt_lp_rm_do_update(int stateid, int type, void const *p)
+{
+ int res = MT_RM_STATUS_BAD;
+ struct mt_resource_constraint *const *rc;
+ struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
+
+ if (rm == NULL) {
+ return res;
+ }
+
+ for (rc = rm->consts; *rc != NULL; rc++) {
+ if ((*rc)->update != NULL) {
+ res = (*rc)->update(stateid, type, p);
+ if (res != MT_RM_STATUS_OK) {
+ break;
+ }
+ }
+ }
+
+ return res;
+}
diff --git a/plat/mediatek/common/lpm/mt_lp_rm.h b/plat/mediatek/common/lpm/mt_lp_rm.h
new file mode 100644
index 0000000000..39759f1d22
--- /dev/null
+++ b/plat/mediatek/common/lpm/mt_lp_rm.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_LP_RM_H
+#define MT_LP_RM_H
+
+#include <stdbool.h>
+
+#define MT_RM_STATUS_OK 0
+#define MT_RM_STATUS_BAD -1
+
+enum PLAT_MT_LPM_RC_TYPE {
+ PLAT_RC_UPDATE_CONDITION,
+ PLAT_RC_UPDATE_REMAIN_IRQS
+};
+
+struct mt_resource_constraint {
+ int level;
+ int (*init)(void);
+ bool (*is_valid)(unsigned int cpu, int stateid);
+ int (*update)(int stateid, int type, const void *p);
+ int (*run)(unsigned int cpu, int stateid);
+ int (*reset)(unsigned int cpu, int stateid);
+ unsigned int (*allow)(int stateid);
+};
+
+struct mt_resource_manager {
+ int (*update)(struct mt_resource_constraint **con,
+ int stateid, void *priv);
+ struct mt_resource_constraint **consts;
+};
+
+extern int mt_lp_rm_register(struct mt_resource_manager *rm);
+extern int mt_lp_rm_find_and_run_constraint(int idx, unsigned int cpuid,
+ int stateid, void *priv);
+extern int mt_lp_rm_reset_constraint(int constraint_id, unsigned int cpuid,
+ int stateid);
+extern int mt_lp_rm_do_update(int stateid, int type, void const *p);
+#endif /* MT_LP_RM_H */
diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk
index a5e7ee26a5..9c9b233bb8 100644
--- a/plat/mediatek/mt8192/platform.mk
+++ b/plat/mediatek/mt8192/platform.mk
@@ -8,6 +8,7 @@ MTK_PLAT := plat/mediatek
MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
+ -I${MTK_PLAT}/common/lpm/ \
-I${MTK_PLAT_SOC}/include/ \
-I${MTK_PLAT_SOC}/drivers/ \
-I${MTK_PLAT_SOC}/drivers/dcm \
@@ -42,6 +43,7 @@ BL31_SOURCES += common/desc_image_load.c \
${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init_v2.c \
${MTK_PLAT}/common/drivers/rtc/rtc_common.c \
${MTK_PLAT}/common/drivers/uart/uart.c \
+ ${MTK_PLAT}/common/lpm/mt_lp_rm.c \
${MTK_PLAT}/common/mtk_plat_common.c \
${MTK_PLAT}/common/mtk_sip_svc.c \
${MTK_PLAT}/common/params_setup.c \