summaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gk20a/hw_flush_gk20a.h42
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c45
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gm20b/hw_flush_gm20b.h42
-rw-r--r--drivers/gpu/nvgpu/gm20b/mm_gm20b.c1
6 files changed, 129 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 58c8e9ad..e43e58a0 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -376,6 +376,7 @@ struct gpu_ops {
376 int (*fb_flush)(struct gk20a *g); 376 int (*fb_flush)(struct gk20a *g);
377 void (*l2_invalidate)(struct gk20a *g); 377 void (*l2_invalidate)(struct gk20a *g);
378 void (*l2_flush)(struct gk20a *g, bool invalidate); 378 void (*l2_flush)(struct gk20a *g, bool invalidate);
379 void (*cbc_clean)(struct gk20a *g);
379 void (*tlb_invalidate)(struct vm_gk20a *vm); 380 void (*tlb_invalidate)(struct vm_gk20a *vm);
380 void (*set_big_page_size)(struct gk20a *g, 381 void (*set_big_page_size)(struct gk20a *g,
381 void *inst_ptr, int size); 382 void *inst_ptr, int size);
diff --git a/drivers/gpu/nvgpu/gk20a/hw_flush_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_flush_gk20a.h
index 0aeb11f9..9cd91fad 100644
--- a/drivers/gpu/nvgpu/gk20a/hw_flush_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/hw_flush_gk20a.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -114,6 +114,46 @@ static inline u32 flush_l2_flush_dirty_outstanding_true_v(void)
114{ 114{
115 return 0x00000001; 115 return 0x00000001;
116} 116}
117static inline u32 flush_l2_clean_comptags_r(void)
118{
119 return 0x0007000c;
120}
121static inline u32 flush_l2_clean_comptags_pending_v(u32 r)
122{
123 return (r >> 0) & 0x1;
124}
125static inline u32 flush_l2_clean_comptags_pending_empty_v(void)
126{
127 return 0x00000000;
128}
129static inline u32 flush_l2_clean_comptags_pending_empty_f(void)
130{
131 return 0x0;
132}
133static inline u32 flush_l2_clean_comptags_pending_busy_v(void)
134{
135 return 0x00000001;
136}
137static inline u32 flush_l2_clean_comptags_pending_busy_f(void)
138{
139 return 0x1;
140}
141static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r)
142{
143 return (r >> 1) & 0x1;
144}
145static inline u32 flush_l2_clean_comptags_outstanding_false_v(void)
146{
147 return 0x00000000;
148}
149static inline u32 flush_l2_clean_comptags_outstanding_false_f(void)
150{
151 return 0x0;
152}
153static inline u32 flush_l2_clean_comptags_outstanding_true_v(void)
154{
155 return 0x00000001;
156}
117static inline u32 flush_fb_flush_r(void) 157static inline u32 flush_fb_flush_r(void)
118{ 158{
119 return 0x00070000; 159 return 0x00070000;
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;
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
index e44ee631..9e373d8e 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
@@ -283,6 +283,7 @@ int gk20a_init_mm_setup_hw(struct gk20a *g);
283 283
284int gk20a_mm_fb_flush(struct gk20a *g); 284int gk20a_mm_fb_flush(struct gk20a *g);
285void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate); 285void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate);
286void gk20a_mm_cbc_clean(struct gk20a *g);
286void gk20a_mm_l2_invalidate(struct gk20a *g); 287void gk20a_mm_l2_invalidate(struct gk20a *g);
287 288
288struct mm_gk20a { 289struct mm_gk20a {
diff --git a/drivers/gpu/nvgpu/gm20b/hw_flush_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_flush_gm20b.h
index a6d5e548..b77643be 100644
--- a/drivers/gpu/nvgpu/gm20b/hw_flush_gm20b.h
+++ b/drivers/gpu/nvgpu/gm20b/hw_flush_gm20b.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -114,6 +114,46 @@ static inline u32 flush_l2_flush_dirty_outstanding_true_v(void)
114{ 114{
115 return 0x00000001; 115 return 0x00000001;
116} 116}
117static inline u32 flush_l2_clean_comptags_r(void)
118{
119 return 0x0007000c;
120}
121static inline u32 flush_l2_clean_comptags_pending_v(u32 r)
122{
123 return (r >> 0) & 0x1;
124}
125static inline u32 flush_l2_clean_comptags_pending_empty_v(void)
126{
127 return 0x00000000;
128}
129static inline u32 flush_l2_clean_comptags_pending_empty_f(void)
130{
131 return 0x0;
132}
133static inline u32 flush_l2_clean_comptags_pending_busy_v(void)
134{
135 return 0x00000001;
136}
137static inline u32 flush_l2_clean_comptags_pending_busy_f(void)
138{
139 return 0x1;
140}
141static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r)
142{
143 return (r >> 1) & 0x1;
144}
145static inline u32 flush_l2_clean_comptags_outstanding_false_v(void)
146{
147 return 0x00000000;
148}
149static inline u32 flush_l2_clean_comptags_outstanding_false_f(void)
150{
151 return 0x0;
152}
153static inline u32 flush_l2_clean_comptags_outstanding_true_v(void)
154{
155 return 0x00000001;
156}
117static inline u32 flush_fb_flush_r(void) 157static inline u32 flush_fb_flush_r(void)
118{ 158{
119 return 0x00070000; 159 return 0x00070000;
diff --git a/drivers/gpu/nvgpu/gm20b/mm_gm20b.c b/drivers/gpu/nvgpu/gm20b/mm_gm20b.c
index cf7ae46b..3d75a631 100644
--- a/drivers/gpu/nvgpu/gm20b/mm_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/mm_gm20b.c
@@ -120,6 +120,7 @@ void gm20b_init_mm(struct gpu_ops *gops)
120 gops->mm.fb_flush = gk20a_mm_fb_flush; 120 gops->mm.fb_flush = gk20a_mm_fb_flush;
121 gops->mm.l2_invalidate = gk20a_mm_l2_invalidate; 121 gops->mm.l2_invalidate = gk20a_mm_l2_invalidate;
122 gops->mm.l2_flush = gk20a_mm_l2_flush; 122 gops->mm.l2_flush = gk20a_mm_l2_flush;
123 gops->mm.cbc_clean = gk20a_mm_cbc_clean;
123 gops->mm.tlb_invalidate = gk20a_mm_tlb_invalidate; 124 gops->mm.tlb_invalidate = gk20a_mm_tlb_invalidate;
124 gops->mm.set_big_page_size = gm20b_mm_set_big_page_size; 125 gops->mm.set_big_page_size = gm20b_mm_set_big_page_size;
125 gops->mm.get_big_page_sizes = gm20b_mm_get_big_page_sizes; 126 gops->mm.get_big_page_sizes = gm20b_mm_get_big_page_sizes;