feat(mt8188): add apusys ao devapc setting
Apusys ao devapc is a set of control registers inside APU, and it
controls the access permission of APU ao domain.
Moreover, apusys ao devapc must be set after apusys power init, so
we need to place the drivers in TF-A instead of coreboot.
Change-Id: Ife849c32d4dd9dca15432d4b8a51753fde61b148
diff --git a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.c b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.c
new file mode 100644
index 0000000..4bd4272
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* TF-A system header */
+#include <common/debug.h>
+#include <lib/utils_def.h>
+
+/* Vendor header */
+#include "apusys.h"
+#include "apusys_dapc_v1.h"
+#include <platform_def.h>
+
+enum apusys_apc_err_status set_apusys_dapc_v1(const struct apc_dom_16 *dapc,
+ uint32_t size, dapc_cfg_func cfg)
+{
+ enum apusys_apc_err_status ret = APUSYS_APC_OK;
+ uint32_t i;
+
+ if ((dapc == NULL) || (cfg == NULL)) {
+ return APUSYS_APC_ERR_GENERIC;
+ }
+
+ for (i = 0; i < size; i++) {
+ ret += cfg(i, DOMAIN_0, dapc[i].d0_permission);
+ ret += cfg(i, DOMAIN_1, dapc[i].d1_permission);
+ ret += cfg(i, DOMAIN_2, dapc[i].d2_permission);
+ ret += cfg(i, DOMAIN_3, dapc[i].d3_permission);
+ ret += cfg(i, DOMAIN_4, dapc[i].d4_permission);
+ ret += cfg(i, DOMAIN_5, dapc[i].d5_permission);
+ ret += cfg(i, DOMAIN_6, dapc[i].d6_permission);
+ ret += cfg(i, DOMAIN_7, dapc[i].d7_permission);
+ ret += cfg(i, DOMAIN_8, dapc[i].d8_permission);
+ ret += cfg(i, DOMAIN_9, dapc[i].d9_permission);
+ ret += cfg(i, DOMAIN_10, dapc[i].d10_permission);
+ ret += cfg(i, DOMAIN_11, dapc[i].d11_permission);
+ ret += cfg(i, DOMAIN_12, dapc[i].d12_permission);
+ ret += cfg(i, DOMAIN_13, dapc[i].d13_permission);
+ ret += cfg(i, DOMAIN_14, dapc[i].d14_permission);
+ ret += cfg(i, DOMAIN_15, dapc[i].d15_permission);
+ }
+
+ if (ret != APUSYS_APC_OK) {
+ ret = APUSYS_APC_ERR_GENERIC;
+ }
+
+ return ret;
+}
+
+void dump_apusys_dapc_v1(const char *name, uintptr_t base, uint32_t reg_num, uint32_t dom_num)
+{
+ uint32_t d, i;
+
+ if ((name == NULL) || (base == 0)) {
+ return;
+ }
+
+ for (d = 0; d < dom_num; d++) {
+ for (i = 0; i <= reg_num; i++) {
+ INFO(MODULE_TAG "[%s] D%d_APC_%d: 0x%x\n", name, d, i,
+ mmio_read_32(base + d * DEVAPC_DOM_SIZE + i * DEVAPC_REG_SIZE));
+ }
+ }
+
+ INFO(MODULE_TAG "[%s] APC_CON: 0x%x\n", name, mmio_read_32(APUSYS_DAPC_CON(base)));
+}
diff --git a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
new file mode 100644
index 0000000..621a08c
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_DAPC_V1_H
+#define APUSYS_DAPC_V1_H
+
+#include <lib/mmio.h>
+
+/******************************************************************************
+ * STRUCTURE DEFINITION
+ ******************************************************************************/
+enum apusys_apc_err_status {
+ APUSYS_APC_OK = 0x0,
+ APUSYS_APC_ERR_GENERIC = 0x1,
+};
+
+enum apusys_apc_perm_type {
+ NO_PROTECTION = 0,
+ SEC_RW_ONLY = 1,
+ SEC_RW_NS_R = 2,
+ FORBIDDEN = 3,
+ PERM_NUM = 4,
+};
+
+enum apusys_apc_domain_id {
+ DOMAIN_0 = 0,
+ DOMAIN_1 = 1,
+ DOMAIN_2 = 2,
+ DOMAIN_3 = 3,
+ DOMAIN_4 = 4,
+ DOMAIN_5 = 5,
+ DOMAIN_6 = 6,
+ DOMAIN_7 = 7,
+ DOMAIN_8 = 8,
+ DOMAIN_9 = 9,
+ DOMAIN_10 = 10,
+ DOMAIN_11 = 11,
+ DOMAIN_12 = 12,
+ DOMAIN_13 = 13,
+ DOMAIN_14 = 14,
+ DOMAIN_15 = 15,
+};
+
+struct apc_dom_16 {
+ unsigned char d0_permission;
+ unsigned char d1_permission;
+ unsigned char d2_permission;
+ unsigned char d3_permission;
+ unsigned char d4_permission;
+ unsigned char d5_permission;
+ unsigned char d6_permission;
+ unsigned char d7_permission;
+ unsigned char d8_permission;
+ unsigned char d9_permission;
+ unsigned char d10_permission;
+ unsigned char d11_permission;
+ unsigned char d12_permission;
+ unsigned char d13_permission;
+ unsigned char d14_permission;
+ unsigned char d15_permission;
+};
+
+#define APUSYS_APC_AO_ATTR(DEV_NAME, \
+ PERM_ATTR0, PERM_ATTR1, PERM_ATTR2, PERM_ATTR3, \
+ PERM_ATTR4, PERM_ATTR5, PERM_ATTR6, PERM_ATTR7, \
+ PERM_ATTR8, PERM_ATTR9, PERM_ATTR10, PERM_ATTR11, \
+ PERM_ATTR12, PERM_ATTR13, PERM_ATTR14, PERM_ATTR15) \
+ {(unsigned char)PERM_ATTR0, (unsigned char)PERM_ATTR1, \
+ (unsigned char)PERM_ATTR2, (unsigned char)PERM_ATTR3, \
+ (unsigned char)PERM_ATTR4, (unsigned char)PERM_ATTR5, \
+ (unsigned char)PERM_ATTR6, (unsigned char)PERM_ATTR7, \
+ (unsigned char)PERM_ATTR8, (unsigned char)PERM_ATTR9, \
+ (unsigned char)PERM_ATTR10, (unsigned char)PERM_ATTR11, \
+ (unsigned char)PERM_ATTR12, (unsigned char)PERM_ATTR13, \
+ (unsigned char)PERM_ATTR14, (unsigned char)PERM_ATTR15}
+
+typedef enum apusys_apc_err_status (*dapc_cfg_func)(uint32_t slave,
+ enum apusys_apc_domain_id domain_id,
+ enum apusys_apc_perm_type perm);
+
+/* Register */
+#define DEVAPC_DOM_SIZE (0x40)
+#define DEVAPC_REG_SIZE (4)
+
+/* APUSYS APC offsets */
+#define APUSYS_DAPC_CON_VIO_MASK (0x80000000)
+#define APUSYS_DAPC_CON(base) ((base) + 0x00f00)
+
+/******************************************************************************
+ * DAPC Common Function
+ ******************************************************************************/
+#define SET_APUSYS_DAPC_V1(dapc, cfg) \
+ set_apusys_dapc_v1(dapc, ARRAY_SIZE(dapc), cfg)
+
+#define DUMP_APUSYS_DAPC_V1(apc) \
+ dump_apusys_dapc_v1(#apc, apc##_BASE, \
+ (apc##_SLAVE_NUM / apc##_SLAVE_NUM_IN_1_DOM), apc##_DOM_NUM)
+
+enum apusys_apc_err_status set_apusys_dapc_v1(const struct apc_dom_16 *dapc,
+ uint32_t size, dapc_cfg_func cfg);
+
+void dump_apusys_dapc_v1(const char *name, uintptr_t base, uint32_t reg_num, uint32_t dom_num);
+
+/******************************************************************************
+ * DAPC Permission Policy
+ ******************************************************************************/
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D5_NO_PROTECT(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ SEC_RW_NS_R, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D7_NO_PROTECT(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D5_D7_NO_PROTECT(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ NO_PROTECTION, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ NO_PROTECTION, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
+ FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#endif /* APUSYS_DAPC_V1_H */
diff --git a/plat/mediatek/drivers/apusys/devapc/rules.mk b/plat/mediatek/drivers/apusys/devapc/rules.mk
new file mode 100644
index 0000000..6153b31
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/devapc/rules.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2023, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := apusys_devapc
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_dapc_v1.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))