summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/fb/fb_gm20b.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/fb/fb_gm20b.c')
-rw-r--r--drivers/gpu/nvgpu/common/fb/fb_gm20b.c229
1 files changed, 229 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/common/fb/fb_gm20b.c b/drivers/gpu/nvgpu/common/fb/fb_gm20b.c
new file mode 100644
index 00000000..bd093b31
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/fb/fb_gm20b.c
@@ -0,0 +1,229 @@
1/*
2 * GM20B GPC MMU
3 *
4 * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
5*
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <nvgpu/sizes.h>
26
27#include "gk20a/gk20a.h"
28
29#include "fb_gk20a.h"
30#include "fb_gm20b.h"
31
32#include <nvgpu/hw/gm20b/hw_fb_gm20b.h>
33#include <nvgpu/hw/gm20b/hw_top_gm20b.h>
34#include <nvgpu/hw/gm20b/hw_gmmu_gm20b.h>
35#include <nvgpu/hw/gm20b/hw_gr_gm20b.h>
36
37#define VPR_INFO_FETCH_WAIT (5)
38#define WPR_INFO_ADDR_ALIGNMENT 0x0000000c
39
40void fb_gm20b_init_fs_state(struct gk20a *g)
41{
42 nvgpu_log_info(g, "initialize gm20b fb");
43
44 gk20a_writel(g, fb_fbhub_num_active_ltcs_r(),
45 g->ltc_count);
46
47 if (!nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) {
48 /* Bypass MMU check for non-secure boot. For
49 * secure-boot,this register write has no-effect */
50 gk20a_writel(g, fb_priv_mmu_phy_secure_r(), 0xffffffffU);
51 }
52}
53
54void gm20b_fb_set_mmu_page_size(struct gk20a *g)
55{
56 /* set large page size in fb */
57 u32 fb_mmu_ctrl = gk20a_readl(g, fb_mmu_ctrl_r());
58 fb_mmu_ctrl |= fb_mmu_ctrl_use_pdb_big_page_size_true_f();
59 gk20a_writel(g, fb_mmu_ctrl_r(), fb_mmu_ctrl);
60}
61
62bool gm20b_fb_set_use_full_comp_tag_line(struct gk20a *g)
63{
64 /* set large page size in fb */
65 u32 fb_mmu_ctrl = gk20a_readl(g, fb_mmu_ctrl_r());
66 fb_mmu_ctrl |= fb_mmu_ctrl_use_full_comp_tag_line_true_f();
67 gk20a_writel(g, fb_mmu_ctrl_r(), fb_mmu_ctrl);
68
69 return true;
70}
71
72u32 gm20b_fb_mmu_ctrl(struct gk20a *g)
73{
74 return gk20a_readl(g, fb_mmu_ctrl_r());
75}
76
77u32 gm20b_fb_mmu_debug_ctrl(struct gk20a *g)
78{
79 return gk20a_readl(g, fb_mmu_debug_ctrl_r());
80}
81
82u32 gm20b_fb_mmu_debug_wr(struct gk20a *g)
83{
84 return gk20a_readl(g, fb_mmu_debug_wr_r());
85}
86
87u32 gm20b_fb_mmu_debug_rd(struct gk20a *g)
88{
89 return gk20a_readl(g, fb_mmu_debug_rd_r());
90}
91
92unsigned int gm20b_fb_compression_page_size(struct gk20a *g)
93{
94 return SZ_128K;
95}
96
97unsigned int gm20b_fb_compressible_page_size(struct gk20a *g)
98{
99 return SZ_64K;
100}
101
102u32 gm20b_fb_compression_align_mask(struct gk20a *g)
103{
104 return SZ_64K - 1;
105}
106
107void gm20b_fb_dump_vpr_wpr_info(struct gk20a *g)
108{
109 u32 val;
110
111 /* print vpr and wpr info */
112 val = gk20a_readl(g, fb_mmu_vpr_info_r());
113 val &= ~0x3;
114 val |= fb_mmu_vpr_info_index_addr_lo_v();
115 gk20a_writel(g, fb_mmu_vpr_info_r(), val);
116 nvgpu_err(g, "VPR: %08x %08x %08x %08x",
117 gk20a_readl(g, fb_mmu_vpr_info_r()),
118 gk20a_readl(g, fb_mmu_vpr_info_r()),
119 gk20a_readl(g, fb_mmu_vpr_info_r()),
120 gk20a_readl(g, fb_mmu_vpr_info_r()));
121
122 val = gk20a_readl(g, fb_mmu_wpr_info_r());
123 val &= ~0xf;
124 val |= (fb_mmu_wpr_info_index_allow_read_v());
125 gk20a_writel(g, fb_mmu_wpr_info_r(), val);
126 nvgpu_err(g, "WPR: %08x %08x %08x %08x %08x %08x",
127 gk20a_readl(g, fb_mmu_wpr_info_r()),
128 gk20a_readl(g, fb_mmu_wpr_info_r()),
129 gk20a_readl(g, fb_mmu_wpr_info_r()),
130 gk20a_readl(g, fb_mmu_wpr_info_r()),
131 gk20a_readl(g, fb_mmu_wpr_info_r()),
132 gk20a_readl(g, fb_mmu_wpr_info_r()));
133
134}
135
136static int gm20b_fb_vpr_info_fetch_wait(struct gk20a *g,
137 unsigned int msec)
138{
139 struct nvgpu_timeout timeout;
140
141 nvgpu_timeout_init(g, &timeout, msec, NVGPU_TIMER_CPU_TIMER);
142
143 do {
144 u32 val;
145
146 val = gk20a_readl(g, fb_mmu_vpr_info_r());
147 if (fb_mmu_vpr_info_fetch_v(val) ==
148 fb_mmu_vpr_info_fetch_false_v())
149 return 0;
150
151 } while (!nvgpu_timeout_expired(&timeout));
152
153 return -ETIMEDOUT;
154}
155
156int gm20b_fb_vpr_info_fetch(struct gk20a *g)
157{
158 if (gm20b_fb_vpr_info_fetch_wait(g, VPR_INFO_FETCH_WAIT)) {
159 return -ETIMEDOUT;
160 }
161
162 gk20a_writel(g, fb_mmu_vpr_info_r(),
163 fb_mmu_vpr_info_fetch_true_v());
164
165 return gm20b_fb_vpr_info_fetch_wait(g, VPR_INFO_FETCH_WAIT);
166}
167
168void gm20b_fb_read_wpr_info(struct gk20a *g, struct wpr_carveout_info *inf)
169{
170 u32 val = 0;
171 u64 wpr_start = 0;
172 u64 wpr_end = 0;
173
174 val = gk20a_readl(g, fb_mmu_wpr_info_r());
175 val &= ~0xF;
176 val |= fb_mmu_wpr_info_index_wpr1_addr_lo_v();
177 gk20a_writel(g, fb_mmu_wpr_info_r(), val);
178
179 val = gk20a_readl(g, fb_mmu_wpr_info_r()) >> 0x4;
180 wpr_start = hi32_lo32_to_u64(
181 (val >> (32 - WPR_INFO_ADDR_ALIGNMENT)),
182 (val << WPR_INFO_ADDR_ALIGNMENT));
183
184 val = gk20a_readl(g, fb_mmu_wpr_info_r());
185 val &= ~0xF;
186 val |= fb_mmu_wpr_info_index_wpr1_addr_hi_v();
187 gk20a_writel(g, fb_mmu_wpr_info_r(), val);
188
189 val = gk20a_readl(g, fb_mmu_wpr_info_r()) >> 0x4;
190 wpr_end = hi32_lo32_to_u64(
191 (val >> (32 - WPR_INFO_ADDR_ALIGNMENT)),
192 (val << WPR_INFO_ADDR_ALIGNMENT));
193
194 inf->wpr_base = wpr_start;
195 inf->nonwpr_base = 0;
196 inf->size = (wpr_end - wpr_start);
197}
198
199bool gm20b_fb_debug_mode_enabled(struct gk20a *g)
200{
201 u32 debug_ctrl = gk20a_readl(g, gr_gpcs_pri_mmu_debug_ctrl_r());
202 return gr_gpcs_pri_mmu_debug_ctrl_debug_v(debug_ctrl) ==
203 gr_gpcs_pri_mmu_debug_ctrl_debug_enabled_v();
204}
205
206void gm20b_fb_set_debug_mode(struct gk20a *g, bool enable)
207{
208 u32 reg_val, fb_debug_ctrl, gpc_debug_ctrl;
209
210 if (enable) {
211 fb_debug_ctrl = fb_mmu_debug_ctrl_debug_enabled_f();
212 gpc_debug_ctrl = gr_gpcs_pri_mmu_debug_ctrl_debug_enabled_f();
213 g->mmu_debug_ctrl = true;
214 } else {
215 fb_debug_ctrl = fb_mmu_debug_ctrl_debug_disabled_f();
216 gpc_debug_ctrl = gr_gpcs_pri_mmu_debug_ctrl_debug_disabled_f();
217 g->mmu_debug_ctrl = false;
218 }
219
220 reg_val = gk20a_readl(g, fb_mmu_debug_ctrl_r());
221 reg_val = set_field(reg_val,
222 fb_mmu_debug_ctrl_debug_m(), fb_debug_ctrl);
223 gk20a_writel(g, fb_mmu_debug_ctrl_r(), reg_val);
224
225 reg_val = gk20a_readl(g, gr_gpcs_pri_mmu_debug_ctrl_r());
226 reg_val = set_field(reg_val,
227 gr_gpcs_pri_mmu_debug_ctrl_debug_m(), gpc_debug_ctrl);
228 gk20a_writel(g, gr_gpcs_pri_mmu_debug_ctrl_r(), reg_val);
229}