Message ID | 20220919082611.19824-3-chengci.xu@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | MT8188 IOMMU SUPPORT | expand |
Il 19/09/22 10:26, Chengci.Xu ha scritto: > The register which can enable IOMMU for INFRA master should be setted > in secure world for security concerns. Therefore, we add a SMC command > for INFRA master to enable/disable INFRA IOMMU in ATF. This function is > prepared for MT8188. > > Signed-off-by: Chengci.Xu <chengci.xu@mediatek.com> > --- > drivers/iommu/mtk_iommu.c | 21 +++++++++++++++++++-- > include/soc/mediatek/smi.h | 1 + > 2 files changed, 20 insertions(+), 2 deletions(-) > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > index 552e4eb8c610..8b8a289bab2c 100644 > --- a/drivers/iommu/mtk_iommu.c > +++ b/drivers/iommu/mtk_iommu.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/bitfield.h> > #include <linux/bug.h> > #include <linux/clk.h> > @@ -28,6 +29,7 @@ > #include <linux/slab.h> > #include <linux/spinlock.h> > #include <linux/soc/mediatek/infracfg.h> > +#include <linux/soc/mediatek/mtk_sip_svc.h> > #include <asm/barrier.h> > #include <soc/mediatek/smi.h> > > @@ -138,6 +140,7 @@ > #define PM_CLK_AO BIT(15) > #define IFA_IOMMU_PCIE_SUPPORT BIT(16) > #define PGTABLE_PA_35_EN BIT(17) > +#define CFG_IFA_MASTER_IN_ATF BIT(18) > > #define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask) \ > ((((pdata)->flags) & (mask)) == (_x)) > @@ -553,7 +556,20 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev, > larb_mmu->mmu |= MTK_SMI_MMU_EN(portid); > else > larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid); > - } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) { > + } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) && > + MTK_IOMMU_HAS_FLAG(data->plat_data, CFG_IFA_MASTER_IN_ATF)) { > + struct arm_smccc_res res; > + > + arm_smccc_smc(MTK_SIP_KERNEL_IOMMU_CONTROL, > + IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU, > + portid, enable, 0, 0, 0, 0, &res); > + if (res.a0 != 0) { > + dev_err(dev, "%s iommu(%s) inframaster %d fail(%ld).\n", > + enable ? "enable" : "disable", > + dev_name(data->dev), portid, res.a0); > + ret = -EINVAL; > + } > + } else { This one is opening a big window for future mistakes. I think that the only way that you have to do this is... } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) { if (MTK_IOMMU_HAS_FLAG(data->plat_data, CFG_IFA_MASTER_IN_ATF)) { arm_smcc_smc .... } else { peri_mmuen_msk .... } } Otherwise, to reduce indentation, you'd have to do something like... static int mtk_iommu_config_one(struct mtk_iommu_data *data, struct device *dev, bool enable, u32 regionid, u32 larbid, u32 portid) { struct mtk_smi_larb_iommu *larb_mmu; ............ } static int mtk_iommu_config(struct .............) { vars, etc.... for (i = 0; i < fwspec->num_ids; ++i) mtk_iommu_config_one(data, dev, enable, regionid, MTK_M4U_TO_LARB(...), MTK_M4U_TO_PORT(...)); } or.... static int mtk_iommu_config_one_infra(struct ....) { if (is atf) .... else .... } Your choice. Regards, Angelo
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 552e4eb8c610..8b8a289bab2c 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.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/bitfield.h> #include <linux/bug.h> #include <linux/clk.h> @@ -28,6 +29,7 @@ #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/soc/mediatek/infracfg.h> +#include <linux/soc/mediatek/mtk_sip_svc.h> #include <asm/barrier.h> #include <soc/mediatek/smi.h> @@ -138,6 +140,7 @@ #define PM_CLK_AO BIT(15) #define IFA_IOMMU_PCIE_SUPPORT BIT(16) #define PGTABLE_PA_35_EN BIT(17) +#define CFG_IFA_MASTER_IN_ATF BIT(18) #define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask) \ ((((pdata)->flags) & (mask)) == (_x)) @@ -553,7 +556,20 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev, larb_mmu->mmu |= MTK_SMI_MMU_EN(portid); else larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid); - } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) { + } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) && + MTK_IOMMU_HAS_FLAG(data->plat_data, CFG_IFA_MASTER_IN_ATF)) { + struct arm_smccc_res res; + + arm_smccc_smc(MTK_SIP_KERNEL_IOMMU_CONTROL, + IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU, + portid, enable, 0, 0, 0, 0, &res); + if (res.a0 != 0) { + dev_err(dev, "%s iommu(%s) inframaster %d fail(%ld).\n", + enable ? "enable" : "disable", + dev_name(data->dev), portid, res.a0); + ret = -EINVAL; + } + } else { peri_mmuen_msk = BIT(portid); /* PCI dev has only one output id, enable the next writing bit for PCIe */ if (dev_is_pci(dev)) @@ -1213,7 +1229,8 @@ static int mtk_iommu_probe(struct platform_device *pdev) dev_err_probe(dev, ret, "mm dts parse fail\n"); goto out_runtime_disable; } - } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) { + } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) && + !MTK_IOMMU_HAS_FLAG(data->plat_data, CFG_IFA_MASTER_IN_ATF)) { p = data->plat_data->pericfg_comp_str; data->pericfg = syscon_regmap_lookup_by_compatible(p); if (IS_ERR(data->pericfg)) { diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h index dfd8efca5e60..99f13b0e416d 100644 --- a/include/soc/mediatek/smi.h +++ b/include/soc/mediatek/smi.h @@ -13,6 +13,7 @@ enum iommu_atf_cmd { IOMMU_ATF_CMD_CONFIG_SMI_LARB, /* For mm master to en/disable iommu */ + IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU, /* For infra master en/disable iommu */ IOMMU_ATF_CMD_MAX, };
The register which can enable IOMMU for INFRA master should be setted in secure world for security concerns. Therefore, we add a SMC command for INFRA master to enable/disable INFRA IOMMU in ATF. This function is prepared for MT8188. Signed-off-by: Chengci.Xu <chengci.xu@mediatek.com> --- drivers/iommu/mtk_iommu.c | 21 +++++++++++++++++++-- include/soc/mediatek/smi.h | 1 + 2 files changed, 20 insertions(+), 2 deletions(-)