diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/nvgpu_mem.c | 58 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/mm/gmmu.c | 6 |
2 files changed, 61 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c b/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c index 34fd6626..e4991d0d 100644 --- a/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c +++ b/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <nvgpu/dma.h> | 17 | #include <nvgpu/dma.h> |
18 | #include <nvgpu/gmmu.h> | ||
18 | #include <nvgpu/nvgpu_mem.h> | 19 | #include <nvgpu/nvgpu_mem.h> |
19 | #include <nvgpu/page_allocator.h> | 20 | #include <nvgpu/page_allocator.h> |
20 | #include <nvgpu/log.h> | 21 | #include <nvgpu/log.h> |
@@ -23,6 +24,8 @@ | |||
23 | 24 | ||
24 | #include <nvgpu/linux/dma.h> | 25 | #include <nvgpu/linux/dma.h> |
25 | 26 | ||
27 | #include "os_linux.h" | ||
28 | |||
26 | #include "gk20a/gk20a.h" | 29 | #include "gk20a/gk20a.h" |
27 | #include "gk20a/mm_gk20a.h" | 30 | #include "gk20a/mm_gk20a.h" |
28 | 31 | ||
@@ -247,6 +250,61 @@ void nvgpu_memset(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, | |||
247 | } | 250 | } |
248 | 251 | ||
249 | /* | 252 | /* |
253 | * Obtain a SYSMEM address from a Linux SGL. This should eventually go away | ||
254 | * and/or become private to this file once all bad usages of Linux SGLs are | ||
255 | * cleaned up in the driver. | ||
256 | */ | ||
257 | u64 nvgpu_mem_get_addr_sgl(struct gk20a *g, struct scatterlist *sgl) | ||
258 | { | ||
259 | struct nvgpu_os_linux *l = container_of(g, struct nvgpu_os_linux, g); | ||
260 | |||
261 | if (!device_is_iommuable(l->dev)) | ||
262 | return g->ops.mm.gpu_phys_addr(g, NULL, sg_phys(sgl)); | ||
263 | |||
264 | if (sg_dma_address(sgl) == 0) | ||
265 | return g->ops.mm.gpu_phys_addr(g, NULL, sg_phys(sgl)); | ||
266 | |||
267 | if (sg_dma_address(sgl) == DMA_ERROR_CODE) | ||
268 | return 0; | ||
269 | |||
270 | return gk20a_mm_smmu_vaddr_translate(g, sg_dma_address(sgl)); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * Obtain the address the GPU should use from the %mem assuming this is a SYSMEM | ||
275 | * allocation. | ||
276 | */ | ||
277 | static u64 nvgpu_mem_get_addr_sysmem(struct gk20a *g, struct nvgpu_mem *mem) | ||
278 | { | ||
279 | return nvgpu_mem_get_addr_sgl(g, mem->priv.sgt->sgl); | ||
280 | } | ||
281 | |||
282 | /* | ||
283 | * Return the base address of %mem. Handles whether this is a VIDMEM or SYSMEM | ||
284 | * allocation. | ||
285 | * | ||
286 | * %attrs can be NULL. If it is not NULL then it may be inspected to determine | ||
287 | * if the address needs to be modified before writing into a PTE. | ||
288 | */ | ||
289 | u64 nvgpu_mem_get_addr(struct gk20a *g, struct nvgpu_mem *mem) | ||
290 | { | ||
291 | struct nvgpu_page_alloc *alloc; | ||
292 | |||
293 | if (mem->aperture == APERTURE_SYSMEM) | ||
294 | return nvgpu_mem_get_addr_sysmem(g, mem); | ||
295 | |||
296 | /* | ||
297 | * Otherwise get the vidmem address. | ||
298 | */ | ||
299 | alloc = get_vidmem_page_alloc(mem->priv.sgt->sgl); | ||
300 | |||
301 | /* This API should not be used with > 1 chunks */ | ||
302 | WARN_ON(alloc->nr_chunks != 1); | ||
303 | |||
304 | return alloc->base; | ||
305 | } | ||
306 | |||
307 | /* | ||
250 | * Be careful how you use this! You are responsible for correctly freeing this | 308 | * Be careful how you use this! You are responsible for correctly freeing this |
251 | * memory. | 309 | * memory. |
252 | */ | 310 | */ |
diff --git a/drivers/gpu/nvgpu/common/mm/gmmu.c b/drivers/gpu/nvgpu/common/mm/gmmu.c index 1be87c85..30be1b85 100644 --- a/drivers/gpu/nvgpu/common/mm/gmmu.c +++ b/drivers/gpu/nvgpu/common/mm/gmmu.c | |||
@@ -201,7 +201,7 @@ u64 nvgpu_pde_phys_addr(struct gk20a *g, struct nvgpu_gmmu_pd *pd) | |||
201 | if (g->mm.has_physical_mode) | 201 | if (g->mm.has_physical_mode) |
202 | page_addr = sg_phys(pd->mem->priv.sgt->sgl); | 202 | page_addr = sg_phys(pd->mem->priv.sgt->sgl); |
203 | else | 203 | else |
204 | page_addr = nvgpu_mem_get_base_addr(g, pd->mem, 0); | 204 | page_addr = nvgpu_mem_get_addr(g, pd->mem); |
205 | 205 | ||
206 | return page_addr + pd->mem_offs; | 206 | return page_addr + pd->mem_offs; |
207 | } | 207 | } |
@@ -559,7 +559,7 @@ static int __nvgpu_gmmu_update_page_table_sysmem(struct vm_gk20a *vm, | |||
559 | sgl = sgt->sgl; | 559 | sgl = sgt->sgl; |
560 | 560 | ||
561 | if (!g->mm.bypass_smmu) { | 561 | if (!g->mm.bypass_smmu) { |
562 | u64 io_addr = g->ops.mm.get_iova_addr(g, sgl, 0); | 562 | u64 io_addr = nvgpu_mem_get_addr_sgl(g, sgl); |
563 | 563 | ||
564 | io_addr += space_to_skip; | 564 | io_addr += space_to_skip; |
565 | 565 | ||
@@ -670,7 +670,7 @@ static int __nvgpu_gmmu_update_page_table(struct vm_gk20a *vm, | |||
670 | 670 | ||
671 | phys_addr = alloc->base; | 671 | phys_addr = alloc->base; |
672 | } else | 672 | } else |
673 | phys_addr = g->ops.mm.get_iova_addr(g, sgt->sgl, 0); | 673 | phys_addr = nvgpu_mem_get_addr_sgl(g, sgt->sgl); |
674 | } | 674 | } |
675 | 675 | ||
676 | __gmmu_dbg(g, attrs, | 676 | __gmmu_dbg(g, attrs, |