Skip to content

Commit e762907

Browse files
YongWu-HFjoergroedel
authored andcommitted
iommu/mediatek: Add PCIe support
Currently the code for of_iommu_configure_dev_id is like this: static int of_iommu_configure_dev_id(struct device_node *master_np, struct device *dev, const u32 *id) { struct of_phandle_args iommu_spec = { .args_count = 1 }; err = of_map_id(master_np, *id, "iommu-map", "iommu-map-mask", &iommu_spec.np, iommu_spec.args); ... } It supports only one id output. BUT our PCIe HW has two ID(one is for writing, the other is for reading). I'm not sure if we should change of_map_id to support output MAX_PHANDLE_ARGS. Here add the solution in ourselve drivers. If it's pcie case, enable one more bit. Not all infra iommu support PCIe, thus add a PCIe support flag here. 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-23-yong.wu@mediatek.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent f9b8c9b commit e762907

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

drivers/iommu/mtk_iommu.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/of_address.h>
2121
#include <linux/of_irq.h>
2222
#include <linux/of_platform.h>
23+
#include <linux/pci.h>
2324
#include <linux/platform_device.h>
2425
#include <linux/pm_runtime.h>
2526
#include <linux/regmap.h>
@@ -134,6 +135,7 @@
134135
#define MTK_IOMMU_TYPE_MASK (0x3 << 13)
135136
/* PM and clock always on. e.g. infra iommu */
136137
#define PM_CLK_AO BIT(15)
138+
#define IFA_IOMMU_PCIE_SUPPORT BIT(16)
137139

138140
#define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask) \
139141
((((pdata)->flags) & (mask)) == (_x))
@@ -420,8 +422,11 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
420422
larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
421423
} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) {
422424
peri_mmuen_msk = BIT(portid);
423-
peri_mmuen = enable ? peri_mmuen_msk : 0;
425+
/* PCI dev has only one output id, enable the next writing bit for PCIe */
426+
if (dev_is_pci(dev))
427+
peri_mmuen_msk |= BIT(portid + 1);
424428

429+
peri_mmuen = enable ? peri_mmuen_msk : 0;
425430
ret = regmap_update_bits(data->pericfg, PERICFG_IOMMU_1,
426431
peri_mmuen_msk, peri_mmuen);
427432
if (ret)
@@ -1054,6 +1059,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)
10541059
ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
10551060
if (ret)
10561061
goto out_bus_set_null;
1062+
} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
1063+
MTK_IOMMU_HAS_FLAG(data->plat_data, IFA_IOMMU_PCIE_SUPPORT)) {
1064+
#ifdef CONFIG_PCI
1065+
if (!iommu_present(&pci_bus_type)) {
1066+
ret = bus_set_iommu(&pci_bus_type, &mtk_iommu_ops);
1067+
if (ret) /* PCIe fail don't affect platform_bus. */
1068+
goto out_list_del;
1069+
}
1070+
#endif
10571071
}
10581072
return ret;
10591073

@@ -1084,6 +1098,11 @@ static int mtk_iommu_remove(struct platform_device *pdev)
10841098
if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
10851099
device_link_remove(data->smicomm_dev, &pdev->dev);
10861100
component_master_del(&pdev->dev, &mtk_iommu_com_ops);
1101+
} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
1102+
MTK_IOMMU_HAS_FLAG(data->plat_data, IFA_IOMMU_PCIE_SUPPORT)) {
1103+
#ifdef CONFIG_PCI
1104+
bus_set_iommu(&pci_bus_type, NULL);
1105+
#endif
10871106
}
10881107
pm_runtime_disable(&pdev->dev);
10891108
devm_free_irq(&pdev->dev, data->irq, data);

0 commit comments

Comments
 (0)