[Nouveau] [PATCH 1/4] platform: allow to specify the IOMMU bit

Alexandre Courbot acourbot at nvidia.com
Fri Sep 4 03:59:31 PDT 2015


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 <acourbot at nvidia.com>
---
 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



More information about the Nouveau mailing list