summaryrefslogtreecommitdiffstats
path: root/plat/mediatek/common/lpm
diff options
context:
space:
mode:
Diffstat (limited to 'plat/mediatek/common/lpm')
-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/common/lpm/rules.mk14
3 files changed, 166 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 0000000..0bafc66
--- /dev/null
+++ b/plat/mediatek/common/lpm/mt_lp_rm.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2020-2022, 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 0000000..e93dac3
--- /dev/null
+++ b/plat/mediatek/common/lpm/mt_lp_rm.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2020-2022, 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/common/lpm/rules.mk b/plat/mediatek/common/lpm/rules.mk
new file mode 100644
index 0000000..87a212a
--- /dev/null
+++ b/plat/mediatek/common/lpm/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := lpm
+LOCAL_SRCS-y := $(LOCAL_DIR)/mt_lp_rm.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))