diff options
Diffstat (limited to 'drivers/gpu/drm/tegra/gem.c')
-rw-r--r-- | drivers/gpu/drm/tegra/gem.c | 25 |
1 files changed, 8 insertions, 17 deletions
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 1217272a51f2..01e16e146bfe 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c | |||
@@ -189,7 +189,6 @@ static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo) | |||
189 | static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo) | 189 | static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo) |
190 | { | 190 | { |
191 | struct scatterlist *s; | 191 | struct scatterlist *s; |
192 | struct sg_table *sgt; | ||
193 | unsigned int i; | 192 | unsigned int i; |
194 | 193 | ||
195 | bo->pages = drm_gem_get_pages(&bo->gem); | 194 | bo->pages = drm_gem_get_pages(&bo->gem); |
@@ -198,36 +197,28 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo) | |||
198 | 197 | ||
199 | bo->num_pages = bo->gem.size >> PAGE_SHIFT; | 198 | bo->num_pages = bo->gem.size >> PAGE_SHIFT; |
200 | 199 | ||
201 | sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages); | 200 | bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages); |
202 | if (IS_ERR(sgt)) | 201 | if (IS_ERR(bo->sgt)) |
203 | goto put_pages; | 202 | goto put_pages; |
204 | 203 | ||
205 | /* | 204 | /* |
206 | * Fake up the SG table so that dma_map_sg() can be used to flush the | 205 | * Fake up the SG table so that dma_sync_sg_for_device() can be used |
207 | * pages associated with it. Note that this relies on the fact that | 206 | * to flush the pages associated with it. |
208 | * the DMA API doesn't hook into IOMMU on Tegra, therefore mapping is | ||
209 | * only cache maintenance. | ||
210 | * | 207 | * |
211 | * TODO: Replace this by drm_clflash_sg() once it can be implemented | 208 | * TODO: Replace this by drm_clflash_sg() once it can be implemented |
212 | * without relying on symbols that are not exported. | 209 | * without relying on symbols that are not exported. |
213 | */ | 210 | */ |
214 | for_each_sg(sgt->sgl, s, sgt->nents, i) | 211 | for_each_sg(bo->sgt->sgl, s, bo->sgt->nents, i) |
215 | sg_dma_address(s) = sg_phys(s); | 212 | sg_dma_address(s) = sg_phys(s); |
216 | 213 | ||
217 | if (dma_map_sg(drm->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE) == 0) | 214 | dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents, |
218 | goto release_sgt; | 215 | DMA_TO_DEVICE); |
219 | |||
220 | bo->sgt = sgt; | ||
221 | 216 | ||
222 | return 0; | 217 | return 0; |
223 | 218 | ||
224 | release_sgt: | ||
225 | sg_free_table(sgt); | ||
226 | kfree(sgt); | ||
227 | sgt = ERR_PTR(-ENOMEM); | ||
228 | put_pages: | 219 | put_pages: |
229 | drm_gem_put_pages(&bo->gem, bo->pages, false, false); | 220 | drm_gem_put_pages(&bo->gem, bo->pages, false, false); |
230 | return PTR_ERR(sgt); | 221 | return PTR_ERR(bo->sgt); |
231 | } | 222 | } |
232 | 223 | ||
233 | static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo) | 224 | static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo) |