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