drm/nouveau/platform: allow to specify the IOMMU bit
Current Tegra code taking advantage of the IOMMU assumes a hardcoded value for the IOMMU bit. Make it a platform property instead for flexibility. v2 (Ben Skeggs): remove nvkm dependence on drm structures Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
69c4938249
commit
e396ecd178
|
@ -27,6 +27,7 @@
|
||||||
#include <linux/agp_backend.h>
|
#include <linux/agp_backend.h>
|
||||||
#include <linux/reset.h>
|
#include <linux/reset.h>
|
||||||
#include <linux/iommu.h>
|
#include <linux/iommu.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
|
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <core/mm.h>
|
#include <core/mm.h>
|
||||||
|
|
||||||
struct nvkm_device_tegra {
|
struct nvkm_device_tegra {
|
||||||
|
const struct nvkm_device_tegra_func *func;
|
||||||
struct nvkm_device device;
|
struct nvkm_device device;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
int irq;
|
int irq;
|
||||||
|
@ -28,7 +29,17 @@ struct nvkm_device_tegra {
|
||||||
int gpu_speedo;
|
int gpu_speedo;
|
||||||
};
|
};
|
||||||
|
|
||||||
int nvkm_device_tegra_new(struct platform_device *,
|
struct nvkm_device_tegra_func {
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *,
|
||||||
|
struct platform_device *,
|
||||||
const char *cfg, const char *dbg,
|
const char *cfg, const char *dbg,
|
||||||
bool detect, bool mmio, u64 subdev_mask,
|
bool detect, bool mmio, u64 subdev_mask,
|
||||||
struct nvkm_device **);
|
struct nvkm_device **);
|
||||||
|
|
|
@ -1028,13 +1028,14 @@ nouveau_drm_pci_driver = {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct drm_device *
|
struct drm_device *
|
||||||
nouveau_platform_device_create(struct platform_device *pdev,
|
nouveau_platform_device_create(const struct nvkm_device_tegra_func *func,
|
||||||
|
struct platform_device *pdev,
|
||||||
struct nvkm_device **pdevice)
|
struct nvkm_device **pdevice)
|
||||||
{
|
{
|
||||||
struct drm_device *drm;
|
struct drm_device *drm;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = nvkm_device_tegra_new(pdev, nouveau_config, nouveau_debug,
|
err = nvkm_device_tegra_new(func, pdev, nouveau_config, nouveau_debug,
|
||||||
true, true, ~0ULL, pdevice);
|
true, true, ~0ULL, pdevice);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
|
@ -178,8 +178,11 @@ nouveau_drm(struct drm_device *dev)
|
||||||
int nouveau_pmops_suspend(struct device *);
|
int nouveau_pmops_suspend(struct device *);
|
||||||
int nouveau_pmops_resume(struct device *);
|
int nouveau_pmops_resume(struct device *);
|
||||||
|
|
||||||
|
#include <nvkm/core/tegra.h>
|
||||||
|
|
||||||
struct drm_device *
|
struct drm_device *
|
||||||
nouveau_platform_device_create(struct platform_device *, struct nvkm_device **);
|
nouveau_platform_device_create(const struct nvkm_device_tegra_func *,
|
||||||
|
struct platform_device *, struct nvkm_device **);
|
||||||
void nouveau_drm_device_remove(struct drm_device *dev);
|
void nouveau_drm_device_remove(struct drm_device *dev);
|
||||||
|
|
||||||
#define NV_PRINTK(l,c,f,a...) do { \
|
#define NV_PRINTK(l,c,f,a...) do { \
|
||||||
|
|
|
@ -23,11 +23,14 @@
|
||||||
|
|
||||||
static int nouveau_platform_probe(struct platform_device *pdev)
|
static int nouveau_platform_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
const struct nvkm_device_tegra_func *func;
|
||||||
struct nvkm_device *device;
|
struct nvkm_device *device;
|
||||||
struct drm_device *drm;
|
struct drm_device *drm;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
drm = nouveau_platform_device_create(pdev, &device);
|
func = of_device_get_match_data(&pdev->dev);
|
||||||
|
|
||||||
|
drm = nouveau_platform_device_create(func, pdev, &device);
|
||||||
if (IS_ERR(drm))
|
if (IS_ERR(drm))
|
||||||
return PTR_ERR(drm);
|
return PTR_ERR(drm);
|
||||||
|
|
||||||
|
@ -48,9 +51,19 @@ static int nouveau_platform_remove(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_OF)
|
#if IS_ENABLED(CONFIG_OF)
|
||||||
|
static const struct nvkm_device_tegra_func gk20a_platform_data = {
|
||||||
|
.iommu_bit = 34,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id nouveau_platform_match[] = {
|
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,
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,9 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
|
||||||
unsigned long pgsize_bitmap;
|
unsigned long pgsize_bitmap;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!tdev->func->iommu_bit)
|
||||||
|
return;
|
||||||
|
|
||||||
mutex_init(&tdev->iommu.mutex);
|
mutex_init(&tdev->iommu.mutex);
|
||||||
|
|
||||||
if (iommu_present(&platform_bus_type)) {
|
if (iommu_present(&platform_bus_type)) {
|
||||||
|
@ -114,7 +117,8 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
|
||||||
goto free_domain;
|
goto free_domain;
|
||||||
|
|
||||||
ret = nvkm_mm_init(&tdev->iommu.mm, 0,
|
ret = nvkm_mm_init(&tdev->iommu.mm, 0,
|
||||||
(1ULL << 40) >> tdev->iommu.pgshift, 1);
|
(1ULL << tdev->func->iommu_bit) >>
|
||||||
|
tdev->iommu.pgshift, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto detach_device;
|
goto detach_device;
|
||||||
}
|
}
|
||||||
|
@ -237,7 +241,8 @@ nvkm_device_tegra_func = {
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
nvkm_device_tegra_new(struct platform_device *pdev,
|
nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
|
||||||
|
struct platform_device *pdev,
|
||||||
const char *cfg, const char *dbg,
|
const char *cfg, const char *dbg,
|
||||||
bool detect, bool mmio, u64 subdev_mask,
|
bool detect, bool mmio, u64 subdev_mask,
|
||||||
struct nvkm_device **pdevice)
|
struct nvkm_device **pdevice)
|
||||||
|
@ -248,6 +253,7 @@ nvkm_device_tegra_new(struct platform_device *pdev,
|
||||||
if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL)))
|
if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL)))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
*pdevice = &tdev->device;
|
*pdevice = &tdev->device;
|
||||||
|
tdev->func = func;
|
||||||
tdev->pdev = pdev;
|
tdev->pdev = pdev;
|
||||||
tdev->irq = -1;
|
tdev->irq = -1;
|
||||||
|
|
||||||
|
@ -285,7 +291,8 @@ nvkm_device_tegra_new(struct platform_device *pdev,
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
nvkm_device_tegra_new(struct platform_device *pdev,
|
nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
|
||||||
|
struct platform_device *pdev,
|
||||||
const char *cfg, const char *dbg,
|
const char *cfg, const char *dbg,
|
||||||
bool detect, bool mmio, u64 subdev_mask,
|
bool detect, bool mmio, u64 subdev_mask,
|
||||||
struct nvkm_device **pdevice)
|
struct nvkm_device **pdevice)
|
||||||
|
|
Loading…
Reference in New Issue