diff options
Diffstat (limited to 'drivers/gpu/nvgpu/vgpu/tsg_vgpu.c')
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/tsg_vgpu.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/vgpu/tsg_vgpu.c b/drivers/gpu/nvgpu/vgpu/tsg_vgpu.c new file mode 100644 index 00000000..683317dc --- /dev/null +++ b/drivers/gpu/nvgpu/vgpu/tsg_vgpu.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016-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 <linux/tegra_vgpu.h> | ||
24 | |||
25 | #include "gk20a/gk20a.h" | ||
26 | #include "gk20a/channel_gk20a.h" | ||
27 | #include "gk20a/tsg_gk20a.h" | ||
28 | #include "common/linux/platform_gk20a.h" | ||
29 | #include "vgpu.h" | ||
30 | #include "fifo_vgpu.h" | ||
31 | |||
32 | #include <nvgpu/bug.h> | ||
33 | |||
34 | int vgpu_tsg_open(struct tsg_gk20a *tsg) | ||
35 | { | ||
36 | struct tegra_vgpu_cmd_msg msg = {}; | ||
37 | struct tegra_vgpu_tsg_open_params *p = | ||
38 | &msg.params.tsg_open; | ||
39 | int err; | ||
40 | |||
41 | gk20a_dbg_fn(""); | ||
42 | |||
43 | msg.cmd = TEGRA_VGPU_CMD_TSG_OPEN; | ||
44 | msg.handle = vgpu_get_handle(tsg->g); | ||
45 | p->tsg_id = tsg->tsgid; | ||
46 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); | ||
47 | err = err ? err : msg.ret; | ||
48 | if (err) { | ||
49 | nvgpu_err(tsg->g, | ||
50 | "vgpu_tsg_open failed, tsgid %d", tsg->tsgid); | ||
51 | } | ||
52 | |||
53 | return err; | ||
54 | } | ||
55 | |||
56 | int vgpu_enable_tsg(struct tsg_gk20a *tsg) | ||
57 | { | ||
58 | struct gk20a *g = tsg->g; | ||
59 | struct channel_gk20a *ch; | ||
60 | |||
61 | nvgpu_rwsem_down_read(&tsg->ch_list_lock); | ||
62 | nvgpu_list_for_each_entry(ch, &tsg->ch_list, channel_gk20a, ch_entry) | ||
63 | g->ops.fifo.enable_channel(ch); | ||
64 | nvgpu_rwsem_up_read(&tsg->ch_list_lock); | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | int vgpu_tsg_bind_channel(struct tsg_gk20a *tsg, | ||
70 | struct channel_gk20a *ch) | ||
71 | { | ||
72 | struct tegra_vgpu_cmd_msg msg = {}; | ||
73 | struct tegra_vgpu_tsg_bind_unbind_channel_params *p = | ||
74 | &msg.params.tsg_bind_unbind_channel; | ||
75 | int err; | ||
76 | |||
77 | gk20a_dbg_fn(""); | ||
78 | |||
79 | err = gk20a_tsg_bind_channel(tsg, ch); | ||
80 | if (err) | ||
81 | return err; | ||
82 | |||
83 | msg.cmd = TEGRA_VGPU_CMD_TSG_BIND_CHANNEL; | ||
84 | msg.handle = vgpu_get_handle(tsg->g); | ||
85 | p->tsg_id = tsg->tsgid; | ||
86 | p->ch_handle = ch->virt_ctx; | ||
87 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); | ||
88 | err = err ? err : msg.ret; | ||
89 | if (err) { | ||
90 | nvgpu_err(tsg->g, | ||
91 | "vgpu_tsg_bind_channel failed, ch %d tsgid %d", | ||
92 | ch->chid, tsg->tsgid); | ||
93 | gk20a_tsg_unbind_channel(ch); | ||
94 | } | ||
95 | |||
96 | return err; | ||
97 | } | ||
98 | |||
99 | int vgpu_tsg_unbind_channel(struct channel_gk20a *ch) | ||
100 | { | ||
101 | struct tegra_vgpu_cmd_msg msg = {}; | ||
102 | struct tegra_vgpu_tsg_bind_unbind_channel_params *p = | ||
103 | &msg.params.tsg_bind_unbind_channel; | ||
104 | int err; | ||
105 | |||
106 | gk20a_dbg_fn(""); | ||
107 | |||
108 | err = gk20a_tsg_unbind_channel(ch); | ||
109 | if (err) | ||
110 | return err; | ||
111 | |||
112 | msg.cmd = TEGRA_VGPU_CMD_TSG_UNBIND_CHANNEL; | ||
113 | msg.handle = vgpu_get_handle(ch->g); | ||
114 | p->ch_handle = ch->virt_ctx; | ||
115 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); | ||
116 | err = err ? err : msg.ret; | ||
117 | WARN_ON(err); | ||
118 | |||
119 | return err; | ||
120 | } | ||
121 | |||
122 | int vgpu_tsg_set_timeslice(struct tsg_gk20a *tsg, u32 timeslice) | ||
123 | { | ||
124 | struct tegra_vgpu_cmd_msg msg = {0}; | ||
125 | struct tegra_vgpu_tsg_timeslice_params *p = | ||
126 | &msg.params.tsg_timeslice; | ||
127 | int err; | ||
128 | |||
129 | gk20a_dbg_fn(""); | ||
130 | |||
131 | msg.cmd = TEGRA_VGPU_CMD_TSG_SET_TIMESLICE; | ||
132 | msg.handle = vgpu_get_handle(tsg->g); | ||
133 | p->tsg_id = tsg->tsgid; | ||
134 | p->timeslice_us = timeslice; | ||
135 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); | ||
136 | err = err ? err : msg.ret; | ||
137 | WARN_ON(err); | ||
138 | if (!err) | ||
139 | tsg->timeslice_us = timeslice; | ||
140 | |||
141 | return err; | ||
142 | } | ||