Skip to content

Commit

Permalink
drm/tegra: gem: Map pages via the DMA API
Browse files Browse the repository at this point in the history
When allocating pages, map them with the DMA API in order to invalidate
caches. This is the correct usage of the API and works just as well as
faking up the SG table and using the dma_sync_sg_for_device() function.

Signed-off-by: Thierry Reding <treding@nvidia.com>
  • Loading branch information
Thierry Reding committed Mar 16, 2018
1 parent 0281c41 commit bd43c9f
Showing 1 changed file with 16 additions and 16 deletions.
32 changes: 16 additions & 16 deletions drivers/gpu/drm/tegra/gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm,
static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
{
if (bo->pages) {
dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
DMA_BIDIRECTIONAL);
drm_gem_put_pages(&bo->gem, bo->pages, true, true);
sg_free_table(bo->sgt);
kfree(bo->sgt);
Expand All @@ -213,8 +215,7 @@ static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)

static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
{
struct scatterlist *s;
unsigned int i;
int err;

bo->pages = drm_gem_get_pages(&bo->gem);
if (IS_ERR(bo->pages))
Expand All @@ -223,27 +224,26 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
bo->num_pages = bo->gem.size >> PAGE_SHIFT;

bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages);
if (IS_ERR(bo->sgt))
if (IS_ERR(bo->sgt)) {
err = PTR_ERR(bo->sgt);
goto put_pages;
}

/*
* Fake up the SG table so that dma_sync_sg_for_device() can be used
* to flush the pages associated with it.
*
* TODO: Replace this by drm_clflash_sg() once it can be implemented
* without relying on symbols that are not exported.
*/
for_each_sg(bo->sgt->sgl, s, bo->sgt->nents, i)
sg_dma_address(s) = sg_phys(s);

dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents,
DMA_TO_DEVICE);
err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
DMA_BIDIRECTIONAL);
if (err == 0) {
err = -EFAULT;
goto free_sgt;
}

return 0;

free_sgt:
sg_free_table(bo->sgt);
kfree(bo->sgt);
put_pages:
drm_gem_put_pages(&bo->gem, bo->pages, false, false);
return PTR_ERR(bo->sgt);
return err;
}

static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo)
Expand Down

0 comments on commit bd43c9f

Please sign in to comment.