1 /*
2 * Copyright 2012 Red Hat Inc.
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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24 #define nv50_instmem(p) container_of((p), struct nv50_instmem, base)
25 #include "priv.h"
26
27 #include <core/memory.h>
28 #include <subdev/bar.h>
29 #include <subdev/fb.h>
30 #include <subdev/gsp.h>
31 #include <subdev/mmu.h>
32
33 #include <linux/io-mapping.h>
34
35 struct nv50_instmem {
36 struct nvkm_instmem base;
37 u64 addr;
38
39 struct io_mapping iomap;
40
41 /* Mappings that can be evicted when BAR2 space has been exhausted. */
42 struct list_head lru;
43 };
44
45 /******************************************************************************
46 * instmem object implementation
47 *****************************************************************************/
48 #define nv50_instobj(p) container_of((p), struct nv50_instobj, base.memory)
49
50 struct nv50_instobj {
51 struct nvkm_instobj base;
52 struct nv50_instmem *imem;
53 struct nvkm_memory *ram;
54 struct nvkm_vma *bar;
55 refcount_t maps;
56 void *map;
57 struct list_head lru;
58 };
59
60 static void
nv50_instobj_wr32_slow(struct nvkm_memory * memory,u64 offset,u32 data)61 nv50_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data)
62 {
63 struct nv50_instobj *iobj = nv50_instobj(memory);
64 struct nv50_instmem *imem = iobj->imem;
65 struct nvkm_device *device = imem->base.subdev.device;
66 u64 base = (nvkm_memory_addr(iobj->ram) + offset) & 0xffffff00000ULL;
67 u64 addr = (nvkm_memory_addr(iobj->ram) + offset) & 0x000000fffffULL;
68 unsigned long flags;
69
70 spin_lock_irqsave(&imem->base.lock, flags);
71 if (unlikely(imem->addr != base)) {
72 imem->base.func->set_bar0_window_addr(device, base);
73 imem->addr = base;
74 }
75 nvkm_wr32(device, 0x700000 + addr, data);
76 spin_unlock_irqrestore(&imem->base.lock, flags);
77 }
78
79 static u32
nv50_instobj_rd32_slow(struct nvkm_memory * memory,u64 offset)80 nv50_instobj_rd32_slow(struct nvkm_memory *memory, u64 offset)
81 {
82 struct nv50_instobj *iobj = nv50_instobj(memory);
83 struct nv50_instmem *imem = iobj->imem;
84 struct nvkm_device *device = imem->base.subdev.device;
85 u64 base = (nvkm_memory_addr(iobj->ram) + offset) & 0xffffff00000ULL;
86 u64 addr = (nvkm_memory_addr(iobj->ram) + offset) & 0x000000fffffULL;
87 u32 data;
88 unsigned long flags;
89
90 spin_lock_irqsave(&imem->base.lock, flags);
91 if (unlikely(imem->addr != base)) {
92 imem->base.func->set_bar0_window_addr(device, base);
93 imem->addr = base;
94 }
95 data = nvkm_rd32(device, 0x700000 + addr);
96 spin_unlock_irqrestore(&imem->base.lock, flags);
97 return data;
98 }
99
100 static const struct nvkm_memory_ptrs
101 nv50_instobj_slow = {
102 .rd32 = nv50_instobj_rd32_slow,
103 .wr32 = nv50_instobj_wr32_slow,
104 };
105
106 static void
nv50_instobj_wr32(struct nvkm_memory * memory,u64 offset,u32 data)107 nv50_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
108 {
109 iowrite32_native(data, nv50_instobj(memory)->map + offset);
110 }
111
112 static u32
nv50_instobj_rd32(struct nvkm_memory * memory,u64 offset)113 nv50_instobj_rd32(struct nvkm_memory *memory, u64 offset)
114 {
115 return ioread32_native(nv50_instobj(memory)->map + offset);
116 }
117
118 static const struct nvkm_memory_ptrs
119 nv50_instobj_fast = {
120 .rd32 = nv50_instobj_rd32,
121 .wr32 = nv50_instobj_wr32,
122 };
123
124 static void
nv50_instobj_kmap(struct nv50_instobj * iobj,struct nvkm_vmm * vmm)125 nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm)
126 {
127 struct nv50_instmem *imem = iobj->imem;
128 struct nv50_instobj *eobj;
129 struct nvkm_memory *memory = &iobj->base.memory;
130 struct nvkm_subdev *subdev = &imem->base.subdev;
131 struct nvkm_vma *bar = NULL, *ebar;
132 u64 size = nvkm_memory_size(memory);
133 void *emap;
134 int ret;
135
136 /* Attempt to allocate BAR2 address-space and map the object
137 * into it. The lock has to be dropped while doing this due
138 * to the possibility of recursion for page table allocation.
139 */
140 mutex_unlock(&imem->base.mutex);
141 while ((ret = nvkm_vmm_get(vmm, 12, size, &bar))) {
142 /* Evict unused mappings, and keep retrying until we either
143 * succeed,or there's no more objects left on the LRU.
144 */
145 mutex_lock(&imem->base.mutex);
146 eobj = list_first_entry_or_null(&imem->lru, typeof(*eobj), lru);
147 if (eobj) {
148 nvkm_debug(subdev, "evict %016llx %016llx @ %016llx\n",
149 nvkm_memory_addr(&eobj->base.memory),
150 nvkm_memory_size(&eobj->base.memory),
151 eobj->bar->addr);
152 list_del_init(&eobj->lru);
153 ebar = eobj->bar;
154 eobj->bar = NULL;
155 emap = eobj->map;
156 eobj->map = NULL;
157 }
158 mutex_unlock(&imem->base.mutex);
159 if (!eobj)
160 break;
161 io_mapping_unmap(emap);
162 nvkm_vmm_put(vmm, &ebar);
163 }
164
165 if (ret == 0)
166 ret = nvkm_memory_map(memory, 0, vmm, bar, NULL, 0);
167 mutex_lock(&imem->base.mutex);
168 if (ret || iobj->bar) {
169 /* We either failed, or another thread beat us. */
170 mutex_unlock(&imem->base.mutex);
171 nvkm_vmm_put(vmm, &bar);
172 mutex_lock(&imem->base.mutex);
173 return;
174 }
175
176 /* Make the mapping visible to the host. */
177 iobj->bar = bar;
178 iobj->map = io_mapping_map_wc(&imem->iomap, (u32)iobj->bar->addr, size);
179 if (!iobj->map) {
180 nvkm_warn(subdev, "PRAMIN ioremap failed\n");
181 nvkm_vmm_put(vmm, &iobj->bar);
182 }
183 }
184
185 static int
nv50_instobj_map(struct nvkm_memory * memory,u64 offset,struct nvkm_vmm * vmm,struct nvkm_vma * vma,void * argv,u32 argc)186 nv50_instobj_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm,
187 struct nvkm_vma *vma, void *argv, u32 argc)
188 {
189 memory = nv50_instobj(memory)->ram;
190 return nvkm_memory_map(memory, offset, vmm, vma, argv, argc);
191 }
192
193 static bool
check_io_mapping(struct nv50_instmem * imem)194 check_io_mapping(struct nv50_instmem *imem)
195 {
196 struct nvkm_device *device = imem->base.subdev.device;
197
198 if (imem->iomap.size)
199 return true;
200
201 return io_mapping_init_wc(&imem->iomap,
202 device->func->resource_addr(device, NVKM_BAR2_INST),
203 device->func->resource_size(device, NVKM_BAR2_INST)) != NULL;
204 }
205
206 static void
nv50_instobj_release(struct nvkm_memory * memory)207 nv50_instobj_release(struct nvkm_memory *memory)
208 {
209 struct nv50_instobj *iobj = nv50_instobj(memory);
210 struct nv50_instmem *imem = iobj->imem;
211 struct nvkm_subdev *subdev = &imem->base.subdev;
212
213 wmb();
214 nvkm_bar_flush(subdev->device->bar);
215
216 if (refcount_dec_and_mutex_lock(&iobj->maps, &imem->base.mutex)) {
217 /* Add the now-unused mapping to the LRU instead of directly
218 * unmapping it here, in case we need to map it again later.
219 */
220 if (likely(iobj->lru.next) && iobj->map) {
221 BUG_ON(!list_empty(&iobj->lru));
222 list_add_tail(&iobj->lru, &imem->lru);
223 }
224
225 /* Switch back to NULL accessors when last map is gone. */
226 iobj->base.memory.ptrs = NULL;
227 mutex_unlock(&imem->base.mutex);
228 }
229 }
230
231 static void __iomem *
nv50_instobj_acquire(struct nvkm_memory * memory)232 nv50_instobj_acquire(struct nvkm_memory *memory)
233 {
234 struct nv50_instobj *iobj = nv50_instobj(memory);
235 struct nvkm_instmem *imem = &iobj->imem->base;
236 struct nvkm_vmm *vmm;
237 void __iomem *map = NULL;
238
239 /* Already mapped? */
240 if (refcount_inc_not_zero(&iobj->maps)) {
241 /* read barrier match the wmb on refcount set */
242 smp_rmb();
243 return iobj->map;
244 }
245
246 /* Take the lock, and re-check that another thread hasn't
247 * already mapped the object in the meantime.
248 */
249 mutex_lock(&imem->mutex);
250 if (refcount_inc_not_zero(&iobj->maps)) {
251 mutex_unlock(&imem->mutex);
252 return iobj->map;
253 }
254
255 /* Attempt to get a direct CPU mapping of the object. */
256 if ((vmm = nvkm_bar_bar2_vmm(imem->subdev.device))) {
257 if (!iobj->map && iobj->imem->iomap.size)
258 nv50_instobj_kmap(iobj, vmm);
259 map = iobj->map;
260 }
261
262 if (!refcount_inc_not_zero(&iobj->maps)) {
263 /* Exclude object from eviction while it's being accessed. */
264 if (likely(iobj->lru.next))
265 list_del_init(&iobj->lru);
266
267 if (map)
268 iobj->base.memory.ptrs = &nv50_instobj_fast;
269 else
270 iobj->base.memory.ptrs = &nv50_instobj_slow;
271 /* barrier to ensure the ptrs are written before refcount is set */
272 smp_wmb();
273 refcount_set(&iobj->maps, 1);
274 }
275
276 mutex_unlock(&imem->mutex);
277 return map;
278 }
279
280 static void
nv50_instobj_boot(struct nvkm_memory * memory,struct nvkm_vmm * vmm)281 nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vmm *vmm)
282 {
283 struct nv50_instobj *iobj = nv50_instobj(memory);
284 struct nvkm_instmem *imem = &iobj->imem->base;
285
286 /* Exclude bootstrapped objects (ie. the page tables for the
287 * instmem BAR itself) from eviction.
288 */
289 mutex_lock(&imem->mutex);
290 if (likely(iobj->lru.next)) {
291 list_del_init(&iobj->lru);
292 iobj->lru.next = NULL;
293 }
294
295 /*
296 * boot is only called on BAR2, if we can't remap the complete
297 * BAR it's unlikely things are functioning well.
298 */
299 if (check_io_mapping(iobj->imem))
300 nv50_instobj_kmap(iobj, vmm);
301 nvkm_instmem_boot(imem);
302 mutex_unlock(&imem->mutex);
303 }
304
305 static u64
nv50_instobj_size(struct nvkm_memory * memory)306 nv50_instobj_size(struct nvkm_memory *memory)
307 {
308 return nvkm_memory_size(nv50_instobj(memory)->ram);
309 }
310
311 static u64
nv50_instobj_addr(struct nvkm_memory * memory)312 nv50_instobj_addr(struct nvkm_memory *memory)
313 {
314 return nvkm_memory_addr(nv50_instobj(memory)->ram);
315 }
316
317 static u64
nv50_instobj_bar2(struct nvkm_memory * memory)318 nv50_instobj_bar2(struct nvkm_memory *memory)
319 {
320 struct nv50_instobj *iobj = nv50_instobj(memory);
321 u64 addr = ~0ULL;
322 if (nv50_instobj_acquire(&iobj->base.memory)) {
323 iobj->lru.next = NULL; /* Exclude from eviction. */
324 addr = iobj->bar->addr;
325 }
326 nv50_instobj_release(&iobj->base.memory);
327 return addr;
328 }
329
330 static enum nvkm_memory_target
nv50_instobj_target(struct nvkm_memory * memory)331 nv50_instobj_target(struct nvkm_memory *memory)
332 {
333 return nvkm_memory_target(nv50_instobj(memory)->ram);
334 }
335
336 static void *
nv50_instobj_dtor(struct nvkm_memory * memory)337 nv50_instobj_dtor(struct nvkm_memory *memory)
338 {
339 struct nv50_instobj *iobj = nv50_instobj(memory);
340 struct nvkm_instmem *imem = &iobj->imem->base;
341 struct nvkm_vma *bar;
342 void *map;
343
344 mutex_lock(&imem->mutex);
345 if (likely(iobj->lru.next))
346 list_del(&iobj->lru);
347 map = iobj->map;
348 bar = iobj->bar;
349 mutex_unlock(&imem->mutex);
350
351 if (map) {
352 struct nvkm_vmm *vmm = nvkm_bar_bar2_vmm(imem->subdev.device);
353 io_mapping_unmap(map);
354 if (likely(vmm)) /* Can be NULL during BAR destructor. */
355 nvkm_vmm_put(vmm, &bar);
356 }
357
358 nvkm_memory_unref(&iobj->ram);
359 nvkm_instobj_dtor(imem, &iobj->base);
360 return iobj;
361 }
362
363 static const struct nvkm_memory_func
364 nv50_instobj_func = {
365 .dtor = nv50_instobj_dtor,
366 .target = nv50_instobj_target,
367 .bar2 = nv50_instobj_bar2,
368 .addr = nv50_instobj_addr,
369 .size = nv50_instobj_size,
370 .boot = nv50_instobj_boot,
371 .acquire = nv50_instobj_acquire,
372 .release = nv50_instobj_release,
373 .map = nv50_instobj_map,
374 };
375
376 int
nv50_instobj_wrap(struct nvkm_instmem * base,struct nvkm_memory * memory,struct nvkm_memory ** pmemory)377 nv50_instobj_wrap(struct nvkm_instmem *base,
378 struct nvkm_memory *memory, struct nvkm_memory **pmemory)
379 {
380 struct nv50_instmem *imem = nv50_instmem(base);
381 struct nv50_instobj *iobj;
382
383 if (!(iobj = kzalloc_obj(*iobj)))
384 return -ENOMEM;
385 *pmemory = &iobj->base.memory;
386
387 nvkm_instobj_ctor(&nv50_instobj_func, &imem->base, &iobj->base);
388 iobj->imem = imem;
389 refcount_set(&iobj->maps, 0);
390 INIT_LIST_HEAD(&iobj->lru);
391
392 iobj->ram = nvkm_memory_ref(memory);
393 return 0;
394 }
395
396 int
nv50_instobj_new(struct nvkm_instmem * imem,u32 size,u32 align,bool zero,struct nvkm_memory ** pmemory)397 nv50_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
398 struct nvkm_memory **pmemory)
399 {
400 u8 page = max(order_base_2(align), 12);
401 struct nvkm_memory *ram;
402 int ret;
403
404 ret = nvkm_ram_get(imem->subdev.device, 0, 1, page, size, true, true, &ram);
405 if (ret)
406 return ret;
407
408 ret = nv50_instobj_wrap(imem, ram, pmemory);
409 nvkm_memory_unref(&ram);
410 return ret;
411 }
412
413 /******************************************************************************
414 * instmem subdev implementation
415 *****************************************************************************/
416
417 static void
nv50_instmem_set_bar0_window_addr(struct nvkm_device * device,u64 addr)418 nv50_instmem_set_bar0_window_addr(struct nvkm_device *device, u64 addr)
419 {
420 nvkm_wr32(device, 0x001700, addr >> 16);
421 }
422
423 void
nv50_instmem_fini(struct nvkm_instmem * base)424 nv50_instmem_fini(struct nvkm_instmem *base)
425 {
426 nv50_instmem(base)->addr = ~0ULL;
427 }
428
429 void *
nv50_instmem_dtor(struct nvkm_instmem * base)430 nv50_instmem_dtor(struct nvkm_instmem *base)
431 {
432 struct nv50_instmem *imem = nv50_instmem(base);
433
434 if (imem->iomap.size)
435 io_mapping_fini(&imem->iomap);
436 return imem;
437 }
438
439 static const struct nvkm_instmem_func
440 nv50_instmem = {
441 .dtor = nv50_instmem_dtor,
442 .fini = nv50_instmem_fini,
443 .suspend = nv04_instmem_suspend,
444 .resume = nv04_instmem_resume,
445 .memory_new = nv50_instobj_new,
446 .memory_wrap = nv50_instobj_wrap,
447 .zero = false,
448 .set_bar0_window_addr = nv50_instmem_set_bar0_window_addr,
449 };
450
451 int
nv50_instmem_new_(const struct nvkm_instmem_func * func,struct nvkm_device * device,enum nvkm_subdev_type type,int inst,struct nvkm_instmem ** pimem)452 nv50_instmem_new_(const struct nvkm_instmem_func *func,
453 struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
454 struct nvkm_instmem **pimem)
455 {
456 struct nv50_instmem *imem;
457
458 if (!(imem = kzalloc_obj(*imem)))
459 return -ENOMEM;
460 nvkm_instmem_ctor(func, device, type, inst, &imem->base);
461 INIT_LIST_HEAD(&imem->lru);
462 *pimem = &imem->base;
463 return 0;
464 }
465
466 int
nv50_instmem_new(struct nvkm_device * device,enum nvkm_subdev_type type,int inst,struct nvkm_instmem ** pimem)467 nv50_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
468 struct nvkm_instmem **pimem)
469 {
470 if (nvkm_gsp_rm(device->gsp))
471 return r535_instmem_new(&nv50_instmem, device, type, inst, pimem);
472
473 return nv50_instmem_new_(&nv50_instmem, device, type, inst, pimem);
474 }
475