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