summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/vgpu/mm_vgpu.c
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2017-11-14 09:43:28 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-11-17 11:27:19 -0500
commitb42fb7ba26b565f93118fbdd9e17b42ee6144c5e (patch)
tree26e2d919f019d15b51bba4d7b5c938f77ad5cff5 /drivers/gpu/nvgpu/vgpu/mm_vgpu.c
parentb7cc3a2aa6c92a09eed43513287c9062f22ad127 (diff)
gpu: nvgpu: move vgpu code to linux
Most of VGPU code is linux specific but lies in common code So until VGPU code is properly abstracted and made os-independent, move all of VGPU code to linux specific directory Handle corresponding Makefile changes Update all #includes to reflect new paths Add GPL license to newly added linux files Jira NVGPU-387 Change-Id: Ic133e4c80e570bcc273f0dacf45283fefd678923 Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1599472 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/vgpu/mm_vgpu.c')
-rw-r--r--drivers/gpu/nvgpu/vgpu/mm_vgpu.c369
1 files changed, 0 insertions, 369 deletions
diff --git a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c
deleted file mode 100644
index 79d15d10..00000000
--- a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c
+++ /dev/null
@@ -1,369 +0,0 @@
1/*
2 * Virtualized GPU Memory Management
3 *
4 * Copyright (c) 2014-2017, 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 <linux/dma-mapping.h>
26#include <uapi/linux/nvgpu.h>
27
28#include <nvgpu/kmem.h>
29#include <nvgpu/dma.h>
30#include <nvgpu/bug.h>
31#include <nvgpu/vm.h>
32#include <nvgpu/vm_area.h>
33
34#include <nvgpu/vgpu/vm.h>
35
36#include <nvgpu/linux/vm.h>
37#include <nvgpu/linux/nvgpu_mem.h>
38
39#include "vgpu/vgpu.h"
40#include "vgpu/mm_vgpu.h"
41#include "gk20a/mm_gk20a.h"
42#include "gm20b/mm_gm20b.h"
43
44static int vgpu_init_mm_setup_sw(struct gk20a *g)
45{
46 struct mm_gk20a *mm = &g->mm;
47
48 gk20a_dbg_fn("");
49
50 if (mm->sw_ready) {
51 gk20a_dbg_fn("skip init");
52 return 0;
53 }
54
55 nvgpu_mutex_init(&mm->tlb_lock);
56 nvgpu_mutex_init(&mm->priv_lock);
57
58 mm->g = g;
59
60 /*TBD: make channel vm size configurable */
61 mm->channel.user_size = NV_MM_DEFAULT_USER_SIZE;
62 mm->channel.kernel_size = NV_MM_DEFAULT_KERNEL_SIZE;
63
64 gk20a_dbg_info("channel vm size: user %dMB kernel %dMB",
65 (int)(mm->channel.user_size >> 20),
66 (int)(mm->channel.kernel_size >> 20));
67
68 mm->sw_ready = true;
69
70 return 0;
71}
72
73int vgpu_init_mm_support(struct gk20a *g)
74{
75 int err;
76
77 gk20a_dbg_fn("");
78
79 err = vgpu_init_mm_setup_sw(g);
80 if (err)
81 return err;
82
83 if (g->ops.mm.init_mm_setup_hw)
84 err = g->ops.mm.init_mm_setup_hw(g);
85
86 return err;
87}
88
89u64 vgpu_locked_gmmu_map(struct vm_gk20a *vm,
90 u64 map_offset,
91 struct nvgpu_sgt *sgt,
92 u64 buffer_offset,
93 u64 size,
94 int pgsz_idx,
95 u8 kind_v,
96 u32 ctag_offset,
97 u32 flags,
98 int rw_flag,
99 bool clear_ctags,
100 bool sparse,
101 bool priv,
102 struct vm_gk20a_mapping_batch *batch,
103 enum nvgpu_aperture aperture)
104{
105 int err = 0;
106 struct device *d = dev_from_vm(vm);
107 struct gk20a *g = gk20a_from_vm(vm);
108 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(d);
109 struct tegra_vgpu_cmd_msg msg;
110 struct tegra_vgpu_as_map_params *p = &msg.params.as_map;
111 u64 addr = nvgpu_sgt_get_gpu_addr(g, sgt, sgt->sgl, NULL);
112 u8 prot;
113
114 gk20a_dbg_fn("");
115
116 /* Allocate (or validate when map_offset != 0) the virtual address. */
117 if (!map_offset) {
118 map_offset = __nvgpu_vm_alloc_va(vm, size,
119 pgsz_idx);
120 if (!map_offset) {
121 nvgpu_err(g, "failed to allocate va space");
122 err = -ENOMEM;
123 goto fail;
124 }
125 }
126
127 if (rw_flag == gk20a_mem_flag_read_only)
128 prot = TEGRA_VGPU_MAP_PROT_READ_ONLY;
129 else if (rw_flag == gk20a_mem_flag_write_only)
130 prot = TEGRA_VGPU_MAP_PROT_WRITE_ONLY;
131 else
132 prot = TEGRA_VGPU_MAP_PROT_NONE;
133
134 msg.cmd = TEGRA_VGPU_CMD_AS_MAP;
135 msg.handle = vgpu_get_handle(g);
136 p->handle = vm->handle;
137 p->addr = addr;
138 p->gpu_va = map_offset;
139 p->size = size;
140 if (pgsz_idx == gmmu_page_size_kernel) {
141 u32 page_size = vm->gmmu_page_sizes[pgsz_idx];
142
143 if (page_size == vm->gmmu_page_sizes[gmmu_page_size_small]) {
144 pgsz_idx = gmmu_page_size_small;
145 } else if (page_size ==
146 vm->gmmu_page_sizes[gmmu_page_size_big]) {
147 pgsz_idx = gmmu_page_size_big;
148 } else {
149 nvgpu_err(g, "invalid kernel page size %d",
150 page_size);
151 goto fail;
152 }
153 }
154 p->pgsz_idx = pgsz_idx;
155 p->iova = mapping ? 1 : 0;
156 p->kind = kind_v;
157 p->cacheable = (flags & NVGPU_AS_MAP_BUFFER_FLAGS_CACHEABLE) ? 1 : 0;
158 p->prot = prot;
159 p->ctag_offset = ctag_offset;
160 p->clear_ctags = clear_ctags;
161 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
162 err = err ? err : msg.ret;
163 if (err)
164 goto fail;
165
166 /* TLB invalidate handled on server side */
167
168 return map_offset;
169fail:
170 nvgpu_err(g, "%s: failed with err=%d", __func__, err);
171 return 0;
172}
173
174void vgpu_locked_gmmu_unmap(struct vm_gk20a *vm,
175 u64 vaddr,
176 u64 size,
177 int pgsz_idx,
178 bool va_allocated,
179 int rw_flag,
180 bool sparse,
181 struct vm_gk20a_mapping_batch *batch)
182{
183 struct gk20a *g = gk20a_from_vm(vm);
184 struct tegra_vgpu_cmd_msg msg;
185 struct tegra_vgpu_as_map_params *p = &msg.params.as_map;
186 int err;
187
188 gk20a_dbg_fn("");
189
190 if (va_allocated) {
191 err = __nvgpu_vm_free_va(vm, vaddr, pgsz_idx);
192 if (err) {
193 dev_err(dev_from_vm(vm),
194 "failed to free va");
195 return;
196 }
197 }
198
199 msg.cmd = TEGRA_VGPU_CMD_AS_UNMAP;
200 msg.handle = vgpu_get_handle(g);
201 p->handle = vm->handle;
202 p->gpu_va = vaddr;
203 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
204 if (err || msg.ret)
205 dev_err(dev_from_vm(vm),
206 "failed to update gmmu ptes on unmap");
207
208 /* TLB invalidate handled on server side */
209}
210
211/*
212 * This is called by the common VM init routine to handle vGPU specifics of
213 * intializing a VM on a vGPU. This alone is not enough to init a VM. See
214 * nvgpu_vm_init().
215 */
216int vgpu_vm_init(struct gk20a *g, struct vm_gk20a *vm)
217{
218 struct tegra_vgpu_cmd_msg msg;
219 struct tegra_vgpu_as_share_params *p = &msg.params.as_share;
220 int err;
221
222 msg.cmd = TEGRA_VGPU_CMD_AS_ALLOC_SHARE;
223 msg.handle = vgpu_get_handle(g);
224 p->size = vm->va_limit;
225 p->big_page_size = vm->big_page_size;
226
227 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
228 if (err || msg.ret)
229 return -ENOMEM;
230
231 vm->handle = p->handle;
232
233 return 0;
234}
235
236/*
237 * Similar to vgpu_vm_init() this is called as part of the cleanup path for
238 * VMs. This alone is not enough to remove a VM - see nvgpu_vm_remove().
239 */
240void vgpu_vm_remove(struct vm_gk20a *vm)
241{
242 struct gk20a *g = gk20a_from_vm(vm);
243 struct tegra_vgpu_cmd_msg msg;
244 struct tegra_vgpu_as_share_params *p = &msg.params.as_share;
245 int err;
246
247 msg.cmd = TEGRA_VGPU_CMD_AS_FREE_SHARE;
248 msg.handle = vgpu_get_handle(g);
249 p->handle = vm->handle;
250 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
251 WARN_ON(err || msg.ret);
252}
253
254u64 vgpu_bar1_map(struct gk20a *g, struct sg_table **sgt, u64 size)
255{
256 struct dma_iommu_mapping *mapping =
257 to_dma_iommu_mapping(dev_from_gk20a(g));
258 u64 addr = nvgpu_mem_get_addr_sgl(g, (*sgt)->sgl);
259 struct tegra_vgpu_cmd_msg msg;
260 struct tegra_vgpu_as_map_params *p = &msg.params.as_map;
261 int err;
262
263 msg.cmd = TEGRA_VGPU_CMD_MAP_BAR1;
264 msg.handle = vgpu_get_handle(g);
265 p->addr = addr;
266 p->size = size;
267 p->iova = mapping ? 1 : 0;
268 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
269 if (err || msg.ret)
270 addr = 0;
271 else
272 addr = p->gpu_va;
273
274 return addr;
275}
276
277int vgpu_vm_bind_channel(struct gk20a_as_share *as_share,
278 struct channel_gk20a *ch)
279{
280 struct vm_gk20a *vm = as_share->vm;
281 struct tegra_vgpu_cmd_msg msg;
282 struct tegra_vgpu_as_bind_share_params *p = &msg.params.as_bind_share;
283 int err;
284
285 gk20a_dbg_fn("");
286
287 ch->vm = vm;
288 msg.cmd = TEGRA_VGPU_CMD_AS_BIND_SHARE;
289 msg.handle = vgpu_get_handle(ch->g);
290 p->as_handle = vm->handle;
291 p->chan_handle = ch->virt_ctx;
292 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
293
294 if (err || msg.ret) {
295 ch->vm = NULL;
296 err = -ENOMEM;
297 }
298
299 if (ch->vm)
300 nvgpu_vm_get(ch->vm);
301
302 return err;
303}
304
305static void vgpu_cache_maint(u64 handle, u8 op)
306{
307 struct tegra_vgpu_cmd_msg msg;
308 struct tegra_vgpu_cache_maint_params *p = &msg.params.cache_maint;
309 int err;
310
311 msg.cmd = TEGRA_VGPU_CMD_CACHE_MAINT;
312 msg.handle = handle;
313 p->op = op;
314 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
315 WARN_ON(err || msg.ret);
316}
317
318int vgpu_mm_fb_flush(struct gk20a *g)
319{
320
321 gk20a_dbg_fn("");
322
323 vgpu_cache_maint(vgpu_get_handle(g), TEGRA_VGPU_FB_FLUSH);
324 return 0;
325}
326
327void vgpu_mm_l2_invalidate(struct gk20a *g)
328{
329
330 gk20a_dbg_fn("");
331
332 vgpu_cache_maint(vgpu_get_handle(g), TEGRA_VGPU_L2_MAINT_INV);
333}
334
335void vgpu_mm_l2_flush(struct gk20a *g, bool invalidate)
336{
337 u8 op;
338
339 gk20a_dbg_fn("");
340
341 if (invalidate)
342 op = TEGRA_VGPU_L2_MAINT_FLUSH_INV;
343 else
344 op = TEGRA_VGPU_L2_MAINT_FLUSH;
345
346 vgpu_cache_maint(vgpu_get_handle(g), op);
347}
348
349void vgpu_mm_tlb_invalidate(struct gk20a *g, struct nvgpu_mem *pdb)
350{
351 gk20a_dbg_fn("");
352
353 nvgpu_err(g, "call to RM server not supported");
354}
355
356void vgpu_mm_mmu_set_debug_mode(struct gk20a *g, bool enable)
357{
358 struct tegra_vgpu_cmd_msg msg;
359 struct tegra_vgpu_mmu_debug_mode *p = &msg.params.mmu_debug_mode;
360 int err;
361
362 gk20a_dbg_fn("");
363
364 msg.cmd = TEGRA_VGPU_CMD_SET_MMU_DEBUG_MODE;
365 msg.handle = vgpu_get_handle(g);
366 p->enable = (u32)enable;
367 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
368 WARN_ON(err || msg.ret);
369}