summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c72
1 files changed, 51 insertions, 21 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 81fa38bb..08fbfb80 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -2183,6 +2183,51 @@ err_kfree:
2183#endif 2183#endif
2184} 2184}
2185 2185
2186static u64 gk20a_mm_get_align(struct gk20a *g, struct scatterlist *sgl,
2187 enum gk20a_aperture aperture)
2188{
2189 u64 align = 0, chunk_align = 0;
2190 u64 buf_addr;
2191
2192 if (aperture == APERTURE_VIDMEM) {
2193 struct gk20a_page_alloc *alloc = (struct gk20a_page_alloc *)
2194 sg_dma_address(sgl);
2195 struct page_alloc_chunk *chunk = NULL;
2196
2197 list_for_each_entry(chunk, &alloc->alloc_chunks, list_entry) {
2198 chunk_align = 1ULL << __ffs(chunk->base | chunk->length);
2199
2200 if (align)
2201 align = min(align, chunk_align);
2202 else
2203 align = chunk_align;
2204 }
2205
2206 return align;
2207 }
2208
2209 buf_addr = (u64)sg_dma_address(sgl);
2210
2211 if (g->mm.bypass_smmu || buf_addr == DMA_ERROR_CODE || !buf_addr) {
2212 while (sgl) {
2213 buf_addr = (u64)sg_phys(sgl);
2214 chunk_align = 1ULL << __ffs(buf_addr | (u64)sgl->length);
2215
2216 if (align)
2217 align = min(align, chunk_align);
2218 else
2219 align = chunk_align;
2220 sgl = sg_next(sgl);
2221 }
2222
2223 return align;
2224 }
2225
2226 align = 1ULL << __ffs(buf_addr);
2227
2228 return align;
2229}
2230
2186u64 gk20a_vm_map(struct vm_gk20a *vm, 2231u64 gk20a_vm_map(struct vm_gk20a *vm,
2187 struct dma_buf *dmabuf, 2232 struct dma_buf *dmabuf,
2188 u64 offset_align, 2233 u64 offset_align,
@@ -2207,7 +2252,6 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
2207 struct gk20a_comptags comptags; 2252 struct gk20a_comptags comptags;
2208 bool clear_ctags = false; 2253 bool clear_ctags = false;
2209 struct scatterlist *sgl; 2254 struct scatterlist *sgl;
2210 u64 buf_addr;
2211 u64 ctag_map_win_size = 0; 2255 u64 ctag_map_win_size = 0;
2212 u32 ctag_map_win_ctagline = 0; 2256 u32 ctag_map_win_ctagline = 0;
2213 struct vm_reserved_va_node *va_node = NULL; 2257 struct vm_reserved_va_node *va_node = NULL;
@@ -2257,22 +2301,14 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
2257 bfr.kind_v = kind; 2301 bfr.kind_v = kind;
2258 bfr.size = dmabuf->size; 2302 bfr.size = dmabuf->size;
2259 sgl = bfr.sgt->sgl; 2303 sgl = bfr.sgt->sgl;
2260 buf_addr = (u64)sg_dma_address(bfr.sgt->sgl);
2261 if (g->mm.bypass_smmu || buf_addr == DMA_ERROR_CODE || !buf_addr) {
2262 while (sgl) {
2263 u64 align;
2264 2304
2265 buf_addr = (u64)sg_phys(sgl); 2305 aperture = gk20a_dmabuf_aperture(g, dmabuf);
2306 if (aperture == APERTURE_INVALID) {
2307 err = -EINVAL;
2308 goto clean_up;
2309 }
2266 2310
2267 align = 1ULL << __ffs(buf_addr | (u64)sgl->length); 2311 bfr.align = gk20a_mm_get_align(g, sgl, aperture);
2268 if (bfr.align)
2269 bfr.align = min_t(u64, align, bfr.align);
2270 else
2271 bfr.align = align;
2272 sgl = sg_next(sgl);
2273 }
2274 } else
2275 bfr.align = 1ULL << __ffs(buf_addr);
2276 2312
2277 bfr.pgsz_idx = -1; 2313 bfr.pgsz_idx = -1;
2278 mapping_size = mapping_size ? mapping_size : bfr.size; 2314 mapping_size = mapping_size ? mapping_size : bfr.size;
@@ -2388,12 +2424,6 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
2388 ctag_offset += buffer_offset >> 2424 ctag_offset += buffer_offset >>
2389 ilog2(g->ops.fb.compression_page_size(g)); 2425 ilog2(g->ops.fb.compression_page_size(g));
2390 2426
2391 aperture = gk20a_dmabuf_aperture(g, dmabuf);
2392 if (aperture == APERTURE_INVALID) {
2393 err = -EINVAL;
2394 goto clean_up;
2395 }
2396
2397 /* update gmmu ptes */ 2427 /* update gmmu ptes */
2398 map_offset = g->ops.mm.gmmu_map(vm, map_offset, 2428 map_offset = g->ops.mm.gmmu_map(vm, map_offset,
2399 bfr.sgt, 2429 bfr.sgt,