summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2015-11-06 11:32:36 -0500
committerTerje Bergstrom <tbergstrom@nvidia.com>2015-11-10 13:33:39 -0500
commit84523485399e29abeb4e89c064b4591985aeea91 (patch)
tree04b339fc93a5f155e53b2bc72df3ec66f22eaa1d /drivers/gpu/nvgpu/gk20a/mm_gk20a.c
parentcccd038f8d753c045d3592fc2730f750766df78b (diff)
gpu: nvgpu: Do not use G_ELPG_FLUSH
G_ELPG_FLUSH is protected in some chips. Use L2 flush operations instead. Bug 1698618 Change-Id: I984a8ace8bcd0ad2d4a4e2d63af75a342bdeb75a Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/828656 (cherry picked from commit ba9075fa43975112a221d37d246f0b8f5af40fab) Reviewed-on: http://git-master/r/829415
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 859e46fc..15fd32d3 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -3460,6 +3460,47 @@ hw_was_off:
3460 pm_runtime_put_noidle(&g->dev->dev); 3460 pm_runtime_put_noidle(&g->dev->dev);
3461} 3461}
3462 3462
3463void gk20a_mm_cbc_clean(struct gk20a *g)
3464{
3465 struct mm_gk20a *mm = &g->mm;
3466 u32 data;
3467 s32 retry = 200;
3468
3469 gk20a_dbg_fn("");
3470
3471 gk20a_busy_noresume(g->dev);
3472 if (!g->power_on)
3473 goto hw_was_off;
3474
3475 mutex_lock(&mm->l2_op_lock);
3476
3477 /* Flush all dirty lines from the CBC to L2 */
3478 gk20a_writel(g, flush_l2_clean_comptags_r(),
3479 flush_l2_clean_comptags_pending_busy_f());
3480
3481 do {
3482 data = gk20a_readl(g, flush_l2_clean_comptags_r());
3483
3484 if (flush_l2_clean_comptags_outstanding_v(data) ==
3485 flush_l2_clean_comptags_outstanding_true_v() ||
3486 flush_l2_clean_comptags_pending_v(data) ==
3487 flush_l2_clean_comptags_pending_busy_v()) {
3488 gk20a_dbg_info("l2_clean_comptags 0x%x", data);
3489 retry--;
3490 udelay(5);
3491 } else
3492 break;
3493 } while (retry >= 0 || !tegra_platform_is_silicon());
3494
3495 if (tegra_platform_is_silicon() && retry < 0)
3496 gk20a_warn(dev_from_gk20a(g),
3497 "l2_clean_comptags too many retries");
3498
3499 mutex_unlock(&mm->l2_op_lock);
3500
3501hw_was_off:
3502 pm_runtime_put_noidle(&g->dev->dev);
3503}
3463 3504
3464int gk20a_vm_find_buffer(struct vm_gk20a *vm, u64 gpu_va, 3505int gk20a_vm_find_buffer(struct vm_gk20a *vm, u64 gpu_va,
3465 struct dma_buf **dmabuf, 3506 struct dma_buf **dmabuf,
@@ -3555,7 +3596,8 @@ int gk20a_mm_suspend(struct gk20a *g)
3555{ 3596{
3556 gk20a_dbg_fn(""); 3597 gk20a_dbg_fn("");
3557 3598
3558 g->ops.ltc.elpg_flush(g); 3599 g->ops.mm.cbc_clean(g);
3600 g->ops.mm.l2_flush(g, false);
3559 3601
3560 gk20a_dbg_fn("done"); 3602 gk20a_dbg_fn("done");
3561 return 0; 3603 return 0;
@@ -3591,6 +3633,7 @@ void gk20a_init_mm(struct gpu_ops *gops)
3591 gops->mm.fb_flush = gk20a_mm_fb_flush; 3633 gops->mm.fb_flush = gk20a_mm_fb_flush;
3592 gops->mm.l2_invalidate = gk20a_mm_l2_invalidate; 3634 gops->mm.l2_invalidate = gk20a_mm_l2_invalidate;
3593 gops->mm.l2_flush = gk20a_mm_l2_flush; 3635 gops->mm.l2_flush = gk20a_mm_l2_flush;
3636 gops->mm.cbc_clean = gk20a_mm_cbc_clean;
3594 gops->mm.tlb_invalidate = gk20a_mm_tlb_invalidate; 3637 gops->mm.tlb_invalidate = gk20a_mm_tlb_invalidate;
3595 gops->mm.get_iova_addr = gk20a_mm_iova_addr; 3638 gops->mm.get_iova_addr = gk20a_mm_iova_addr;
3596 gops->mm.get_physical_addr_bits = gk20a_mm_get_physical_addr_bits; 3639 gops->mm.get_physical_addr_bits = gk20a_mm_get_physical_addr_bits;