diff options
Diffstat (limited to 'drivers/gpu/nvgpu/vgpu')
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/fifo_vgpu.c | 25 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/gr_vgpu.c | 82 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/tsg_vgpu.c | 85 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/vgpu.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/vgpu.h | 3 |
5 files changed, 177 insertions, 21 deletions
diff --git a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c index 8fcc7cc1..fb19db4a 100644 --- a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c | |||
@@ -410,6 +410,30 @@ static int vgpu_fifo_preempt_channel(struct gk20a *g, u32 hw_chid) | |||
410 | return err; | 410 | return err; |
411 | } | 411 | } |
412 | 412 | ||
413 | static int vgpu_fifo_preempt_tsg(struct gk20a *g, u32 tsgid) | ||
414 | { | ||
415 | struct gk20a_platform *platform = gk20a_get_platform(g->dev); | ||
416 | struct tegra_vgpu_cmd_msg msg; | ||
417 | struct tegra_vgpu_tsg_preempt_params *p = | ||
418 | &msg.params.tsg_preempt; | ||
419 | int err; | ||
420 | |||
421 | gk20a_dbg_fn(""); | ||
422 | |||
423 | msg.cmd = TEGRA_VGPU_CMD_TSG_PREEMPT; | ||
424 | msg.handle = platform->virt_handle; | ||
425 | p->tsg_id = tsgid; | ||
426 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); | ||
427 | err = err ? err : msg.ret; | ||
428 | |||
429 | if (err) { | ||
430 | gk20a_err(dev_from_gk20a(g), | ||
431 | "preempt tsg %u failed\n", tsgid); | ||
432 | } | ||
433 | |||
434 | return err; | ||
435 | } | ||
436 | |||
413 | static int vgpu_submit_runlist(u64 handle, u8 runlist_id, u16 *runlist, | 437 | static int vgpu_submit_runlist(u64 handle, u8 runlist_id, u16 *runlist, |
414 | u32 num_entries) | 438 | u32 num_entries) |
415 | { | 439 | { |
@@ -680,6 +704,7 @@ void vgpu_init_fifo_ops(struct gpu_ops *gops) | |||
680 | gops->fifo.free_inst = vgpu_channel_free_inst; | 704 | gops->fifo.free_inst = vgpu_channel_free_inst; |
681 | gops->fifo.setup_ramfc = vgpu_channel_setup_ramfc; | 705 | gops->fifo.setup_ramfc = vgpu_channel_setup_ramfc; |
682 | gops->fifo.preempt_channel = vgpu_fifo_preempt_channel; | 706 | gops->fifo.preempt_channel = vgpu_fifo_preempt_channel; |
707 | gops->fifo.preempt_tsg = vgpu_fifo_preempt_tsg; | ||
683 | gops->fifo.update_runlist = vgpu_fifo_update_runlist; | 708 | gops->fifo.update_runlist = vgpu_fifo_update_runlist; |
684 | gops->fifo.wait_engine_idle = vgpu_fifo_wait_engine_idle; | 709 | gops->fifo.wait_engine_idle = vgpu_fifo_wait_engine_idle; |
685 | gops->fifo.channel_set_priority = vgpu_channel_set_priority; | 710 | gops->fifo.channel_set_priority = vgpu_channel_set_priority; |
diff --git a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c index b9490ac9..f395ac1e 100644 --- a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c | |||
@@ -445,6 +445,26 @@ static int vgpu_gr_ch_bind_gr_ctx(struct channel_gk20a *c) | |||
445 | return err; | 445 | return err; |
446 | } | 446 | } |
447 | 447 | ||
448 | static int vgpu_gr_tsg_bind_gr_ctx(struct tsg_gk20a *tsg) | ||
449 | { | ||
450 | struct gk20a_platform *platform = gk20a_get_platform(tsg->g->dev); | ||
451 | struct gr_ctx_desc *gr_ctx = tsg->tsg_gr_ctx; | ||
452 | struct tegra_vgpu_cmd_msg msg = {0}; | ||
453 | struct tegra_vgpu_tsg_bind_gr_ctx_params *p = | ||
454 | &msg.params.tsg_bind_gr_ctx; | ||
455 | int err; | ||
456 | |||
457 | msg.cmd = TEGRA_VGPU_CMD_TSG_BIND_GR_CTX; | ||
458 | msg.handle = platform->virt_handle; | ||
459 | p->tsg_id = tsg->tsgid; | ||
460 | p->gr_ctx_handle = gr_ctx->virt_ctx; | ||
461 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); | ||
462 | err = err ? err : msg.ret; | ||
463 | WARN_ON(err); | ||
464 | |||
465 | return err; | ||
466 | } | ||
467 | |||
448 | static int vgpu_gr_alloc_obj_ctx(struct channel_gk20a *c, | 468 | static int vgpu_gr_alloc_obj_ctx(struct channel_gk20a *c, |
449 | struct nvgpu_alloc_obj_ctx_args *args) | 469 | struct nvgpu_alloc_obj_ctx_args *args) |
450 | { | 470 | { |
@@ -472,32 +492,58 @@ static int vgpu_gr_alloc_obj_ctx(struct channel_gk20a *c, | |||
472 | } | 492 | } |
473 | c->obj_class = args->class_num; | 493 | c->obj_class = args->class_num; |
474 | 494 | ||
475 | /* FIXME: add TSG support */ | ||
476 | if (gk20a_is_channel_marked_as_tsg(c)) | 495 | if (gk20a_is_channel_marked_as_tsg(c)) |
477 | tsg = &f->tsg[c->tsgid]; | 496 | tsg = &f->tsg[c->tsgid]; |
478 | 497 | ||
479 | /* allocate gr ctx buffer */ | 498 | if (!tsg) { |
480 | if (!ch_ctx->gr_ctx) { | 499 | /* allocate gr ctx buffer */ |
481 | err = g->ops.gr.alloc_gr_ctx(g, &c->ch_ctx.gr_ctx, | 500 | if (!ch_ctx->gr_ctx) { |
482 | c->vm, | 501 | err = g->ops.gr.alloc_gr_ctx(g, &c->ch_ctx.gr_ctx, |
483 | args->class_num, | 502 | c->vm, |
484 | args->flags); | 503 | args->class_num, |
485 | if (!err) | 504 | args->flags); |
486 | err = vgpu_gr_ch_bind_gr_ctx(c); | 505 | if (!err) |
506 | err = vgpu_gr_ch_bind_gr_ctx(c); | ||
507 | if (err) { | ||
508 | gk20a_err(dev_from_gk20a(g), | ||
509 | "fail to allocate gr ctx buffer"); | ||
510 | goto out; | ||
511 | } | ||
512 | } else { | ||
513 | /*TBD: needs to be more subtle about which is | ||
514 | * being allocated as some are allowed to be | ||
515 | * allocated along same channel */ | ||
516 | gk20a_err(dev_from_gk20a(g), | ||
517 | "too many classes alloc'd on same channel"); | ||
518 | err = -EINVAL; | ||
519 | goto out; | ||
520 | } | ||
521 | } else { | ||
522 | if (!tsg->tsg_gr_ctx) { | ||
523 | tsg->vm = c->vm; | ||
524 | gk20a_vm_get(tsg->vm); | ||
525 | err = g->ops.gr.alloc_gr_ctx(g, &tsg->tsg_gr_ctx, | ||
526 | c->vm, | ||
527 | args->class_num, | ||
528 | args->flags); | ||
529 | if (!err) | ||
530 | err = vgpu_gr_tsg_bind_gr_ctx(tsg); | ||
531 | if (err) { | ||
532 | gk20a_err(dev_from_gk20a(g), | ||
533 | "fail to allocate TSG gr ctx buffer, err=%d", err); | ||
534 | gk20a_vm_put(tsg->vm); | ||
535 | tsg->vm = NULL; | ||
536 | goto out; | ||
537 | } | ||
538 | } | ||
487 | 539 | ||
540 | ch_ctx->gr_ctx = tsg->tsg_gr_ctx; | ||
541 | err = vgpu_gr_ch_bind_gr_ctx(c); | ||
488 | if (err) { | 542 | if (err) { |
489 | gk20a_err(dev_from_gk20a(g), | 543 | gk20a_err(dev_from_gk20a(g), |
490 | "fail to allocate gr ctx buffer"); | 544 | "fail to bind gr ctx buffer"); |
491 | goto out; | 545 | goto out; |
492 | } | 546 | } |
493 | } else { | ||
494 | /*TBD: needs to be more subtle about which is | ||
495 | * being allocated as some are allowed to be | ||
496 | * allocated along same channel */ | ||
497 | gk20a_err(dev_from_gk20a(g), | ||
498 | "too many classes alloc'd on same channel"); | ||
499 | err = -EINVAL; | ||
500 | goto out; | ||
501 | } | 547 | } |
502 | 548 | ||
503 | /* commit gr ctx buffer */ | 549 | /* commit gr ctx buffer */ |
diff --git a/drivers/gpu/nvgpu/vgpu/tsg_vgpu.c b/drivers/gpu/nvgpu/vgpu/tsg_vgpu.c new file mode 100644 index 00000000..9245693d --- /dev/null +++ b/drivers/gpu/nvgpu/vgpu/tsg_vgpu.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
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, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/tegra_vgpu.h> | ||
19 | |||
20 | #include "gk20a/gk20a.h" | ||
21 | #include "gk20a/channel_gk20a.h" | ||
22 | #include "gk20a/platform_gk20a.h" | ||
23 | #include "gk20a/tsg_gk20a.h" | ||
24 | #include "vgpu.h" | ||
25 | |||
26 | static int vgpu_tsg_bind_channel(struct tsg_gk20a *tsg, | ||
27 | struct channel_gk20a *ch) | ||
28 | { | ||
29 | struct gk20a_platform *platform = gk20a_get_platform(tsg->g->dev); | ||
30 | struct tegra_vgpu_cmd_msg msg = {}; | ||
31 | struct tegra_vgpu_tsg_bind_unbind_channel_params *p = | ||
32 | &msg.params.tsg_bind_unbind_channel; | ||
33 | int err; | ||
34 | |||
35 | gk20a_dbg_fn(""); | ||
36 | |||
37 | err = gk20a_tsg_bind_channel(tsg, ch); | ||
38 | if (err) | ||
39 | return err; | ||
40 | |||
41 | msg.cmd = TEGRA_VGPU_CMD_TSG_BIND_CHANNEL; | ||
42 | msg.handle = platform->virt_handle; | ||
43 | p->tsg_id = tsg->tsgid; | ||
44 | p->ch_handle = ch->virt_ctx; | ||
45 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); | ||
46 | err = err ? err : msg.ret; | ||
47 | if (err) { | ||
48 | gk20a_err(dev_from_gk20a(tsg->g), | ||
49 | "vgpu_tsg_bind_channel failed, ch %d tsgid %d", | ||
50 | ch->hw_chid, tsg->tsgid); | ||
51 | gk20a_tsg_unbind_channel(ch); | ||
52 | } | ||
53 | |||
54 | return err; | ||
55 | } | ||
56 | |||
57 | static int vgpu_tsg_unbind_channel(struct channel_gk20a *ch) | ||
58 | { | ||
59 | struct gk20a_platform *platform = gk20a_get_platform(ch->g->dev); | ||
60 | struct tegra_vgpu_cmd_msg msg = {}; | ||
61 | struct tegra_vgpu_tsg_bind_unbind_channel_params *p = | ||
62 | &msg.params.tsg_bind_unbind_channel; | ||
63 | int err; | ||
64 | |||
65 | gk20a_dbg_fn(""); | ||
66 | |||
67 | err = gk20a_tsg_unbind_channel(ch); | ||
68 | if (err) | ||
69 | return err; | ||
70 | |||
71 | msg.cmd = TEGRA_VGPU_CMD_TSG_UNBIND_CHANNEL; | ||
72 | msg.handle = platform->virt_handle; | ||
73 | p->ch_handle = ch->virt_ctx; | ||
74 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); | ||
75 | err = err ? err : msg.ret; | ||
76 | WARN_ON(err); | ||
77 | |||
78 | return err; | ||
79 | } | ||
80 | |||
81 | void vgpu_init_tsg_ops(struct gpu_ops *gops) | ||
82 | { | ||
83 | gops->fifo.tsg_bind_channel = vgpu_tsg_bind_channel; | ||
84 | gops->fifo.tsg_unbind_channel = vgpu_tsg_unbind_channel; | ||
85 | } | ||
diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c index 3c06652b..4948d246 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/vgpu.c | |||
@@ -268,6 +268,7 @@ void vgpu_init_hal_common(struct gk20a *g) | |||
268 | vgpu_init_mm_ops(gops); | 268 | vgpu_init_mm_ops(gops); |
269 | vgpu_init_debug_ops(gops); | 269 | vgpu_init_debug_ops(gops); |
270 | vgpu_init_fecs_trace_ops(gops); | 270 | vgpu_init_fecs_trace_ops(gops); |
271 | vgpu_init_tsg_ops(gops); | ||
271 | gops->chip_init_gpu_characteristics = gk20a_init_gpu_characteristics; | 272 | gops->chip_init_gpu_characteristics = gk20a_init_gpu_characteristics; |
272 | } | 273 | } |
273 | 274 | ||
@@ -340,8 +341,6 @@ int vgpu_pm_finalize_poweron(struct device *dev) | |||
340 | goto done; | 341 | goto done; |
341 | } | 342 | } |
342 | 343 | ||
343 | g->gpu_characteristics.flags &= ~NVGPU_GPU_FLAGS_SUPPORT_TSG; | ||
344 | |||
345 | gk20a_ctxsw_trace_init(g); | 344 | gk20a_ctxsw_trace_init(g); |
346 | gk20a_channel_resume(g); | 345 | gk20a_channel_resume(g); |
347 | 346 | ||
diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.h b/drivers/gpu/nvgpu/vgpu/vgpu.h index 32f4b110..fdd0a54c 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.h +++ b/drivers/gpu/nvgpu/vgpu/vgpu.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Virtualized GPU Interfaces | 2 | * Virtualized GPU Interfaces |
3 | * | 3 | * |
4 | * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
@@ -47,6 +47,7 @@ void vgpu_init_gr_ops(struct gpu_ops *gops); | |||
47 | void vgpu_init_ltc_ops(struct gpu_ops *gops); | 47 | void vgpu_init_ltc_ops(struct gpu_ops *gops); |
48 | void vgpu_init_mm_ops(struct gpu_ops *gops); | 48 | void vgpu_init_mm_ops(struct gpu_ops *gops); |
49 | void vgpu_init_debug_ops(struct gpu_ops *gops); | 49 | void vgpu_init_debug_ops(struct gpu_ops *gops); |
50 | void vgpu_init_tsg_ops(struct gpu_ops *gops); | ||
50 | int vgpu_init_mm_support(struct gk20a *g); | 51 | int vgpu_init_mm_support(struct gk20a *g); |
51 | int vgpu_init_gr_support(struct gk20a *g); | 52 | int vgpu_init_gr_support(struct gk20a *g); |
52 | int vgpu_init_fifo_support(struct gk20a *g); | 53 | int vgpu_init_fifo_support(struct gk20a *g); |