Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

memory: mtk-smi: Add enable IOMMU SMC command for MM master

For concerns about security, the register to enable/disable IOMMU of
SMI LARB should only be configured in secure world. Thus, we add some
SMC command for multimedia master to enable/disable MM IOMMU in ATF by
setting the register of SMI LARB. This function is prepared for MT8188.

Signed-off-by: Chengci.Xu <chengci.xu@mediatek.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20220817124608.10062-4-chengci.xu@mediatek.com

authored by

Chengci.Xu and committed by
Krzysztof Kozlowski
4e508b25 8c1561ed

+26
+18
drivers/memory/mtk-smi.c
··· 3 3 * Copyright (c) 2015-2016 MediaTek Inc. 4 4 * Author: Yong Wu <yong.wu@mediatek.com> 5 5 */ 6 + #include <linux/arm-smccc.h> 6 7 #include <linux/clk.h> 7 8 #include <linux/component.h> 8 9 #include <linux/device.h> ··· 15 14 #include <linux/of_platform.h> 16 15 #include <linux/platform_device.h> 17 16 #include <linux/pm_runtime.h> 17 + #include <linux/soc/mediatek/mtk_sip_svc.h> 18 18 #include <soc/mediatek/smi.h> 19 19 #include <dt-bindings/memory/mt2701-larb-port.h> 20 20 #include <dt-bindings/memory/mtk-memory-port.h> ··· 91 89 #define MTK_SMI_FLAG_THRT_UPDATE BIT(0) 92 90 #define MTK_SMI_FLAG_SW_FLAG BIT(1) 93 91 #define MTK_SMI_FLAG_SLEEP_CTL BIT(2) 92 + #define MTK_SMI_FLAG_CFG_PORT_SEC_CTL BIT(3) 94 93 #define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x))) 95 94 96 95 struct mtk_smi_reg_pair { ··· 241 238 struct mtk_smi_larb *larb = dev_get_drvdata(dev); 242 239 u32 reg, flags_general = larb->larb_gen->flags_general; 243 240 const u8 *larbostd = larb->larb_gen->ostd ? larb->larb_gen->ostd[larb->larbid] : NULL; 241 + struct arm_smccc_res res; 244 242 int i; 245 243 246 244 if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask) ··· 259 255 260 256 for (i = 0; i < SMI_LARB_PORT_NR_MAX && larbostd && !!larbostd[i]; i++) 261 257 writel_relaxed(larbostd[i], larb->base + SMI_LARB_OSTDL_PORTx(i)); 258 + 259 + /* 260 + * When mmu_en bits are in security world, the bank_sel still is in the 261 + * LARB_NONSEC_CON below. And the mmu_en bits of LARB_NONSEC_CON have no 262 + * effect in this case. 263 + */ 264 + if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_CFG_PORT_SEC_CTL)) { 265 + arm_smccc_smc(MTK_SIP_KERNEL_IOMMU_CONTROL, IOMMU_ATF_CMD_CONFIG_SMI_LARB, 266 + larb->larbid, *larb->mmu, 0, 0, 0, 0, &res); 267 + if (res.a0 != 0) { 268 + dev_err(dev, "Enable iommu fail, ret %ld\n", res.a0); 269 + return -EINVAL; 270 + } 271 + } 262 272 263 273 for_each_set_bit(i, (unsigned long *)larb->mmu, 32) { 264 274 reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
+3
include/linux/soc/mediatek/mtk_sip_svc.h
··· 22 22 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, MTK_SIP_SMC_CONVENTION, \ 23 23 ARM_SMCCC_OWNER_SIP, fn_id) 24 24 25 + /* IOMMU related SMC call */ 26 + #define MTK_SIP_KERNEL_IOMMU_CONTROL MTK_SIP_SMC_CMD(0x514) 27 + 25 28 #endif
+5
include/soc/mediatek/smi.h
··· 11 11 12 12 #if IS_ENABLED(CONFIG_MTK_SMI) 13 13 14 + enum iommu_atf_cmd { 15 + IOMMU_ATF_CMD_CONFIG_SMI_LARB, /* For mm master to en/disable iommu */ 16 + IOMMU_ATF_CMD_MAX, 17 + }; 18 + 14 19 #define MTK_SMI_MMU_EN(port) BIT(port) 15 20 16 21 struct mtk_smi_larb_iommu {