summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/vgpu/gp10b/vgpu_gr_gp10b.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/vgpu/gp10b/vgpu_gr_gp10b.c')
-rw-r--r--drivers/gpu/nvgpu/vgpu/gp10b/vgpu_gr_gp10b.c336
1 files changed, 336 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/vgpu/gp10b/vgpu_gr_gp10b.c b/drivers/gpu/nvgpu/vgpu/gp10b/vgpu_gr_gp10b.c
new file mode 100644
index 00000000..d3ad6280
--- /dev/null
+++ b/drivers/gpu/nvgpu/vgpu/gp10b/vgpu_gr_gp10b.c
@@ -0,0 +1,336 @@
1/*
2 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <nvgpu/kmem.h>
24#include <nvgpu/dma.h>
25#include <nvgpu/bug.h>
26
27#include "vgpu/vgpu.h"
28#include "vgpu/gm20b/vgpu_gr_gm20b.h"
29
30#include "vgpu_gr_gp10b.h"
31
32#include <nvgpu/hw/gp10b/hw_gr_gp10b.h>
33
34void vgpu_gr_gp10b_free_gr_ctx(struct gk20a *g, struct vm_gk20a *vm,
35 struct gr_ctx_desc *gr_ctx)
36{
37 struct tegra_vgpu_cmd_msg msg = {0};
38 struct tegra_vgpu_gr_ctx_params *p = &msg.params.gr_ctx;
39 int err;
40
41 gk20a_dbg_fn("");
42
43 if (!gr_ctx || !gr_ctx->mem.gpu_va)
44 return;
45
46 msg.cmd = TEGRA_VGPU_CMD_GR_CTX_FREE;
47 msg.handle = vgpu_get_handle(g);
48 p->gr_ctx_handle = gr_ctx->virt_ctx;
49 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
50 WARN_ON(err || msg.ret);
51
52 __nvgpu_vm_free_va(vm, gr_ctx->mem.gpu_va, gmmu_page_size_kernel);
53
54 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.pagepool_ctxsw_buffer);
55 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.betacb_ctxsw_buffer);
56 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.spill_ctxsw_buffer);
57 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.preempt_ctxsw_buffer);
58
59 nvgpu_kfree(g, gr_ctx);
60}
61
62int vgpu_gr_gp10b_alloc_gr_ctx(struct gk20a *g,
63 struct gr_ctx_desc **__gr_ctx,
64 struct vm_gk20a *vm,
65 u32 class,
66 u32 flags)
67{
68 struct gr_ctx_desc *gr_ctx;
69 u32 graphics_preempt_mode = 0;
70 u32 compute_preempt_mode = 0;
71 struct vgpu_priv_data *priv = vgpu_get_priv_data(g);
72 int err;
73
74 gk20a_dbg_fn("");
75
76 err = vgpu_gr_alloc_gr_ctx(g, __gr_ctx, vm, class, flags);
77 if (err)
78 return err;
79
80 gr_ctx = *__gr_ctx;
81
82 if (flags & NVGPU_OBJ_CTX_FLAGS_SUPPORT_GFXP)
83 graphics_preempt_mode = NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP;
84 if (flags & NVGPU_OBJ_CTX_FLAGS_SUPPORT_CILP)
85 compute_preempt_mode = NVGPU_PREEMPTION_MODE_COMPUTE_CILP;
86
87 if (priv->constants.force_preempt_mode && !graphics_preempt_mode &&
88 !compute_preempt_mode) {
89 graphics_preempt_mode = PASCAL_A == class ?
90 NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP : 0;
91 compute_preempt_mode = PASCAL_COMPUTE_A == class ?
92 NVGPU_PREEMPTION_MODE_COMPUTE_CTA : 0;
93 }
94
95 if (graphics_preempt_mode || compute_preempt_mode) {
96 if (g->ops.gr.set_ctxsw_preemption_mode) {
97 err = g->ops.gr.set_ctxsw_preemption_mode(g, gr_ctx, vm,
98 class, graphics_preempt_mode, compute_preempt_mode);
99 if (err) {
100 nvgpu_err(g,
101 "set_ctxsw_preemption_mode failed");
102 goto fail;
103 }
104 } else {
105 err = -ENOSYS;
106 goto fail;
107 }
108 }
109
110 gk20a_dbg_fn("done");
111 return err;
112
113fail:
114 vgpu_gr_gp10b_free_gr_ctx(g, vm, gr_ctx);
115 return err;
116}
117
118int vgpu_gr_gp10b_set_ctxsw_preemption_mode(struct gk20a *g,
119 struct gr_ctx_desc *gr_ctx,
120 struct vm_gk20a *vm, u32 class,
121 u32 graphics_preempt_mode,
122 u32 compute_preempt_mode)
123{
124 struct tegra_vgpu_cmd_msg msg = {};
125 struct tegra_vgpu_gr_bind_ctxsw_buffers_params *p =
126 &msg.params.gr_bind_ctxsw_buffers;
127 int err = 0;
128
129 if (class == PASCAL_A && g->gr.t18x.ctx_vars.force_preemption_gfxp)
130 graphics_preempt_mode = NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP;
131
132 if (class == PASCAL_COMPUTE_A &&
133 g->gr.t18x.ctx_vars.force_preemption_cilp)
134 compute_preempt_mode = NVGPU_PREEMPTION_MODE_COMPUTE_CILP;
135
136 /* check for invalid combinations */
137 if ((graphics_preempt_mode == 0) && (compute_preempt_mode == 0))
138 return -EINVAL;
139
140 if ((graphics_preempt_mode == NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP) &&
141 (compute_preempt_mode == NVGPU_PREEMPTION_MODE_COMPUTE_CILP))
142 return -EINVAL;
143
144 /* set preemption modes */
145 switch (graphics_preempt_mode) {
146 case NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP:
147 {
148 u32 spill_size =
149 gr_gpc0_swdx_rm_spill_buffer_size_256b_default_v() *
150 gr_gpc0_swdx_rm_spill_buffer_size_256b_byte_granularity_v();
151 u32 pagepool_size = g->ops.gr.pagepool_default_size(g) *
152 gr_scc_pagepool_total_pages_byte_granularity_v();
153 u32 betacb_size = g->gr.attrib_cb_default_size +
154 (gr_gpc0_ppc0_cbm_beta_cb_size_v_gfxp_v() -
155 gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v());
156 u32 attrib_cb_size = (betacb_size + g->gr.alpha_cb_size) *
157 gr_gpc0_ppc0_cbm_beta_cb_size_v_granularity_v() *
158 g->gr.max_tpc_count;
159 struct nvgpu_mem *desc;
160
161 attrib_cb_size = ALIGN(attrib_cb_size, 128);
162
163 gk20a_dbg_info("gfxp context preempt size=%d",
164 g->gr.t18x.ctx_vars.preempt_image_size);
165 gk20a_dbg_info("gfxp context spill size=%d", spill_size);
166 gk20a_dbg_info("gfxp context pagepool size=%d", pagepool_size);
167 gk20a_dbg_info("gfxp context attrib cb size=%d",
168 attrib_cb_size);
169
170 err = gr_gp10b_alloc_buffer(vm,
171 g->gr.t18x.ctx_vars.preempt_image_size,
172 &gr_ctx->t18x.preempt_ctxsw_buffer);
173 if (err) {
174 err = -ENOMEM;
175 goto fail;
176 }
177 desc = &gr_ctx->t18x.preempt_ctxsw_buffer;
178 p->gpu_va[TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_MAIN] = desc->gpu_va;
179 p->size[TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_MAIN] = desc->size;
180
181 err = gr_gp10b_alloc_buffer(vm,
182 spill_size,
183 &gr_ctx->t18x.spill_ctxsw_buffer);
184 if (err) {
185 err = -ENOMEM;
186 goto fail;
187 }
188 desc = &gr_ctx->t18x.spill_ctxsw_buffer;
189 p->gpu_va[TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_SPILL] = desc->gpu_va;
190 p->size[TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_SPILL] = desc->size;
191
192 err = gr_gp10b_alloc_buffer(vm,
193 pagepool_size,
194 &gr_ctx->t18x.pagepool_ctxsw_buffer);
195 if (err) {
196 err = -ENOMEM;
197 goto fail;
198 }
199 desc = &gr_ctx->t18x.pagepool_ctxsw_buffer;
200 p->gpu_va[TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_PAGEPOOL] =
201 desc->gpu_va;
202 p->size[TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_PAGEPOOL] = desc->size;
203
204 err = gr_gp10b_alloc_buffer(vm,
205 attrib_cb_size,
206 &gr_ctx->t18x.betacb_ctxsw_buffer);
207 if (err) {
208 err = -ENOMEM;
209 goto fail;
210 }
211 desc = &gr_ctx->t18x.betacb_ctxsw_buffer;
212 p->gpu_va[TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_BETACB] =
213 desc->gpu_va;
214 p->size[TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_BETACB] = desc->size;
215
216 gr_ctx->graphics_preempt_mode = NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP;
217 p->mode = TEGRA_VGPU_GR_CTXSW_PREEMPTION_MODE_GFX_GFXP;
218 break;
219 }
220 case NVGPU_PREEMPTION_MODE_GRAPHICS_WFI:
221 gr_ctx->graphics_preempt_mode = graphics_preempt_mode;
222 break;
223
224 default:
225 break;
226 }
227
228 if (class == PASCAL_COMPUTE_A) {
229 switch (compute_preempt_mode) {
230 case NVGPU_PREEMPTION_MODE_COMPUTE_WFI:
231 gr_ctx->compute_preempt_mode =
232 NVGPU_PREEMPTION_MODE_COMPUTE_WFI;
233 p->mode = TEGRA_VGPU_GR_CTXSW_PREEMPTION_MODE_WFI;
234 break;
235 case NVGPU_PREEMPTION_MODE_COMPUTE_CTA:
236 gr_ctx->compute_preempt_mode =
237 NVGPU_PREEMPTION_MODE_COMPUTE_CTA;
238 p->mode =
239 TEGRA_VGPU_GR_CTXSW_PREEMPTION_MODE_COMPUTE_CTA;
240 break;
241 case NVGPU_PREEMPTION_MODE_COMPUTE_CILP:
242 gr_ctx->compute_preempt_mode =
243 NVGPU_PREEMPTION_MODE_COMPUTE_CILP;
244 p->mode =
245 TEGRA_VGPU_GR_CTXSW_PREEMPTION_MODE_COMPUTE_CILP;
246 break;
247 default:
248 break;
249 }
250 }
251
252 if (gr_ctx->graphics_preempt_mode || gr_ctx->compute_preempt_mode) {
253 msg.cmd = TEGRA_VGPU_CMD_CHANNEL_BIND_GR_CTXSW_BUFFERS;
254 msg.handle = vgpu_get_handle(g);
255 p->gr_ctx_handle = gr_ctx->virt_ctx;
256 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
257 if (err || msg.ret) {
258 err = -ENOMEM;
259 goto fail;
260 }
261 }
262
263 return err;
264
265fail:
266 nvgpu_err(g, "%s failed %d", __func__, err);
267 return err;
268}
269
270int vgpu_gr_gp10b_set_preemption_mode(struct channel_gk20a *ch,
271 u32 graphics_preempt_mode,
272 u32 compute_preempt_mode)
273{
274 struct gr_ctx_desc *gr_ctx = ch->ch_ctx.gr_ctx;
275 struct gk20a *g = ch->g;
276 struct tsg_gk20a *tsg;
277 struct vm_gk20a *vm;
278 u32 class;
279 int err;
280
281 class = ch->obj_class;
282 if (!class)
283 return -EINVAL;
284
285 /* skip setting anything if both modes are already set */
286 if (graphics_preempt_mode &&
287 (graphics_preempt_mode == gr_ctx->graphics_preempt_mode))
288 graphics_preempt_mode = 0;
289
290 if (compute_preempt_mode &&
291 (compute_preempt_mode == gr_ctx->compute_preempt_mode))
292 compute_preempt_mode = 0;
293
294 if (graphics_preempt_mode == 0 && compute_preempt_mode == 0)
295 return 0;
296
297 if (gk20a_is_channel_marked_as_tsg(ch)) {
298 tsg = &g->fifo.tsg[ch->tsgid];
299 vm = tsg->vm;
300 } else {
301 vm = ch->vm;
302 }
303
304 if (g->ops.gr.set_ctxsw_preemption_mode) {
305 err = g->ops.gr.set_ctxsw_preemption_mode(g, gr_ctx, vm, class,
306 graphics_preempt_mode,
307 compute_preempt_mode);
308 if (err) {
309 nvgpu_err(g, "set_ctxsw_preemption_mode failed");
310 return err;
311 }
312 } else {
313 err = -ENOSYS;
314 }
315
316 return err;
317}
318
319int vgpu_gr_gp10b_init_ctx_state(struct gk20a *g)
320{
321 struct vgpu_priv_data *priv = vgpu_get_priv_data(g);
322 int err;
323
324 gk20a_dbg_fn("");
325
326 err = vgpu_gr_init_ctx_state(g);
327 if (err)
328 return err;
329
330 g->gr.t18x.ctx_vars.preempt_image_size =
331 priv->constants.preempt_ctx_size;
332 if (!g->gr.t18x.ctx_vars.preempt_image_size)
333 return -EINVAL;
334
335 return 0;
336}