summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fb_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/fb_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fb_gk20a.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fb_gk20a.c b/drivers/gpu/nvgpu/gk20a/fb_gk20a.c
index 1efa56fb..4b8baad5 100644
--- a/drivers/gpu/nvgpu/gk20a/fb_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fb_gk20a.c
@@ -14,6 +14,8 @@
14 */ 14 */
15 15
16#include <linux/types.h> 16#include <linux/types.h>
17#include <trace/events/gk20a.h>
18#include <linux/delay.h>
17 19
18#include "gk20a.h" 20#include "gk20a.h"
19#include "kind_gk20a.h" 21#include "kind_gk20a.h"
@@ -40,6 +42,13 @@ void fb_gk20a_reset(struct gk20a *g)
40 gk20a_writel(g, mc_elpg_enable_r(), val); 42 gk20a_writel(g, mc_elpg_enable_r(), val);
41} 43}
42 44
45void gk20a_fb_init_hw(struct gk20a *g)
46{
47 gk20a_writel(g, fb_niso_flush_sysmem_addr_r(),
48 g->ops.mm.get_iova_addr(g, g->mm.sysmem_flush.sgt->sgl, 0)
49 >> 8);
50}
51
43static void gk20a_fb_set_mmu_page_size(struct gk20a *g) 52static void gk20a_fb_set_mmu_page_size(struct gk20a *g)
44{ 53{
45 /* set large page size in fb */ 54 /* set large page size in fb */
@@ -62,12 +71,104 @@ static unsigned int gk20a_fb_compressible_page_size(struct gk20a *g)
62 return SZ_64K; 71 return SZ_64K;
63} 72}
64 73
74bool gk20a_fb_debug_mode_enabled(struct gk20a *g)
75{
76 u32 debug_ctrl = gk20a_readl(g, fb_mmu_debug_ctrl_r());
77 return fb_mmu_debug_ctrl_debug_v(debug_ctrl) ==
78 fb_mmu_debug_ctrl_debug_enabled_v();
79}
80
81static void gk20a_fb_set_debug_mode(struct gk20a *g, bool enable)
82{
83 u32 reg_val, debug_ctrl;
84
85 reg_val = gk20a_readl(g, fb_mmu_debug_ctrl_r());
86 if (enable) {
87 debug_ctrl = fb_mmu_debug_ctrl_debug_enabled_f();
88 g->mmu_debug_ctrl = true;
89 } else {
90 debug_ctrl = fb_mmu_debug_ctrl_debug_disabled_f();
91 g->mmu_debug_ctrl = false;
92 }
93
94 reg_val = set_field(reg_val,
95 fb_mmu_debug_ctrl_debug_m(), debug_ctrl);
96 gk20a_writel(g, fb_mmu_debug_ctrl_r(), reg_val);
97}
98
99void gk20a_fb_tlb_invalidate(struct gk20a *g, struct mem_desc *pdb)
100{
101 struct nvgpu_timeout timeout;
102 u32 addr_lo;
103 u32 data;
104
105 gk20a_dbg_fn("");
106
107 /* pagetables are considered sw states which are preserved after
108 prepare_poweroff. When gk20a deinit releases those pagetables,
109 common code in vm unmap path calls tlb invalidate that touches
110 hw. Use the power_on flag to skip tlb invalidation when gpu
111 power is turned off */
112
113 if (!g->power_on)
114 return;
115
116 addr_lo = u64_lo32(gk20a_mem_get_base_addr(g, pdb, 0) >> 12);
117
118 nvgpu_mutex_acquire(&g->mm.tlb_lock);
119
120 trace_gk20a_mm_tlb_invalidate(dev_name(g->dev));
121
122 nvgpu_timeout_init(g, &timeout, 1000, NVGPU_TIMER_RETRY_TIMER);
123
124 do {
125 data = gk20a_readl(g, fb_mmu_ctrl_r());
126 if (fb_mmu_ctrl_pri_fifo_space_v(data) != 0)
127 break;
128 udelay(2);
129 } while (!nvgpu_timeout_expired_msg(&timeout,
130 "wait mmu fifo space"));
131
132 if (nvgpu_timeout_peek_expired(&timeout))
133 goto out;
134
135 nvgpu_timeout_init(g, &timeout, 1000, NVGPU_TIMER_RETRY_TIMER);
136
137 gk20a_writel(g, fb_mmu_invalidate_pdb_r(),
138 fb_mmu_invalidate_pdb_addr_f(addr_lo) |
139 gk20a_aperture_mask(g, pdb,
140 fb_mmu_invalidate_pdb_aperture_sys_mem_f(),
141 fb_mmu_invalidate_pdb_aperture_vid_mem_f()));
142
143 gk20a_writel(g, fb_mmu_invalidate_r(),
144 fb_mmu_invalidate_all_va_true_f() |
145 fb_mmu_invalidate_trigger_true_f());
146
147 do {
148 data = gk20a_readl(g, fb_mmu_ctrl_r());
149 if (fb_mmu_ctrl_pri_fifo_empty_v(data) !=
150 fb_mmu_ctrl_pri_fifo_empty_false_f())
151 break;
152 udelay(2);
153 } while (!nvgpu_timeout_expired_msg(&timeout,
154 "wait mmu invalidate"));
155
156 trace_gk20a_mm_tlb_invalidate_done(dev_name(g->dev));
157
158out:
159 nvgpu_mutex_release(&g->mm.tlb_lock);
160}
161
65void gk20a_init_fb(struct gpu_ops *gops) 162void gk20a_init_fb(struct gpu_ops *gops)
66{ 163{
164 gops->fb.init_hw = gk20a_fb_init_hw;
67 gops->fb.reset = fb_gk20a_reset; 165 gops->fb.reset = fb_gk20a_reset;
68 gops->fb.set_mmu_page_size = gk20a_fb_set_mmu_page_size; 166 gops->fb.set_mmu_page_size = gk20a_fb_set_mmu_page_size;
69 gops->fb.compression_page_size = gk20a_fb_compression_page_size; 167 gops->fb.compression_page_size = gk20a_fb_compression_page_size;
70 gops->fb.compressible_page_size = gk20a_fb_compressible_page_size; 168 gops->fb.compressible_page_size = gk20a_fb_compressible_page_size;
169 gops->fb.is_debug_mode_enabled = gk20a_fb_debug_mode_enabled;
170 gops->fb.set_debug_mode = gk20a_fb_set_debug_mode;
171 gops->fb.tlb_invalidate = gk20a_fb_tlb_invalidate;
71 gk20a_init_uncompressed_kind_map(); 172 gk20a_init_uncompressed_kind_map();
72 gk20a_init_kind_attr(); 173 gk20a_init_kind_attr();
73} 174}