aboutsummaryrefslogtreecommitdiffstats
path: root/include/gk20a/mm_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'include/gk20a/mm_gk20a.c')
-rw-r--r--include/gk20a/mm_gk20a.c654
1 files changed, 0 insertions, 654 deletions
diff --git a/include/gk20a/mm_gk20a.c b/include/gk20a/mm_gk20a.c
deleted file mode 100644
index 10ca84d..0000000
--- a/include/gk20a/mm_gk20a.c
+++ /dev/null
@@ -1,654 +0,0 @@
1/*
2 * Copyright (c) 2011-2020, 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 <trace/events/gk20a.h>
24
25#include <nvgpu/mm.h>
26#include <nvgpu/vm.h>
27#include <nvgpu/vm_area.h>
28#include <nvgpu/dma.h>
29#include <nvgpu/kmem.h>
30#include <nvgpu/timers.h>
31#include <nvgpu/pramin.h>
32#include <nvgpu/list.h>
33#include <nvgpu/nvgpu_mem.h>
34#include <nvgpu/allocator.h>
35#include <nvgpu/semaphore.h>
36#include <nvgpu/page_allocator.h>
37#include <nvgpu/log.h>
38#include <nvgpu/bug.h>
39#include <nvgpu/log2.h>
40#include <nvgpu/enabled.h>
41#include <nvgpu/vidmem.h>
42#include <nvgpu/sizes.h>
43#include <nvgpu/io.h>
44#include <nvgpu/utils.h>
45#include <nvgpu/channel.h>
46
47#include "gk20a.h"
48#include "mm_gk20a.h"
49#include "fence_gk20a.h"
50
51#include <nvgpu/hw/gk20a/hw_gmmu_gk20a.h>
52#include <nvgpu/hw/gk20a/hw_ram_gk20a.h>
53#include <nvgpu/hw/gk20a/hw_pram_gk20a.h>
54#include <nvgpu/hw/gk20a/hw_flush_gk20a.h>
55
56/*
57 * GPU mapping life cycle
58 * ======================
59 *
60 * Kernel mappings
61 * ---------------
62 *
63 * Kernel mappings are created through vm.map(..., false):
64 *
65 * - Mappings to the same allocations are reused and refcounted.
66 * - This path does not support deferred unmapping (i.e. kernel must wait for
67 * all hw operations on the buffer to complete before unmapping).
68 * - References to dmabuf are owned and managed by the (kernel) clients of
69 * the gk20a_vm layer.
70 *
71 *
72 * User space mappings
73 * -------------------
74 *
75 * User space mappings are created through as.map_buffer -> vm.map(..., true):
76 *
77 * - Mappings to the same allocations are reused and refcounted.
78 * - This path supports deferred unmapping (i.e. we delay the actual unmapping
79 * until all hw operations have completed).
80 * - References to dmabuf are owned and managed by the vm_gk20a
81 * layer itself. vm.map acquires these refs, and sets
82 * mapped_buffer->own_mem_ref to record that we must release the refs when we
83 * actually unmap.
84 *
85 */
86
87/* make sure gk20a_init_mm_support is called before */
88int gk20a_init_mm_setup_hw(struct gk20a *g)
89{
90 struct mm_gk20a *mm = &g->mm;
91 int err;
92
93 nvgpu_log_fn(g, " ");
94
95 if (g->ops.fb.set_mmu_page_size) {
96 g->ops.fb.set_mmu_page_size(g);
97 }
98
99 if (g->ops.fb.set_use_full_comp_tag_line) {
100 mm->use_full_comp_tag_line =
101 g->ops.fb.set_use_full_comp_tag_line(g);
102 }
103
104 g->ops.fb.init_hw(g);
105
106 if (g->ops.bus.bar1_bind) {
107 g->ops.bus.bar1_bind(g, &mm->bar1.inst_block);
108 }
109
110 if (g->ops.bus.bar2_bind) {
111 err = g->ops.bus.bar2_bind(g, &mm->bar2.inst_block);
112 if (err) {
113 return err;
114 }
115 }
116
117 if (gk20a_mm_fb_flush(g) || gk20a_mm_fb_flush(g)) {
118 return -EBUSY;
119 }
120
121 nvgpu_log_fn(g, "done");
122 return 0;
123}
124
125/* for gk20a the "video memory" apertures here are misnomers. */
126static inline u32 big_valid_pde0_bits(struct gk20a *g,
127 struct nvgpu_gmmu_pd *pd, u64 addr)
128{
129 u32 pde0_bits =
130 nvgpu_aperture_mask(g, pd->mem,
131 gmmu_pde_aperture_big_sys_mem_ncoh_f(),
132 gmmu_pde_aperture_big_sys_mem_coh_f(),
133 gmmu_pde_aperture_big_video_memory_f()) |
134 gmmu_pde_address_big_sys_f(
135 (u32)(addr >> gmmu_pde_address_shift_v()));
136
137 return pde0_bits;
138}
139
140static inline u32 small_valid_pde1_bits(struct gk20a *g,
141 struct nvgpu_gmmu_pd *pd, u64 addr)
142{
143 u32 pde1_bits =
144 nvgpu_aperture_mask(g, pd->mem,
145 gmmu_pde_aperture_small_sys_mem_ncoh_f(),
146 gmmu_pde_aperture_small_sys_mem_coh_f(),
147 gmmu_pde_aperture_small_video_memory_f()) |
148 gmmu_pde_vol_small_true_f() | /* tbd: why? */
149 gmmu_pde_address_small_sys_f(
150 (u32)(addr >> gmmu_pde_address_shift_v()));
151
152 return pde1_bits;
153}
154
155static void update_gmmu_pde_locked(struct vm_gk20a *vm,
156 const struct gk20a_mmu_level *l,
157 struct nvgpu_gmmu_pd *pd,
158 u32 pd_idx,
159 u64 virt_addr,
160 u64 phys_addr,
161 struct nvgpu_gmmu_attrs *attrs)
162{
163 struct gk20a *g = gk20a_from_vm(vm);
164 bool small_valid, big_valid;
165 u32 pd_offset = pd_offset_from_index(l, pd_idx);
166 u32 pde_v[2] = {0, 0};
167
168 small_valid = attrs->pgsz == GMMU_PAGE_SIZE_SMALL;
169 big_valid = attrs->pgsz == GMMU_PAGE_SIZE_BIG;
170
171 pde_v[0] = gmmu_pde_size_full_f();
172 pde_v[0] |= big_valid ?
173 big_valid_pde0_bits(g, pd, phys_addr) :
174 gmmu_pde_aperture_big_invalid_f();
175
176 pde_v[1] |= (small_valid ? small_valid_pde1_bits(g, pd, phys_addr) :
177 (gmmu_pde_aperture_small_invalid_f() |
178 gmmu_pde_vol_small_false_f()))
179 |
180 (big_valid ? (gmmu_pde_vol_big_true_f()) :
181 gmmu_pde_vol_big_false_f());
182
183 pte_dbg(g, attrs,
184 "PDE: i=%-4u size=%-2u offs=%-4u pgsz: %c%c | "
185 "GPU %#-12llx phys %#-12llx "
186 "[0x%08x, 0x%08x]",
187 pd_idx, l->entry_size, pd_offset,
188 small_valid ? 'S' : '-',
189 big_valid ? 'B' : '-',
190 virt_addr, phys_addr,
191 pde_v[1], pde_v[0]);
192
193 pd_write(g, &vm->pdb, pd_offset + 0, pde_v[0]);
194 pd_write(g, &vm->pdb, pd_offset + 1, pde_v[1]);
195}
196
197static void __update_pte_sparse(u32 *pte_w)
198{
199 pte_w[0] = gmmu_pte_valid_false_f();
200 pte_w[1] |= gmmu_pte_vol_true_f();
201}
202
203static void __update_pte(struct vm_gk20a *vm,
204 u32 *pte_w,
205 u64 phys_addr,
206 struct nvgpu_gmmu_attrs *attrs)
207{
208 struct gk20a *g = gk20a_from_vm(vm);
209 u32 page_size = vm->gmmu_page_sizes[attrs->pgsz];
210 u32 pte_valid = attrs->valid ?
211 gmmu_pte_valid_true_f() :
212 gmmu_pte_valid_false_f();
213 u32 phys_shifted = phys_addr >> gmmu_pte_address_shift_v();
214 u32 addr = attrs->aperture == APERTURE_SYSMEM ?
215 gmmu_pte_address_sys_f(phys_shifted) :
216 gmmu_pte_address_vid_f(phys_shifted);
217 int ctag_shift = ilog2(g->ops.fb.compression_page_size(g));
218
219 pte_w[0] = pte_valid | addr;
220
221 if (attrs->priv) {
222 pte_w[0] |= gmmu_pte_privilege_true_f();
223 }
224