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