Skip to content

Commit f9b8c9b

Browse files
YongWu-HFjoergroedel
authored andcommitted
iommu/mediatek: Add infra iommu support
The infra iommu enable bits in mt8195 is in the pericfg register segment, use regmap to update it. If infra iommu master translation fault, It doesn't have the larbid/portid, thus print out the whole register value. Since regmap_update_bits may fail, add return value for mtk_iommu_config. Signed-off-by: Yong Wu <yong.wu@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com> Link: https://lore.kernel.org/r/20220503071427.2285-22-yong.wu@mediatek.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent 6077c7e commit f9b8c9b

2 files changed

Lines changed: 31 additions & 7 deletions

File tree

drivers/iommu/mtk_iommu.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@
112112

113113
#define MTK_PROTECT_PA_ALIGN 256
114114

115+
#define PERICFG_IOMMU_1 0x714
116+
115117
#define HAS_4GB_MODE BIT(0)
116118
/* HW will use the EMI clock if there isn't the "bclk". */
117119
#define HAS_BCLK BIT(1)
@@ -343,8 +345,8 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
343345
write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
344346
dev_err_ratelimited(
345347
data->dev,
346-
"fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d layer=%d %s\n",
347-
int_state, fault_iova, fault_pa, fault_larb, fault_port,
348+
"fault type=0x%x iova=0x%llx pa=0x%llx master=0x%x(larb=%d port=%d) layer=%d %s\n",
349+
int_state, fault_iova, fault_pa, regval, fault_larb, fault_port,
348350
layer, write ? "write" : "read");
349351
}
350352

@@ -388,14 +390,15 @@ static int mtk_iommu_get_domain_id(struct device *dev,
388390
return -EINVAL;
389391
}
390392

391-
static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
392-
bool enable, unsigned int domid)
393+
static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
394+
bool enable, unsigned int domid)
393395
{
394396
struct mtk_smi_larb_iommu *larb_mmu;
395397
unsigned int larbid, portid;
396398
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
397399
const struct mtk_iommu_iova_region *region;
398-
int i;
400+
u32 peri_mmuen, peri_mmuen_msk;
401+
int i, ret = 0;
399402

400403
for (i = 0; i < fwspec->num_ids; ++i) {
401404
larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
@@ -415,8 +418,19 @@ static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
415418
larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
416419
else
417420
larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
421+
} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) {
422+
peri_mmuen_msk = BIT(portid);
423+
peri_mmuen = enable ? peri_mmuen_msk : 0;
424+
425+
ret = regmap_update_bits(data->pericfg, PERICFG_IOMMU_1,
426+
peri_mmuen_msk, peri_mmuen);
427+
if (ret)
428+
dev_err(dev, "%s iommu(%s) inframaster 0x%x fail(%d).\n",
429+
enable ? "enable" : "disable",
430+
dev_name(data->dev), peri_mmuen_msk, ret);
418431
}
419432
}
433+
return ret;
420434
}
421435

422436
static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
@@ -531,8 +545,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
531545
}
532546
mutex_unlock(&data->mutex);
533547

534-
mtk_iommu_config(data, dev, true, domid);
535-
return 0;
548+
return mtk_iommu_config(data, dev, true, domid);
536549

537550
err_unlock:
538551
mutex_unlock(&data->mutex);
@@ -997,6 +1010,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)
9971010
dev_err(dev, "mm dts parse fail(%d).", ret);
9981011
goto out_runtime_disable;
9991012
}
1013+
} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
1014+
data->plat_data->pericfg_comp_str) {
1015+
infracfg = syscon_regmap_lookup_by_compatible(data->plat_data->pericfg_comp_str);
1016+
if (IS_ERR(infracfg)) {
1017+
ret = PTR_ERR(infracfg);
1018+
goto out_runtime_disable;
1019+
}
1020+
1021+
data->pericfg = infracfg;
10001022
}
10011023

10021024
platform_set_drvdata(pdev, data);

drivers/iommu/mtk_iommu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct mtk_iommu_plat_data {
5555
u32 flags;
5656
u32 inv_sel_reg;
5757

58+
char *pericfg_comp_str;
5859
struct list_head *hw_list;
5960
unsigned int iova_region_nr;
6061
const struct mtk_iommu_iova_region *iova_region;
@@ -80,6 +81,7 @@ struct mtk_iommu_data {
8081
struct device *smicomm_dev;
8182

8283
struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */
84+
struct regmap *pericfg;
8385

8486
struct mutex mutex; /* Protect m4u_group/m4u_dom above */
8587

0 commit comments

Comments
 (0)