summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tegra/gem.c
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2019-10-28 13:37:13 +0100
committerThierry Reding <treding@nvidia.com>2019-10-29 15:04:35 +0100
commitaf1cbfb9bf0fe079ca328231451fd4db8b3eafec (patch)
tree136ba6066a4ed6b84181e5850e76dc751aeda168 /drivers/gpu/drm/tegra/gem.c
parentb78e70c04c149299bd210759d7c7af7c86b89ca8 (diff)
gpu: host1x: Support DMA mapping of buffers
If host1x_bo_pin() returns an SG table, create a DMA mapping for the buffer. For buffers that the host1x client has already mapped itself, host1x_bo_pin() returns NULL and the existing DMA address is used. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra/gem.c')
-rw-r--r--drivers/gpu/drm/tegra/gem.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 564ef60f67c2..746dae32c484 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -34,9 +34,19 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
struct sg_table *sgt;
int err;
- if (phys)
+ /*
+ * If we've manually mapped the buffer object through the IOMMU, make
+ * sure to return the IOVA address of our mapping.
+ */
+ if (phys && obj->mm) {
*phys = obj->iova;
+ return NULL;
+ }
+ /*
+ * If we don't have a mapping for this buffer yet, return an SG table
+ * so that host1x can do the mapping for us via the DMA API.
+ */
sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
if (!sgt)
return ERR_PTR(-ENOMEM);
@@ -62,8 +72,10 @@ free:
static void tegra_bo_unpin(struct device *dev, struct sg_table *sgt)
{
- sg_free_table(sgt);
- kfree(sgt);
+ if (sgt) {
+ sg_free_table(sgt);
+ kfree(sgt);
+ }
}
static void *tegra_bo_mmap(struct host1x_bo *bo)