diff options
author | Chengci.Xu <chengci.xu@mediatek.com> | 2022-08-17 20:46:07 +0800 |
---|---|---|
committer | Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | 2022-08-30 20:54:05 +0300 |
commit | 4e508b259ed02f5fa608cdd83b817a7f49c22271 (patch) | |
tree | fe616ab4fcbaa42cd115da667be36d1e8e39582b /drivers/memory | |
parent | 8c1561edc0692fa8e321daf2777c3c32454b5748 (diff) |
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
Diffstat (limited to 'drivers/memory')
-rw-r--r-- | drivers/memory/mtk-smi.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 7e97406ab4a3..73a8a9867082 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -3,6 +3,7 @@ * Copyright (c) 2015-2016 MediaTek Inc. * Author: Yong Wu <yong.wu@mediatek.com> */ +#include <linux/arm-smccc.h> #include <linux/clk.h> #include <linux/component.h> #include <linux/device.h> @@ -14,6 +15,7 @@ #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/soc/mediatek/mtk_sip_svc.h> #include <soc/mediatek/smi.h> #include <dt-bindings/memory/mt2701-larb-port.h> #include <dt-bindings/memory/mtk-memory-port.h> @@ -89,6 +91,7 @@ #define MTK_SMI_FLAG_THRT_UPDATE BIT(0) #define MTK_SMI_FLAG_SW_FLAG BIT(1) #define MTK_SMI_FLAG_SLEEP_CTL BIT(2) +#define MTK_SMI_FLAG_CFG_PORT_SEC_CTL BIT(3) #define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x))) struct mtk_smi_reg_pair { @@ -238,6 +241,7 @@ static int mtk_smi_larb_config_port_gen2_general(struct device *dev) struct mtk_smi_larb *larb = dev_get_drvdata(dev); u32 reg, flags_general = larb->larb_gen->flags_general; const u8 *larbostd = larb->larb_gen->ostd ? larb->larb_gen->ostd[larb->larbid] : NULL; + struct arm_smccc_res res; int i; if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask) @@ -256,6 +260,20 @@ static int mtk_smi_larb_config_port_gen2_general(struct device *dev) for (i = 0; i < SMI_LARB_PORT_NR_MAX && larbostd && !!larbostd[i]; i++) writel_relaxed(larbostd[i], larb->base + SMI_LARB_OSTDL_PORTx(i)); + /* + * When mmu_en bits are in security world, the bank_sel still is in the + * LARB_NONSEC_CON below. And the mmu_en bits of LARB_NONSEC_CON have no + * effect in this case. + */ + if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_CFG_PORT_SEC_CTL)) { + arm_smccc_smc(MTK_SIP_KERNEL_IOMMU_CONTROL, IOMMU_ATF_CMD_CONFIG_SMI_LARB, + larb->larbid, *larb->mmu, 0, 0, 0, 0, &res); + if (res.a0 != 0) { + dev_err(dev, "Enable iommu fail, ret %ld\n", res.a0); + return -EINVAL; + } + } + for_each_set_bit(i, (unsigned long *)larb->mmu, 32) { reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i)); reg |= F_MMU_EN; |