xref: /arm-trusted-firmware/plat/mediatek/drivers/iommu/mtk_iommu_smc.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <stddef.h>
8*91f16700Schasinglulu #include <mtk_iommu_plat.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu /* defination */
11*91f16700Schasinglulu /* smi larb */
12*91f16700Schasinglulu #define SMI_LARB_NON_SEC_CON(port)	(0x380 + ((port) << 2))
13*91f16700Schasinglulu #define PATH_SEL_MASK			(0xf0000) /* to sram (INT) */
14*91f16700Schasinglulu #define SMI_LARB_SEC_CON_INT(port)	(0xf00 + ((port) << 2))
15*91f16700Schasinglulu #define SMI_LARB_SEC_CON(port)		(0xf80 + ((port) << 2))
16*91f16700Schasinglulu #define MMU_MASK			BIT(0)
17*91f16700Schasinglulu #define MMU_EN(en)			((!!(en)) << 0)
18*91f16700Schasinglulu #define SEC_MASK			BIT(1)
19*91f16700Schasinglulu #define SEC_EN(en)			((!!(en)) << 1)
20*91f16700Schasinglulu #define DOMAIN_MASK			(0x1f << 4)
21*91f16700Schasinglulu #define SMI_MMU_EN(port)		(0x1 << (port))
22*91f16700Schasinglulu 
23*91f16700Schasinglulu /* infra master */
24*91f16700Schasinglulu #define IFR_CFG_MMU_EN_MSK(r_bit)	(0x3 << (r_bit))
25*91f16700Schasinglulu 
26*91f16700Schasinglulu /* smi larb configure */
27*91f16700Schasinglulu /*
28*91f16700Schasinglulu  * If multimedia security config is enabled, the SMI config register must be
29*91f16700Schasinglulu  * configurated in security world.
30*91f16700Schasinglulu  * And the SRAM path is also configurated here to enhance security.
31*91f16700Schasinglulu  */
32*91f16700Schasinglulu static void mtk_smi_larb_port_config_to_sram(
33*91f16700Schasinglulu 				const struct mtk_smi_larb_config *larb,
34*91f16700Schasinglulu 				uint32_t port_id)
35*91f16700Schasinglulu {
36*91f16700Schasinglulu 	mmio_clrbits_32(larb->base + SMI_LARB_SEC_CON_INT(port_id),
37*91f16700Schasinglulu 			MMU_MASK | SEC_MASK | DOMAIN_MASK);
38*91f16700Schasinglulu 
39*91f16700Schasinglulu 	mmio_setbits_32(larb->base + SMI_LARB_NON_SEC_CON(port_id),
40*91f16700Schasinglulu 			PATH_SEL_MASK);
41*91f16700Schasinglulu }
42*91f16700Schasinglulu 
43*91f16700Schasinglulu static void mtk_smi_port_config(const struct mtk_smi_larb_config *larb,
44*91f16700Schasinglulu 				uint32_t port_id, uint8_t mmu_en, uint8_t sec_en)
45*91f16700Schasinglulu {
46*91f16700Schasinglulu 	mmio_clrsetbits_32(larb->base + SMI_LARB_SEC_CON(port_id),
47*91f16700Schasinglulu 			   MMU_MASK | SEC_MASK | DOMAIN_MASK,
48*91f16700Schasinglulu 			   MMU_EN(mmu_en) | SEC_EN(sec_en));
49*91f16700Schasinglulu }
50*91f16700Schasinglulu 
51*91f16700Schasinglulu static int mtk_smi_larb_port_config_sec(uint32_t larb_id, uint32_t mmu_en_msk)
52*91f16700Schasinglulu {
53*91f16700Schasinglulu 	uint32_t port_id, port_nr;
54*91f16700Schasinglulu 	const struct mtk_smi_larb_config *larb;
55*91f16700Schasinglulu 	uint32_t to_sram;
56*91f16700Schasinglulu 	uint8_t mmu_en;
57*91f16700Schasinglulu 
58*91f16700Schasinglulu 	if (larb_id >= SMI_LARB_NUM) {
59*91f16700Schasinglulu 		return MTK_SIP_E_INVALID_PARAM;
60*91f16700Schasinglulu 	}
61*91f16700Schasinglulu 
62*91f16700Schasinglulu 	larb = &g_larb_cfg[larb_id];
63*91f16700Schasinglulu 	port_nr = larb->port_nr;
64*91f16700Schasinglulu 	to_sram = larb->to_sram;
65*91f16700Schasinglulu 
66*91f16700Schasinglulu 	for (port_id = 0; port_id < port_nr; port_id++) {
67*91f16700Schasinglulu 		if ((to_sram & BIT(port_id)) > 0U) {
68*91f16700Schasinglulu 			mtk_smi_larb_port_config_to_sram(larb, port_id);
69*91f16700Schasinglulu 			continue;
70*91f16700Schasinglulu 		}
71*91f16700Schasinglulu 		mmu_en = !!(mmu_en_msk & SMI_MMU_EN(port_id));
72*91f16700Schasinglulu 		mtk_smi_port_config(larb, port_id, mmu_en, 0);
73*91f16700Schasinglulu 	}
74*91f16700Schasinglulu 
75*91f16700Schasinglulu 	return MTK_SIP_E_SUCCESS;
76*91f16700Schasinglulu }
77*91f16700Schasinglulu 
78*91f16700Schasinglulu static int mtk_infra_master_config_sec(uint32_t dev_id_msk, uint32_t enable)
79*91f16700Schasinglulu {
80*91f16700Schasinglulu 	const struct mtk_ifr_mst_config *ifr_cfg;
81*91f16700Schasinglulu 	uint32_t dev_id, reg_addr, reg_mask;
82*91f16700Schasinglulu 
83*91f16700Schasinglulu 	mtk_infra_iommu_enable_protect();
84*91f16700Schasinglulu 
85*91f16700Schasinglulu 	if (dev_id_msk >= BIT(MMU_DEV_NUM)) {
86*91f16700Schasinglulu 		return MTK_SIP_E_INVALID_PARAM;
87*91f16700Schasinglulu 	}
88*91f16700Schasinglulu 
89*91f16700Schasinglulu 	for (dev_id = 0U; dev_id < MMU_DEV_NUM; dev_id++) {
90*91f16700Schasinglulu 		if ((dev_id_msk & BIT(dev_id)) == 0U) {
91*91f16700Schasinglulu 			continue;
92*91f16700Schasinglulu 		}
93*91f16700Schasinglulu 
94*91f16700Schasinglulu 		ifr_cfg = &g_ifr_mst_cfg[dev_id];
95*91f16700Schasinglulu 		reg_addr = g_ifr_mst_cfg_base[(ifr_cfg->cfg_addr_idx)] +
96*91f16700Schasinglulu 			   g_ifr_mst_cfg_offs[(ifr_cfg->cfg_addr_idx)];
97*91f16700Schasinglulu 		reg_mask = IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit);
98*91f16700Schasinglulu 
99*91f16700Schasinglulu 		if (enable > 0U) {
100*91f16700Schasinglulu 			mmio_setbits_32(reg_addr, reg_mask);
101*91f16700Schasinglulu 		} else {
102*91f16700Schasinglulu 			mmio_clrbits_32(reg_addr, reg_mask);
103*91f16700Schasinglulu 		}
104*91f16700Schasinglulu 	}
105*91f16700Schasinglulu 
106*91f16700Schasinglulu 	return MTK_SIP_E_SUCCESS;
107*91f16700Schasinglulu }
108*91f16700Schasinglulu 
109*91f16700Schasinglulu static u_register_t mtk_iommu_handler(u_register_t x1, u_register_t x2,
110*91f16700Schasinglulu 				      u_register_t x3, u_register_t x4,
111*91f16700Schasinglulu 				      void *handle, struct smccc_res *smccc_ret)
112*91f16700Schasinglulu {
113*91f16700Schasinglulu 	uint32_t cmd_id = x1, mdl_id = x2, val = x3;
114*91f16700Schasinglulu 	int ret = MTK_SIP_E_NOT_SUPPORTED;
115*91f16700Schasinglulu 
116*91f16700Schasinglulu 	(void)x4;
117*91f16700Schasinglulu 	(void)handle;
118*91f16700Schasinglulu 
119*91f16700Schasinglulu 	switch (cmd_id) {
120*91f16700Schasinglulu 	case IOMMU_ATF_CMD_CONFIG_SMI_LARB:
121*91f16700Schasinglulu 		ret = mtk_smi_larb_port_config_sec(mdl_id, val);
122*91f16700Schasinglulu 		break;
123*91f16700Schasinglulu 	case IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU:
124*91f16700Schasinglulu 		ret = mtk_infra_master_config_sec(mdl_id, val);
125*91f16700Schasinglulu 		break;
126*91f16700Schasinglulu 	default:
127*91f16700Schasinglulu 		break;
128*91f16700Schasinglulu 	}
129*91f16700Schasinglulu 
130*91f16700Schasinglulu 	return ret;
131*91f16700Schasinglulu }
132*91f16700Schasinglulu DECLARE_SMC_HANDLER(MTK_SIP_IOMMU_CONTROL, mtk_iommu_handler);
133