diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 74 |
1 files changed, 49 insertions, 25 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index b5626035..9fcaebff 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c | |||
@@ -93,23 +93,27 @@ int gk20a_init_mm_setup_hw(struct gk20a *g) | |||
93 | nvgpu_log_fn(g, " "); | 93 | nvgpu_log_fn(g, " "); |
94 | 94 | ||
95 | g->ops.fb.set_mmu_page_size(g); | 95 | g->ops.fb.set_mmu_page_size(g); |
96 | if (g->ops.fb.set_use_full_comp_tag_line) | 96 | if (g->ops.fb.set_use_full_comp_tag_line) { |
97 | mm->use_full_comp_tag_line = | 97 | mm->use_full_comp_tag_line = |
98 | g->ops.fb.set_use_full_comp_tag_line(g); | 98 | g->ops.fb.set_use_full_comp_tag_line(g); |
99 | } | ||
99 | 100 | ||
100 | g->ops.fb.init_hw(g); | 101 | g->ops.fb.init_hw(g); |
101 | 102 | ||
102 | if (g->ops.bus.bar1_bind) | 103 | if (g->ops.bus.bar1_bind) { |
103 | g->ops.bus.bar1_bind(g, &mm->bar1.inst_block); | 104 | g->ops.bus.bar1_bind(g, &mm->bar1.inst_block); |
105 | } | ||
104 | 106 | ||
105 | if (g->ops.bus.bar2_bind) { | 107 | if (g->ops.bus.bar2_bind) { |
106 | err = g->ops.bus.bar2_bind(g, &mm->bar2.inst_block); | 108 | err = g->ops.bus.bar2_bind(g, &mm->bar2.inst_block); |
107 | if (err) | 109 | if (err) { |
108 | return err; | 110 | return err; |
111 | } | ||
109 | } | 112 | } |
110 | 113 | ||
111 | if (gk20a_mm_fb_flush(g) || gk20a_mm_fb_flush(g)) | 114 | if (gk20a_mm_fb_flush(g) || gk20a_mm_fb_flush(g)) { |
112 | return -EBUSY; | 115 | return -EBUSY; |
116 | } | ||
113 | 117 | ||
114 | nvgpu_log_fn(g, "done"); | 118 | nvgpu_log_fn(g, "done"); |
115 | return 0; | 119 | return 0; |
@@ -211,8 +215,9 @@ static void __update_pte(struct vm_gk20a *vm, | |||
211 | 215 | ||
212 | pte_w[0] = pte_valid | addr; | 216 | pte_w[0] = pte_valid | addr; |
213 | 217 | ||
214 | if (attrs->priv) | 218 | if (attrs->priv) { |
215 | pte_w[0] |= gmmu_pte_privilege_true_f(); | 219 | pte_w[0] |= gmmu_pte_privilege_true_f(); |
220 | } | ||
216 | 221 | ||
217 | pte_w[1] = __nvgpu_aperture_mask(g, attrs->aperture, | 222 | pte_w[1] = __nvgpu_aperture_mask(g, attrs->aperture, |
218 | gmmu_pte_aperture_sys_mem_ncoh_f(), | 223 | gmmu_pte_aperture_sys_mem_ncoh_f(), |
@@ -222,9 +227,10 @@ static void __update_pte(struct vm_gk20a *vm, | |||
222 | gmmu_pte_comptagline_f((u32)(attrs->ctag >> ctag_shift)); | 227 | gmmu_pte_comptagline_f((u32)(attrs->ctag >> ctag_shift)); |
223 | 228 | ||
224 | if (attrs->ctag && vm->mm->use_full_comp_tag_line && | 229 | if (attrs->ctag && vm->mm->use_full_comp_tag_line && |
225 | phys_addr & 0x10000) | 230 | phys_addr & 0x10000) { |
226 | pte_w[1] |= gmmu_pte_comptagline_f( | 231 | pte_w[1] |= gmmu_pte_comptagline_f( |
227 | 1 << (gmmu_pte_comptagline_s() - 1)); | 232 | 1 << (gmmu_pte_comptagline_s() - 1)); |
233 | } | ||
228 | 234 | ||
229 | if (attrs->rw_flag == gk20a_mem_flag_read_only) { | 235 | if (attrs->rw_flag == gk20a_mem_flag_read_only) { |
230 | pte_w[0] |= gmmu_pte_read_only_true_f(); | 236 | pte_w[0] |= gmmu_pte_read_only_true_f(); |
@@ -233,11 +239,13 @@ static void __update_pte(struct vm_gk20a *vm, | |||
233 | pte_w[1] |= gmmu_pte_read_disable_true_f(); | 239 | pte_w[1] |= gmmu_pte_read_disable_true_f(); |
234 | } | 240 | } |
235 | 241 | ||
236 | if (!attrs->cacheable) | 242 | if (!attrs->cacheable) { |
237 | pte_w[1] |= gmmu_pte_vol_true_f(); | 243 | pte_w[1] |= gmmu_pte_vol_true_f(); |
244 | } | ||
238 | 245 | ||
239 | if (attrs->ctag) | 246 | if (attrs->ctag) { |
240 | attrs->ctag += page_size; | 247 | attrs->ctag += page_size; |
248 | } | ||
241 | } | 249 | } |
242 | 250 | ||
243 | static void update_gmmu_pte_locked(struct vm_gk20a *vm, | 251 | static void update_gmmu_pte_locked(struct vm_gk20a *vm, |
@@ -254,10 +262,11 @@ static void update_gmmu_pte_locked(struct vm_gk20a *vm, | |||
254 | u32 pte_w[2] = {0, 0}; | 262 | u32 pte_w[2] = {0, 0}; |
255 | int ctag_shift = ilog2(g->ops.fb.compression_page_size(g)); | 263 | int ctag_shift = ilog2(g->ops.fb.compression_page_size(g)); |
256 | 264 | ||
257 | if (phys_addr) | 265 | if (phys_addr) { |
258 | __update_pte(vm, pte_w, phys_addr, attrs); | 266 | __update_pte(vm, pte_w, phys_addr, attrs); |
259 | else if (attrs->sparse) | 267 | } else if (attrs->sparse) { |
260 | __update_pte_sparse(pte_w); | 268 | __update_pte_sparse(pte_w); |
269 | } | ||
261 | 270 | ||
262 | pte_dbg(g, attrs, | 271 | pte_dbg(g, attrs, |
263 | "PTE: i=%-4u size=%-2u offs=%-4u | " | 272 | "PTE: i=%-4u size=%-2u offs=%-4u | " |
@@ -338,8 +347,9 @@ int gk20a_vm_bind_channel(struct vm_gk20a *vm, struct channel_gk20a *ch) | |||
338 | nvgpu_vm_get(vm); | 347 | nvgpu_vm_get(vm); |
339 | ch->vm = vm; | 348 | ch->vm = vm; |
340 | err = channel_gk20a_commit_va(ch); | 349 | err = channel_gk20a_commit_va(ch); |
341 | if (err) | 350 | if (err) { |
342 | ch->vm = NULL; | 351 | ch->vm = NULL; |
352 | } | ||
343 | 353 | ||
344 | nvgpu_log(gk20a_from_vm(vm), gpu_dbg_map, "Binding ch=%d -> VM:%s", | 354 | nvgpu_log(gk20a_from_vm(vm), gpu_dbg_map, "Binding ch=%d -> VM:%s", |
345 | ch->chid, vm->name); | 355 | ch->chid, vm->name); |
@@ -384,8 +394,9 @@ void gk20a_init_inst_block(struct nvgpu_mem *inst_block, struct vm_gk20a *vm, | |||
384 | nvgpu_mem_wr32(g, inst_block, ram_in_adr_limit_hi_w(), | 394 | nvgpu_mem_wr32(g, inst_block, ram_in_adr_limit_hi_w(), |
385 | ram_in_adr_limit_hi_f(u64_hi32(vm->va_limit - 1))); | 395 | ram_in_adr_limit_hi_f(u64_hi32(vm->va_limit - 1))); |
386 | 396 | ||
387 | if (big_page_size && g->ops.mm.set_big_page_size) | 397 | if (big_page_size && g->ops.mm.set_big_page_size) { |
388 | g->ops.mm.set_big_page_size(g, inst_block, big_page_size); | 398 | g->ops.mm.set_big_page_size(g, inst_block, big_page_size); |
399 | } | ||
389 | } | 400 | } |
390 | 401 | ||
391 | int gk20a_alloc_inst_block(struct gk20a *g, struct nvgpu_mem *inst_block) | 402 | int gk20a_alloc_inst_block(struct gk20a *g, struct nvgpu_mem *inst_block) |
@@ -422,8 +433,9 @@ int gk20a_mm_fb_flush(struct gk20a *g) | |||
422 | 433 | ||
423 | retries = 100; | 434 | retries = 100; |
424 | 435 | ||
425 | if (g->ops.mm.get_flush_retries) | 436 | if (g->ops.mm.get_flush_retries) { |
426 | retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_FB); | 437 | retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_FB); |
438 | } | ||
427 | 439 | ||
428 | nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); | 440 | nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); |
429 | 441 | ||
@@ -447,13 +459,15 @@ int gk20a_mm_fb_flush(struct gk20a *g) | |||
447 | flush_fb_flush_pending_busy_v()) { | 459 | flush_fb_flush_pending_busy_v()) { |
448 | nvgpu_log_info(g, "fb_flush 0x%x", data); | 460 | nvgpu_log_info(g, "fb_flush 0x%x", data); |
449 | nvgpu_udelay(5); | 461 | nvgpu_udelay(5); |
450 | } else | 462 | } else { |
451 | break; | 463 | break; |
464 | } | ||
452 | } while (!nvgpu_timeout_expired(&timeout)); | 465 | } while (!nvgpu_timeout_expired(&timeout)); |
453 | 466 | ||
454 | if (nvgpu_timeout_peek_expired(&timeout)) { | 467 | if (nvgpu_timeout_peek_expired(&timeout)) { |
455 | if (g->ops.fb.dump_vpr_wpr_info) | 468 | if (g->ops.fb.dump_vpr_wpr_info) { |
456 | g->ops.fb.dump_vpr_wpr_info(g); | 469 | g->ops.fb.dump_vpr_wpr_info(g); |
470 | } | ||
457 | ret = -EBUSY; | 471 | ret = -EBUSY; |
458 | } | 472 | } |
459 | 473 | ||
@@ -474,8 +488,9 @@ static void gk20a_mm_l2_invalidate_locked(struct gk20a *g) | |||
474 | 488 | ||
475 | trace_gk20a_mm_l2_invalidate(g->name); | 489 | trace_gk20a_mm_l2_invalidate(g->name); |
476 | 490 | ||
477 | if (g->ops.mm.get_flush_retries) | 491 | if (g->ops.mm.get_flush_retries) { |
478 | retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_L2_INV); | 492 | retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_L2_INV); |
493 | } | ||
479 | 494 | ||
480 | nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); | 495 | nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); |
481 | 496 | ||
@@ -494,12 +509,14 @@ static void gk20a_mm_l2_invalidate_locked(struct gk20a *g) | |||
494 | nvgpu_log_info(g, "l2_system_invalidate 0x%x", | 509 | nvgpu_log_info(g, "l2_system_invalidate 0x%x", |
495 | data); | 510 | data); |
496 | nvgpu_udelay(5); | 511 | nvgpu_udelay(5); |
497 | } else | 512 | } else { |
498 | break; | 513 | break; |
514 | } | ||
499 | } while (!nvgpu_timeout_expired(&timeout)); | 515 | } while (!nvgpu_timeout_expired(&timeout)); |
500 | 516 | ||
501 | if (nvgpu_timeout_peek_expired(&timeout)) | 517 | if (nvgpu_timeout_peek_expired(&timeout)) { |
502 | nvgpu_warn(g, "l2_system_invalidate too many retries"); | 518 | nvgpu_warn(g, "l2_system_invalidate too many retries"); |
519 | } | ||
503 | 520 | ||
504 | trace_gk20a_mm_l2_invalidate_done(g->name); | 521 | trace_gk20a_mm_l2_invalidate_done(g->name); |
505 | } | 522 | } |
@@ -526,11 +543,13 @@ void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate) | |||
526 | nvgpu_log_fn(g, " "); | 543 | nvgpu_log_fn(g, " "); |
527 | 544 | ||
528 | gk20a_busy_noresume(g); | 545 | gk20a_busy_noresume(g); |
529 | if (!g->power_on) | 546 | if (!g->power_on) { |
530 | goto hw_was_off; | 547 | goto hw_was_off; |
548 | } | ||
531 | 549 | ||
532 | if (g->ops.mm.get_flush_retries) | 550 | if (g->ops.mm.get_flush_retries) { |
533 | retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_L2_FLUSH); | 551 | retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_L2_FLUSH); |
552 | } | ||
534 | 553 | ||
535 | nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); | 554 | nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); |
536 | 555 | ||
@@ -552,15 +571,17 @@ void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate) | |||
552 | flush_l2_flush_dirty_pending_busy_v()) { | 571 | flush_l2_flush_dirty_pending_busy_v()) { |
553 | nvgpu_log_info(g, "l2_flush_dirty 0x%x", data); | 572 | nvgpu_log_info(g, "l2_flush_dirty 0x%x", data); |
554 | nvgpu_udelay(5); | 573 | nvgpu_udelay(5); |
555 | } else | 574 | } else { |
556 | break; | 575 | break; |
576 | } | ||
557 | } while (!nvgpu_timeout_expired_msg(&timeout, | 577 | } while (!nvgpu_timeout_expired_msg(&timeout, |
558 | "l2_flush_dirty too many retries")); | 578 | "l2_flush_dirty too many retries")); |
559 | 579 | ||
560 | trace_gk20a_mm_l2_flush_done(g->name); | 580 | trace_gk20a_mm_l2_flush_done(g->name); |
561 | 581 | ||
562 | if (invalidate) | 582 | if (invalidate) { |
563 | gk20a_mm_l2_invalidate_locked(g); | 583 | gk20a_mm_l2_invalidate_locked(g); |
584 | } | ||
564 | 585 | ||
565 | nvgpu_mutex_release(&mm->l2_op_lock); | 586 | nvgpu_mutex_release(&mm->l2_op_lock); |
566 | 587 | ||
@@ -578,11 +599,13 @@ void gk20a_mm_cbc_clean(struct gk20a *g) | |||
578 | nvgpu_log_fn(g, " "); | 599 | nvgpu_log_fn(g, " "); |
579 | 600 | ||
580 | gk20a_busy_noresume(g); | 601 | gk20a_busy_noresume(g); |
581 | if (!g->power_on) | 602 | if (!g->power_on) { |
582 | goto hw_was_off; | 603 | goto hw_was_off; |
604 | } | ||
583 | 605 | ||
584 | if (g->ops.mm.get_flush_retries) | 606 | if (g->ops.mm.get_flush_retries) { |
585 | retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_CBC_CLEAN); | 607 | retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_CBC_CLEAN); |
608 | } | ||
586 | 609 | ||
587 | nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); | 610 | nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); |
588 | 611 | ||
@@ -601,8 +624,9 @@ void gk20a_mm_cbc_clean(struct gk20a *g) | |||
601 | flush_l2_clean_comptags_pending_busy_v()) { | 624 | flush_l2_clean_comptags_pending_busy_v()) { |
602 | nvgpu_log_info(g, "l2_clean_comptags 0x%x", data); | 625 | nvgpu_log_info(g, "l2_clean_comptags 0x%x", data); |
603 | nvgpu_udelay(5); | 626 | nvgpu_udelay(5); |
604 | } else | 627 | } else { |
605 | break; | 628 | break; |
629 | } | ||
606 | } while (!nvgpu_timeout_expired_msg(&timeout, | 630 | } while (!nvgpu_timeout_expired_msg(&timeout, |
607 | "l2_clean_comptags too many retries")); | 631 | "l2_clean_comptags too many retries")); |
608 | 632 | ||