diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2015-11-06 11:32:36 -0500 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2015-11-10 13:33:39 -0500 |
commit | 84523485399e29abeb4e89c064b4591985aeea91 (patch) | |
tree | 04b339fc93a5f155e53b2bc72df3ec66f22eaa1d | |
parent | cccd038f8d753c045d3592fc2730f750766df78b (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
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/hw_flush_gk20a.h | 42 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 45 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/hw_flush_gm20b.h | 42 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/mm_gm20b.c | 1 |
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 | } |
117 | static inline u32 flush_l2_clean_comptags_r(void) | ||
118 | { | ||
119 | return 0x0007000c; | ||
120 | } | ||
121 | static inline u32 flush_l2_clean_comptags_pending_v(u32 r) | ||
122 | { | ||
123 | return (r >> 0) & 0x1; | ||
124 | } | ||
125 | static inline u32 flush_l2_clean_comptags_pending_empty_v(void) | ||
126 | { | ||
127 | return 0x00000000; | ||
128 | } | ||
129 | static inline u32 flush_l2_clean_comptags_pending_empty_f(void) | ||
130 | { | ||
131 | return 0x0; | ||
132 | } | ||
133 | static inline u32 flush_l2_clean_comptags_pending_busy_v(void) | ||
134 | { | ||
135 | return 0x00000001; | ||
136 | } | ||
137 | static inline u32 flush_l2_clean_comptags_pending_busy_f(void) | ||
138 | { | ||
139 | return 0x1; | ||
140 | } | ||
141 | static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r) | ||
142 | { | ||
143 | return (r >> 1) & 0x1; | ||
144 | } | ||
145 | static inline u32 flush_l2_clean_comptags_outstanding_false_v(void) | ||
146 | { | ||
147 | return 0x00000000; | ||
148 | } | ||
149 | static inline u32 flush_l2_clean_comptags_outstanding_false_f(void) | ||
150 | { | ||
151 | return 0x0; | ||
152 | } | ||
153 | static inline u32 flush_l2_clean_comptags_outstanding_true_v(void) | ||
154 | { | ||
155 | return 0x00000001; | ||
156 | } | ||
117 | static inline u32 flush_fb_flush_r(void) | 157 | static 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 | ||
3463 | void 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 | |||
3501 | hw_was_off: | ||
3502 | pm_runtime_put_noidle(&g->dev->dev); | ||
3503 | } | ||
3463 | 3504 | ||
3464 | int gk20a_vm_find_buffer(struct vm_gk20a *vm, u64 gpu_va, | 3505 | int 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 | ||
284 | int gk20a_mm_fb_flush(struct gk20a *g); | 284 | int gk20a_mm_fb_flush(struct gk20a *g); |
285 | void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate); | 285 | void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate); |
286 | void gk20a_mm_cbc_clean(struct gk20a *g); | ||
286 | void gk20a_mm_l2_invalidate(struct gk20a *g); | 287 | void gk20a_mm_l2_invalidate(struct gk20a *g); |
287 | 288 | ||
288 | struct mm_gk20a { | 289 | struct 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 | } |
117 | static inline u32 flush_l2_clean_comptags_r(void) | ||
118 | { | ||
119 | return 0x0007000c; | ||
120 | } | ||
121 | static inline u32 flush_l2_clean_comptags_pending_v(u32 r) | ||
122 | { | ||
123 | return (r >> 0) & 0x1; | ||
124 | } | ||
125 | static inline u32 flush_l2_clean_comptags_pending_empty_v(void) | ||
126 | { | ||
127 | return 0x00000000; | ||
128 | } | ||
129 | static inline u32 flush_l2_clean_comptags_pending_empty_f(void) | ||
130 | { | ||
131 | return 0x0; | ||
132 | } | ||
133 | static inline u32 flush_l2_clean_comptags_pending_busy_v(void) | ||
134 | { | ||
135 | return 0x00000001; | ||
136 | } | ||
137 | static inline u32 flush_l2_clean_comptags_pending_busy_f(void) | ||
138 | { | ||
139 | return 0x1; | ||
140 | } | ||
141 | static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r) | ||
142 | { | ||
143 | return (r >> 1) & 0x1; | ||
144 | } | ||
145 | static inline u32 flush_l2_clean_comptags_outstanding_false_v(void) | ||
146 | { | ||
147 | return 0x00000000; | ||
148 | } | ||
149 | static inline u32 flush_l2_clean_comptags_outstanding_false_f(void) | ||
150 | { | ||
151 | return 0x0; | ||
152 | } | ||
153 | static inline u32 flush_l2_clean_comptags_outstanding_true_v(void) | ||
154 | { | ||
155 | return 0x00000001; | ||
156 | } | ||
117 | static inline u32 flush_fb_flush_r(void) | 157 | static 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; |