[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