diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/channel.c | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/ioctl_channel.c | 95 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/ioctl_channel.h | 11 |
3 files changed, 103 insertions, 8 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/channel.c b/drivers/gpu/nvgpu/common/linux/channel.c index 1ae2d444..0ed596ac 100644 --- a/drivers/gpu/nvgpu/common/linux/channel.c +++ b/drivers/gpu/nvgpu/common/linux/channel.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "gk20a/gk20a.h" | 29 | #include "gk20a/gk20a.h" |
30 | 30 | ||
31 | #include "channel.h" | 31 | #include "channel.h" |
32 | #include "ioctl_channel.h" | ||
32 | #include "os_linux.h" | 33 | #include "os_linux.h" |
33 | 34 | ||
34 | #include <nvgpu/hw/gk20a/hw_pbdma_gk20a.h> | 35 | #include <nvgpu/hw/gk20a/hw_pbdma_gk20a.h> |
@@ -242,6 +243,10 @@ static void nvgpu_channel_open_linux(struct channel_gk20a *ch) | |||
242 | static void nvgpu_channel_close_linux(struct channel_gk20a *ch) | 243 | static void nvgpu_channel_close_linux(struct channel_gk20a *ch) |
243 | { | 244 | { |
244 | nvgpu_channel_work_completion_clear(ch); | 245 | nvgpu_channel_work_completion_clear(ch); |
246 | |||
247 | #if defined(CONFIG_GK20A_CYCLE_STATS) | ||
248 | gk20a_channel_free_cycle_stats_snapshot(ch); | ||
249 | #endif | ||
245 | } | 250 | } |
246 | 251 | ||
247 | static int nvgpu_channel_alloc_linux(struct gk20a *g, struct channel_gk20a *ch) | 252 | static int nvgpu_channel_alloc_linux(struct gk20a *g, struct channel_gk20a *ch) |
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c index 67bec31b..13355605 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c +++ b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c | |||
@@ -42,6 +42,11 @@ | |||
42 | #include "os_linux.h" | 42 | #include "os_linux.h" |
43 | #include "ctxsw_trace.h" | 43 | #include "ctxsw_trace.h" |
44 | 44 | ||
45 | /* the minimal size of client buffer */ | ||
46 | #define CSS_MIN_CLIENT_SNAPSHOT_SIZE \ | ||
47 | (sizeof(struct gk20a_cs_snapshot_fifo) + \ | ||
48 | sizeof(struct gk20a_cs_snapshot_fifo_entry) * 256) | ||
49 | |||
45 | static const char *gr_gk20a_graphics_preempt_mode_name(u32 graphics_preempt_mode) | 50 | static const char *gr_gk20a_graphics_preempt_mode_name(u32 graphics_preempt_mode) |
46 | { | 51 | { |
47 | switch (graphics_preempt_mode) { | 52 | switch (graphics_preempt_mode) { |
@@ -157,18 +162,92 @@ static int gk20a_attach_cycle_stats_snapshot(struct channel_gk20a *ch, | |||
157 | u32 perfmon_id_count, | 162 | u32 perfmon_id_count, |
158 | u32 *perfmon_id_start) | 163 | u32 *perfmon_id_start) |
159 | { | 164 | { |
160 | int ret; | 165 | int ret = 0; |
166 | struct gk20a *g = ch->g; | ||
167 | struct gk20a_cs_snapshot_client_linux *client_linux; | ||
168 | struct gk20a_cs_snapshot_client *client; | ||
161 | 169 | ||
162 | nvgpu_mutex_acquire(&ch->cs_client_mutex); | 170 | nvgpu_mutex_acquire(&ch->cs_client_mutex); |
163 | if (ch->cs_client) { | 171 | if (ch->cs_client) { |
164 | ret = -EEXIST; | 172 | nvgpu_mutex_release(&ch->cs_client_mutex); |
165 | } else { | 173 | return -EEXIST; |
166 | ret = gr_gk20a_css_attach(ch, | 174 | } |
167 | dmabuf_fd, | 175 | |
168 | perfmon_id_count, | 176 | client_linux = nvgpu_kzalloc(g, sizeof(*client_linux)); |
169 | perfmon_id_start, | 177 | if (!client_linux) { |
170 | &ch->cs_client); | 178 | ret = -ENOMEM; |
179 | goto err; | ||
180 | } | ||
181 | |||
182 | client_linux->dmabuf_fd = dmabuf_fd; | ||
183 | client_linux->dma_handler = dma_buf_get(client_linux->dmabuf_fd); | ||
184 | if (IS_ERR(client_linux->dma_handler)) { | ||
185 | ret = PTR_ERR(client_linux->dma_handler); | ||
186 | client_linux->dma_handler = NULL; | ||
187 | goto err_free; | ||
188 | } | ||
189 | |||
190 | client = &client_linux->cs_client; | ||
191 | client->snapshot_size = client_linux->dma_handler->size; | ||
192 | if (client->snapshot_size < CSS_MIN_CLIENT_SNAPSHOT_SIZE) { | ||
193 | ret = -ENOMEM; | ||
194 | goto err_put; | ||
195 | } | ||
196 | |||
197 | client->snapshot = (struct gk20a_cs_snapshot_fifo *) | ||
198 | dma_buf_vmap(client_linux->dma_handler); | ||
199 | if (!client->snapshot) { | ||
200 | ret = -ENOMEM; | ||
201 | goto err_put; | ||
202 | } | ||
203 | |||
204 | ch->cs_client = client; | ||
205 | |||
206 | ret = gr_gk20a_css_attach(ch, | ||
207 | perfmon_id_count, | ||
208 | perfmon_id_start, | ||
209 | ch->cs_client); | ||
210 | |||
211 | nvgpu_mutex_release(&ch->cs_client_mutex); | ||
212 | |||
213 | return ret; | ||
214 | |||
215 | err_put: | ||
216 | dma_buf_put(client_linux->dma_handler); | ||
217 | err_free: | ||
218 | nvgpu_kfree(g, client_linux); | ||
219 | err: | ||
220 | nvgpu_mutex_release(&ch->cs_client_mutex); | ||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | int gk20a_channel_free_cycle_stats_snapshot(struct channel_gk20a *ch) | ||
225 | { | ||
226 | int ret; | ||
227 | struct gk20a_cs_snapshot_client_linux *client_linux; | ||
228 | |||
229 | nvgpu_mutex_acquire(&ch->cs_client_mutex); | ||
230 | if (!ch->cs_client) { | ||
231 | nvgpu_mutex_release(&ch->cs_client_mutex); | ||
232 | return 0; | ||
171 | } | 233 | } |
234 | |||
235 | client_linux = container_of(ch->cs_client, | ||
236 | struct gk20a_cs_snapshot_client_linux, | ||
237 | cs_client); | ||
238 | |||
239 | ret = gr_gk20a_css_detach(ch, ch->cs_client); | ||
240 | |||
241 | if (client_linux->dma_handler) { | ||
242 | if (ch->cs_client->snapshot) | ||
243 | dma_buf_vunmap(client_linux->dma_handler, | ||
244 | ch->cs_client->snapshot); | ||
245 | dma_buf_put(client_linux->dma_handler); | ||
246 | } | ||
247 | |||
248 | ch->cs_client = NULL; | ||
249 | nvgpu_kfree(ch->g, client_linux); | ||
250 | |||
172 | nvgpu_mutex_release(&ch->cs_client_mutex); | 251 | nvgpu_mutex_release(&ch->cs_client_mutex); |
173 | 252 | ||
174 | return ret; | 253 | return ret; |
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_channel.h b/drivers/gpu/nvgpu/common/linux/ioctl_channel.h index 235d84ef..3ea8d765 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_channel.h +++ b/drivers/gpu/nvgpu/common/linux/ioctl_channel.h | |||
@@ -15,11 +15,20 @@ | |||
15 | 15 | ||
16 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | 17 | ||
18 | #include "gk20a/css_gr_gk20a.h" | ||
19 | |||
18 | struct inode; | 20 | struct inode; |
19 | struct file; | 21 | struct file; |
20 | struct gk20a; | 22 | struct gk20a; |
21 | struct nvgpu_channel_open_args; | 23 | struct nvgpu_channel_open_args; |
22 | 24 | ||
25 | struct gk20a_cs_snapshot_client_linux { | ||
26 | struct gk20a_cs_snapshot_client cs_client; | ||
27 | |||
28 | u32 dmabuf_fd; | ||
29 | struct dma_buf *dma_handler; | ||
30 | }; | ||
31 | |||
23 | int gk20a_channel_open(struct inode *inode, struct file *filp); | 32 | int gk20a_channel_open(struct inode *inode, struct file *filp); |
24 | int gk20a_channel_release(struct inode *inode, struct file *filp); | 33 | int gk20a_channel_release(struct inode *inode, struct file *filp); |
25 | long gk20a_channel_ioctl(struct file *filp, | 34 | long gk20a_channel_ioctl(struct file *filp, |
@@ -27,6 +36,8 @@ long gk20a_channel_ioctl(struct file *filp, | |||
27 | int gk20a_channel_open_ioctl(struct gk20a *g, | 36 | int gk20a_channel_open_ioctl(struct gk20a *g, |
28 | struct nvgpu_channel_open_args *args); | 37 | struct nvgpu_channel_open_args *args); |
29 | 38 | ||
39 | int gk20a_channel_free_cycle_stats_snapshot(struct channel_gk20a *ch); | ||
40 | |||
30 | extern const struct file_operations gk20a_event_id_ops; | 41 | extern const struct file_operations gk20a_event_id_ops; |
31 | extern const struct file_operations gk20a_channel_ops; | 42 | extern const struct file_operations gk20a_channel_ops; |
32 | 43 | ||