Current Tegra code taking advantage of the IOMMU assumes a hardcoded value for the IOMMU bit. Make it a platform property instead for flexibility.
Signed-off-by: Alexandre Courbot <[email protected]> --- drm/nouveau/include/nvkm/core/tegra.h | 3 +++ drm/nouveau/nouveau_platform.c | 14 ++++++++++++-- drm/nouveau/nouveau_platform.h | 10 ++++++++++ drm/nouveau/nvkm/engine/device/tegra.c | 9 ++++++++- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/drm/nouveau/include/nvkm/core/tegra.h b/drm/nouveau/include/nvkm/core/tegra.h index 5aa2480da25f..3e354edbc580 100644 --- a/drm/nouveau/include/nvkm/core/tegra.h +++ b/drm/nouveau/include/nvkm/core/tegra.h @@ -3,10 +3,13 @@ #include <core/device.h> #include <core/mm.h> +#include "nouveau_platform.h" + struct nvkm_device_tegra { struct nvkm_device device; struct platform_device *pdev; int irq; + const struct nouveau_platform_data *pdata; struct reset_control *rst; struct clk *clk; diff --git a/drm/nouveau/nouveau_platform.c b/drm/nouveau/nouveau_platform.c index 3eb665453165..f1bf2983b993 100644 --- a/drm/nouveau/nouveau_platform.c +++ b/drm/nouveau/nouveau_platform.c @@ -48,9 +48,19 @@ static int nouveau_platform_remove(struct platform_device *pdev) } #if IS_ENABLED(CONFIG_OF) +static const struct nouveau_platform_data gk20a_platform_data = { + .iommu_bit = 34, +}; + static const struct of_device_id nouveau_platform_match[] = { - { .compatible = "nvidia,gk20a" }, - { .compatible = "nvidia,gm20b" }, + { + .compatible = "nvidia,gk20a", + .data = &gk20a_platform_data, + }, + { + .compatible = "nvidia,gm20b", + .data = &gk20a_platform_data, + }, { } }; diff --git a/drm/nouveau/nouveau_platform.h b/drm/nouveau/nouveau_platform.h index f41056d0f5f4..fbce6a4ceab9 100644 --- a/drm/nouveau/nouveau_platform.h +++ b/drm/nouveau/nouveau_platform.h @@ -23,5 +23,15 @@ #define __NOUVEAU_PLATFORM_H__ #include "nouveau_drm.h" +struct nouveau_platform_data +{ + /* + * If an IOMMU is used, indicates which address bit will trigger a + * IOMMU translation when set (when this bit is not set, IOMMU is + * bypassed). A value of 0 means an IOMMU is never used. + */ + u8 iommu_bit; +}; + extern struct platform_driver nouveau_platform_driver; #endif diff --git a/drm/nouveau/nvkm/engine/device/tegra.c b/drm/nouveau/nvkm/engine/device/tegra.c index da57c8a60608..8ec717f20808 100644 --- a/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drm/nouveau/nvkm/engine/device/tegra.c @@ -23,6 +23,8 @@ #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER #include "priv.h" +#include <linux/of_device.h> + static int nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) { @@ -85,6 +87,9 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) unsigned long pgsize_bitmap; int ret; + if (!tdev->pdata->iommu_bit) + return; + mutex_init(&tdev->iommu.mutex); if (iommu_present(&platform_bus_type)) { @@ -114,7 +119,8 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) goto free_domain; ret = nvkm_mm_init(&tdev->iommu.mm, 0, - (1ULL << 40) >> tdev->iommu.pgshift, 1); + (1ULL << tdev->pdata->iommu_bit) >> + tdev->iommu.pgshift, 1); if (ret) goto detach_device; } @@ -250,6 +256,7 @@ nvkm_device_tegra_new(struct platform_device *pdev, *pdevice = &tdev->device; tdev->pdev = pdev; tdev->irq = -1; + tdev->pdata = of_device_get_match_data(&pdev->dev); tdev->vdd = devm_regulator_get(&pdev->dev, "vdd"); if (IS_ERR(tdev->vdd)) -- 2.5.1 _______________________________________________ Nouveau mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/nouveau
