diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b')
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/mm_gp10b.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c index 1608b176..3633e9d9 100644 --- a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c | |||
@@ -148,7 +148,9 @@ u32 *pde3_from_index(struct gk20a_mm_entry *entry, u32 i) | |||
148 | static int update_gmmu_pde3_locked(struct vm_gk20a *vm, | 148 | static int update_gmmu_pde3_locked(struct vm_gk20a *vm, |
149 | struct gk20a_mm_entry *parent, | 149 | struct gk20a_mm_entry *parent, |
150 | u32 i, u32 gmmu_pgsz_idx, | 150 | u32 i, u32 gmmu_pgsz_idx, |
151 | u64 iova, | 151 | struct scatterlist **sgl, |
152 | u64 *offset, | ||
153 | u64 *iova, | ||
152 | u32 kind_v, u32 *ctag, | 154 | u32 kind_v, u32 *ctag, |
153 | bool cacheable, bool unmapped_pte, | 155 | bool cacheable, bool unmapped_pte, |
154 | int rw_flag, bool sparse, u32 flags) | 156 | int rw_flag, bool sparse, u32 flags) |
@@ -188,7 +190,9 @@ u32 *pde0_from_index(struct gk20a_mm_entry *entry, u32 i) | |||
188 | static int update_gmmu_pde0_locked(struct vm_gk20a *vm, | 190 | static int update_gmmu_pde0_locked(struct vm_gk20a *vm, |
189 | struct gk20a_mm_entry *pte, | 191 | struct gk20a_mm_entry *pte, |
190 | u32 i, u32 gmmu_pgsz_idx, | 192 | u32 i, u32 gmmu_pgsz_idx, |
191 | u64 iova, | 193 | struct scatterlist **sgl, |
194 | u64 *offset, | ||
195 | u64 *iova, | ||
192 | u32 kind_v, u32 *ctag, | 196 | u32 kind_v, u32 *ctag, |
193 | bool cacheable, bool unmapped_pte, | 197 | bool cacheable, bool unmapped_pte, |
194 | int rw_flag, bool sparse, u32 flags) | 198 | int rw_flag, bool sparse, u32 flags) |
@@ -241,7 +245,9 @@ static int update_gmmu_pde0_locked(struct vm_gk20a *vm, | |||
241 | static int update_gmmu_pte_locked(struct vm_gk20a *vm, | 245 | static int update_gmmu_pte_locked(struct vm_gk20a *vm, |
242 | struct gk20a_mm_entry *pte, | 246 | struct gk20a_mm_entry *pte, |
243 | u32 i, u32 gmmu_pgsz_idx, | 247 | u32 i, u32 gmmu_pgsz_idx, |
244 | u64 iova, | 248 | struct scatterlist **sgl, |
249 | u64 *offset, | ||
250 | u64 *iova, | ||
245 | u32 kind_v, u32 *ctag, | 251 | u32 kind_v, u32 *ctag, |
246 | bool cacheable, bool unmapped_pte, | 252 | bool cacheable, bool unmapped_pte, |
247 | int rw_flag, bool sparse, u32 flags) | 253 | int rw_flag, bool sparse, u32 flags) |
@@ -251,23 +257,31 @@ static int update_gmmu_pte_locked(struct vm_gk20a *vm, | |||
251 | 257 | ||
252 | gk20a_dbg_fn(""); | 258 | gk20a_dbg_fn(""); |
253 | 259 | ||
254 | if (iova) { | 260 | if (*iova) { |
255 | pte_w[0] = gmmu_new_pte_valid_true_f() | | 261 | if (unmapped_pte) |
256 | gmmu_new_pte_address_sys_f(iova | 262 | pte_w[0] = gmmu_new_pte_valid_false_f() | |
257 | >> gmmu_new_pte_address_shift_v()); | 263 | gmmu_new_pte_address_sys_f(*iova |
264 | >> gmmu_new_pte_address_shift_v()); | ||
265 | else | ||
266 | pte_w[0] = gmmu_new_pte_valid_true_f() | | ||
267 | gmmu_new_pte_address_sys_f(*iova | ||
268 | >> gmmu_new_pte_address_shift_v()); | ||
269 | |||
258 | pte_w[1] = gmmu_new_pte_aperture_video_memory_f() | | 270 | pte_w[1] = gmmu_new_pte_aperture_video_memory_f() | |
259 | gmmu_new_pte_kind_f(kind_v) | | 271 | gmmu_new_pte_kind_f(kind_v) | |
260 | gmmu_new_pte_comptagline_f(*ctag / SZ_128K); | 272 | gmmu_new_pte_comptagline_f(*ctag / SZ_128K); |
261 | 273 | ||
262 | if (rw_flag == gk20a_mem_flag_read_only) | 274 | if (rw_flag == gk20a_mem_flag_read_only) |
263 | pte_w[0] |= gmmu_new_pte_read_only_true_f(); | 275 | pte_w[0] |= gmmu_new_pte_read_only_true_f(); |
264 | if (!cacheable) | 276 | if (unmapped_pte && !cacheable) |
277 | pte_w[0] |= gmmu_new_pte_read_only_true_f(); | ||
278 | else if (!cacheable) | ||
265 | pte_w[1] |= gmmu_new_pte_vol_true_f(); | 279 | pte_w[1] |= gmmu_new_pte_vol_true_f(); |
266 | 280 | ||
267 | gk20a_dbg(gpu_dbg_pte, "pte=%d iova=0x%llx kind=%d" | 281 | gk20a_dbg(gpu_dbg_pte, "pte=%d iova=0x%llx kind=%d" |
268 | " ctag=%d vol=%d" | 282 | " ctag=%d vol=%d" |
269 | " [0x%08x, 0x%08x]", | 283 | " [0x%08x, 0x%08x]", |
270 | i, iova, | 284 | i, *iova, |
271 | kind_v, *ctag, !cacheable, | 285 | kind_v, *ctag, !cacheable, |
272 | pte_w[1], pte_w[0]); | 286 | pte_w[1], pte_w[0]); |
273 | 287 | ||
@@ -283,6 +297,23 @@ static int update_gmmu_pte_locked(struct vm_gk20a *vm, | |||
283 | gk20a_mem_wr32(pte->cpu_va + i*8, 0, pte_w[0]); | 297 | gk20a_mem_wr32(pte->cpu_va + i*8, 0, pte_w[0]); |
284 | gk20a_mem_wr32(pte->cpu_va + i*8, 1, pte_w[1]); | 298 | gk20a_mem_wr32(pte->cpu_va + i*8, 1, pte_w[1]); |
285 | 299 | ||
300 | if (*iova) { | ||
301 | *iova += page_size; | ||
302 | *offset += page_size; | ||
303 | if (*sgl && *offset + page_size > (*sgl)->length) { | ||
304 | u64 new_iova; | ||
305 | *sgl = sg_next(*sgl); | ||
306 | if (*sgl) { | ||
307 | new_iova = sg_phys(*sgl); | ||
308 | gk20a_dbg(gpu_dbg_pte, "chunk address %llx, size %d", | ||
309 | new_iova, (*sgl)->length); | ||
310 | if (new_iova) { | ||
311 | *offset = 0; | ||
312 | *iova = new_iova; | ||
313 | } | ||
314 | } | ||
315 | } | ||
316 | } | ||
286 | gk20a_dbg_fn("done"); | 317 | gk20a_dbg_fn("done"); |
287 | return 0; | 318 | return 0; |
288 | } | 319 | } |