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