Documentation: embargoed-hardware-issues.rst: Add myself for Power
[sfrench/cifs-2.6.git] / drivers / gpu / drm / vmwgfx / vmwgfx_ttm_buffer.c
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /**************************************************************************
3  *
4  * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27
28 #include "vmwgfx_bo.h"
29 #include "vmwgfx_drv.h"
30 #include <drm/ttm/ttm_placement.h>
31
32 static const struct ttm_place vram_placement_flags = {
33         .fpfn = 0,
34         .lpfn = 0,
35         .mem_type = TTM_PL_VRAM,
36         .flags = 0
37 };
38
39 static const struct ttm_place sys_placement_flags = {
40         .fpfn = 0,
41         .lpfn = 0,
42         .mem_type = TTM_PL_SYSTEM,
43         .flags = 0
44 };
45
46 struct ttm_placement vmw_vram_placement = {
47         .num_placement = 1,
48         .placement = &vram_placement_flags,
49 };
50
51 struct ttm_placement vmw_sys_placement = {
52         .num_placement = 1,
53         .placement = &sys_placement_flags,
54 };
55
56 const size_t vmw_tt_size = sizeof(struct vmw_ttm_tt);
57
58 /**
59  * __vmw_piter_non_sg_next: Helper functions to advance
60  * a struct vmw_piter iterator.
61  *
62  * @viter: Pointer to the iterator.
63  *
64  * These functions return false if past the end of the list,
65  * true otherwise. Functions are selected depending on the current
66  * DMA mapping mode.
67  */
68 static bool __vmw_piter_non_sg_next(struct vmw_piter *viter)
69 {
70         return ++(viter->i) < viter->num_pages;
71 }
72
73 static bool __vmw_piter_sg_next(struct vmw_piter *viter)
74 {
75         bool ret = __vmw_piter_non_sg_next(viter);
76
77         return __sg_page_iter_dma_next(&viter->iter) && ret;
78 }
79
80
81 static dma_addr_t __vmw_piter_dma_addr(struct vmw_piter *viter)
82 {
83         return viter->addrs[viter->i];
84 }
85
86 static dma_addr_t __vmw_piter_sg_addr(struct vmw_piter *viter)
87 {
88         return sg_page_iter_dma_address(&viter->iter);
89 }
90
91
92 /**
93  * vmw_piter_start - Initialize a struct vmw_piter.
94  *
95  * @viter: Pointer to the iterator to initialize
96  * @vsgt: Pointer to a struct vmw_sg_table to initialize from
97  * @p_offset: Pointer offset used to update current array position
98  *
99  * Note that we're following the convention of __sg_page_iter_start, so that
100  * the iterator doesn't point to a valid page after initialization; it has
101  * to be advanced one step first.
102  */
103 void vmw_piter_start(struct vmw_piter *viter, const struct vmw_sg_table *vsgt,
104                      unsigned long p_offset)
105 {
106         viter->i = p_offset - 1;
107         viter->num_pages = vsgt->num_pages;
108         viter->pages = vsgt->pages;
109         switch (vsgt->mode) {
110         case vmw_dma_alloc_coherent:
111                 viter->next = &__vmw_piter_non_sg_next;
112                 viter->dma_address = &__vmw_piter_dma_addr;
113                 viter->addrs = vsgt->addrs;
114                 break;
115         case vmw_dma_map_populate:
116         case vmw_dma_map_bind:
117                 viter->next = &__vmw_piter_sg_next;
118                 viter->dma_address = &__vmw_piter_sg_addr;
119                 __sg_page_iter_start(&viter->iter.base, vsgt->sgt->sgl,
120                                      vsgt->sgt->orig_nents, p_offset);
121                 break;
122         default:
123                 BUG();
124         }
125 }
126
127 /**
128  * vmw_ttm_unmap_from_dma - unmap  device addresses previsouly mapped for
129  * TTM pages
130  *
131  * @vmw_tt: Pointer to a struct vmw_ttm_backend
132  *
133  * Used to free dma mappings previously mapped by vmw_ttm_map_for_dma.
134  */
135 static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt)
136 {
137         struct device *dev = vmw_tt->dev_priv->drm.dev;
138
139         dma_unmap_sgtable(dev, &vmw_tt->sgt, DMA_BIDIRECTIONAL, 0);
140         vmw_tt->sgt.nents = vmw_tt->sgt.orig_nents;
141 }
142
143 /**
144  * vmw_ttm_map_for_dma - map TTM pages to get device addresses
145  *
146  * @vmw_tt: Pointer to a struct vmw_ttm_backend
147  *
148  * This function is used to get device addresses from the kernel DMA layer.
149  * However, it's violating the DMA API in that when this operation has been
150  * performed, it's illegal for the CPU to write to the pages without first
151  * unmapping the DMA mappings, or calling dma_sync_sg_for_cpu(). It is
152  * therefore only legal to call this function if we know that the function
153  * dma_sync_sg_for_cpu() is a NOP, and dma_sync_sg_for_device() is at most
154  * a CPU write buffer flush.
155  */
156 static int vmw_ttm_map_for_dma(struct vmw_ttm_tt *vmw_tt)
157 {
158         struct device *dev = vmw_tt->dev_priv->drm.dev;
159
160         return dma_map_sgtable(dev, &vmw_tt->sgt, DMA_BIDIRECTIONAL, 0);
161 }
162
163 /**
164  * vmw_ttm_map_dma - Make sure TTM pages are visible to the device
165  *
166  * @vmw_tt: Pointer to a struct vmw_ttm_tt
167  *
168  * Select the correct function for and make sure the TTM pages are
169  * visible to the device. Allocate storage for the device mappings.
170  * If a mapping has already been performed, indicated by the storage
171  * pointer being non NULL, the function returns success.
172  */
173 static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
174 {
175         struct vmw_private *dev_priv = vmw_tt->dev_priv;
176         struct vmw_sg_table *vsgt = &vmw_tt->vsgt;
177         int ret = 0;
178
179         if (vmw_tt->mapped)
180                 return 0;
181
182         vsgt->mode = dev_priv->map_mode;
183         vsgt->pages = vmw_tt->dma_ttm.pages;
184         vsgt->num_pages = vmw_tt->dma_ttm.num_pages;
185         vsgt->addrs = vmw_tt->dma_ttm.dma_address;
186         vsgt->sgt = NULL;
187
188         switch (dev_priv->map_mode) {
189         case vmw_dma_map_bind:
190         case vmw_dma_map_populate:
191                 vsgt->sgt = &vmw_tt->sgt;
192                 ret = sg_alloc_table_from_pages_segment(
193                         &vmw_tt->sgt, vsgt->pages, vsgt->num_pages, 0,
194                         (unsigned long)vsgt->num_pages << PAGE_SHIFT,
195                         dma_get_max_seg_size(dev_priv->drm.dev), GFP_KERNEL);
196                 if (ret)
197                         goto out_sg_alloc_fail;
198
199                 ret = vmw_ttm_map_for_dma(vmw_tt);
200                 if (unlikely(ret != 0))
201                         goto out_map_fail;
202
203                 break;
204         default:
205                 break;
206         }
207
208         vmw_tt->mapped = true;
209         return 0;
210
211 out_map_fail:
212         sg_free_table(vmw_tt->vsgt.sgt);
213         vmw_tt->vsgt.sgt = NULL;
214 out_sg_alloc_fail:
215         return ret;
216 }
217
218 /**
219  * vmw_ttm_unmap_dma - Tear down any TTM page device mappings
220  *
221  * @vmw_tt: Pointer to a struct vmw_ttm_tt
222  *
223  * Tear down any previously set up device DMA mappings and free
224  * any storage space allocated for them. If there are no mappings set up,
225  * this function is a NOP.
226  */
227 static void vmw_ttm_unmap_dma(struct vmw_ttm_tt *vmw_tt)
228 {
229         struct vmw_private *dev_priv = vmw_tt->dev_priv;
230
231         if (!vmw_tt->vsgt.sgt)
232                 return;
233
234         switch (dev_priv->map_mode) {
235         case vmw_dma_map_bind:
236         case vmw_dma_map_populate:
237                 vmw_ttm_unmap_from_dma(vmw_tt);
238                 sg_free_table(vmw_tt->vsgt.sgt);
239                 vmw_tt->vsgt.sgt = NULL;
240                 break;
241         default:
242                 break;
243         }
244         vmw_tt->mapped = false;
245 }
246
247 /**
248  * vmw_bo_sg_table - Return a struct vmw_sg_table object for a
249  * TTM buffer object
250  *
251  * @bo: Pointer to a struct ttm_buffer_object
252  *
253  * Returns a pointer to a struct vmw_sg_table object. The object should
254  * not be freed after use.
255  * Note that for the device addresses to be valid, the buffer object must
256  * either be reserved or pinned.
257  */
258 const struct vmw_sg_table *vmw_bo_sg_table(struct ttm_buffer_object *bo)
259 {
260         struct vmw_ttm_tt *vmw_tt =
261                 container_of(bo->ttm, struct vmw_ttm_tt, dma_ttm);
262
263         return &vmw_tt->vsgt;
264 }
265
266
267 static int vmw_ttm_bind(struct ttm_device *bdev,
268                         struct ttm_tt *ttm, struct ttm_resource *bo_mem)
269 {
270         struct vmw_ttm_tt *vmw_be =
271                 container_of(ttm, struct vmw_ttm_tt, dma_ttm);
272         int ret = 0;
273
274         if (!bo_mem)
275                 return -EINVAL;
276
277         if (vmw_be->bound)
278                 return 0;
279
280         ret = vmw_ttm_map_dma(vmw_be);
281         if (unlikely(ret != 0))
282                 return ret;
283
284         vmw_be->gmr_id = bo_mem->start;
285         vmw_be->mem_type = bo_mem->mem_type;
286
287         switch (bo_mem->mem_type) {
288         case VMW_PL_GMR:
289                 ret = vmw_gmr_bind(vmw_be->dev_priv, &vmw_be->vsgt,
290                                     ttm->num_pages, vmw_be->gmr_id);
291                 break;
292         case VMW_PL_MOB:
293                 if (unlikely(vmw_be->mob == NULL)) {
294                         vmw_be->mob =
295                                 vmw_mob_create(ttm->num_pages);
296                         if (unlikely(vmw_be->mob == NULL))
297                                 return -ENOMEM;
298                 }
299
300                 ret = vmw_mob_bind(vmw_be->dev_priv, vmw_be->mob,
301                                     &vmw_be->vsgt, ttm->num_pages,
302                                     vmw_be->gmr_id);
303                 break;
304         case VMW_PL_SYSTEM:
305                 /* Nothing to be done for a system bind */
306                 break;
307         default:
308                 BUG();
309         }
310         vmw_be->bound = true;
311         return ret;
312 }
313
314 static void vmw_ttm_unbind(struct ttm_device *bdev,
315                            struct ttm_tt *ttm)
316 {
317         struct vmw_ttm_tt *vmw_be =
318                 container_of(ttm, struct vmw_ttm_tt, dma_ttm);
319
320         if (!vmw_be->bound)
321                 return;
322
323         switch (vmw_be->mem_type) {
324         case VMW_PL_GMR:
325                 vmw_gmr_unbind(vmw_be->dev_priv, vmw_be->gmr_id);
326                 break;
327         case VMW_PL_MOB:
328                 vmw_mob_unbind(vmw_be->dev_priv, vmw_be->mob);
329                 break;
330         case VMW_PL_SYSTEM:
331                 break;
332         default:
333                 BUG();
334         }
335
336         if (vmw_be->dev_priv->map_mode == vmw_dma_map_bind)
337                 vmw_ttm_unmap_dma(vmw_be);
338         vmw_be->bound = false;
339 }
340
341
342 static void vmw_ttm_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
343 {
344         struct vmw_ttm_tt *vmw_be =
345                 container_of(ttm, struct vmw_ttm_tt, dma_ttm);
346
347         vmw_ttm_unmap_dma(vmw_be);
348         ttm_tt_fini(ttm);
349         if (vmw_be->mob)
350                 vmw_mob_destroy(vmw_be->mob);
351
352         kfree(vmw_be);
353 }
354
355
356 static int vmw_ttm_populate(struct ttm_device *bdev,
357                             struct ttm_tt *ttm, struct ttm_operation_ctx *ctx)
358 {
359         int ret;
360
361         /* TODO: maybe completely drop this ? */
362         if (ttm_tt_is_populated(ttm))
363                 return 0;
364
365         ret = ttm_pool_alloc(&bdev->pool, ttm, ctx);
366
367         return ret;
368 }
369
370 static void vmw_ttm_unpopulate(struct ttm_device *bdev,
371                                struct ttm_tt *ttm)
372 {
373         struct vmw_ttm_tt *vmw_tt = container_of(ttm, struct vmw_ttm_tt,
374                                                  dma_ttm);
375
376         vmw_ttm_unbind(bdev, ttm);
377
378         if (vmw_tt->mob) {
379                 vmw_mob_destroy(vmw_tt->mob);
380                 vmw_tt->mob = NULL;
381         }
382
383         vmw_ttm_unmap_dma(vmw_tt);
384
385         ttm_pool_free(&bdev->pool, ttm);
386 }
387
388 static struct ttm_tt *vmw_ttm_tt_create(struct ttm_buffer_object *bo,
389                                         uint32_t page_flags)
390 {
391         struct vmw_ttm_tt *vmw_be;
392         int ret;
393
394         vmw_be = kzalloc(sizeof(*vmw_be), GFP_KERNEL);
395         if (!vmw_be)
396                 return NULL;
397
398         vmw_be->dev_priv = vmw_priv_from_ttm(bo->bdev);
399         vmw_be->mob = NULL;
400
401         if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent)
402                 ret = ttm_sg_tt_init(&vmw_be->dma_ttm, bo, page_flags,
403                                      ttm_cached);
404         else
405                 ret = ttm_tt_init(&vmw_be->dma_ttm, bo, page_flags,
406                                   ttm_cached, 0);
407         if (unlikely(ret != 0))
408                 goto out_no_init;
409
410         return &vmw_be->dma_ttm;
411 out_no_init:
412         kfree(vmw_be);
413         return NULL;
414 }
415
416 static void vmw_evict_flags(struct ttm_buffer_object *bo,
417                      struct ttm_placement *placement)
418 {
419         *placement = vmw_sys_placement;
420 }
421
422 static int vmw_ttm_io_mem_reserve(struct ttm_device *bdev, struct ttm_resource *mem)
423 {
424         struct vmw_private *dev_priv = vmw_priv_from_ttm(bdev);
425
426         switch (mem->mem_type) {
427         case TTM_PL_SYSTEM:
428         case VMW_PL_SYSTEM:
429         case VMW_PL_GMR:
430         case VMW_PL_MOB:
431                 return 0;
432         case TTM_PL_VRAM:
433                 mem->bus.offset = (mem->start << PAGE_SHIFT) +
434                         dev_priv->vram_start;
435                 mem->bus.is_iomem = true;
436                 mem->bus.caching = ttm_cached;
437                 break;
438         default:
439                 return -EINVAL;
440         }
441         return 0;
442 }
443
444 /**
445  * vmw_move_notify - TTM move_notify_callback
446  *
447  * @bo: The TTM buffer object about to move.
448  * @old_mem: The old memory where we move from
449  * @new_mem: The struct ttm_resource indicating to what memory
450  *       region the move is taking place.
451  *
452  * Calls move_notify for all subsystems needing it.
453  * (currently only resources).
454  */
455 static void vmw_move_notify(struct ttm_buffer_object *bo,
456                             struct ttm_resource *old_mem,
457                             struct ttm_resource *new_mem)
458 {
459         vmw_bo_move_notify(bo, new_mem);
460         vmw_query_move_notify(bo, old_mem, new_mem);
461 }
462
463
464 /**
465  * vmw_swap_notify - TTM move_notify_callback
466  *
467  * @bo: The TTM buffer object about to be swapped out.
468  */
469 static void vmw_swap_notify(struct ttm_buffer_object *bo)
470 {
471         vmw_bo_swap_notify(bo);
472         (void) ttm_bo_wait(bo, false, false);
473 }
474
475 static bool vmw_memtype_is_system(uint32_t mem_type)
476 {
477         return mem_type == TTM_PL_SYSTEM || mem_type == VMW_PL_SYSTEM;
478 }
479
480 static int vmw_move(struct ttm_buffer_object *bo,
481                     bool evict,
482                     struct ttm_operation_ctx *ctx,
483                     struct ttm_resource *new_mem,
484                     struct ttm_place *hop)
485 {
486         struct ttm_resource_manager *new_man;
487         struct ttm_resource_manager *old_man = NULL;
488         int ret = 0;
489
490         new_man = ttm_manager_type(bo->bdev, new_mem->mem_type);
491         if (bo->resource)
492                 old_man = ttm_manager_type(bo->bdev, bo->resource->mem_type);
493
494         if (new_man->use_tt && !vmw_memtype_is_system(new_mem->mem_type)) {
495                 ret = vmw_ttm_bind(bo->bdev, bo->ttm, new_mem);
496                 if (ret)
497                         return ret;
498         }
499
500         if (!bo->resource || (bo->resource->mem_type == TTM_PL_SYSTEM &&
501                               bo->ttm == NULL)) {
502                 ttm_bo_move_null(bo, new_mem);
503                 return 0;
504         }
505
506         vmw_move_notify(bo, bo->resource, new_mem);
507
508         if (old_man && old_man->use_tt && new_man->use_tt) {
509                 if (vmw_memtype_is_system(bo->resource->mem_type)) {
510                         ttm_bo_move_null(bo, new_mem);
511                         return 0;
512                 }
513                 ret = ttm_bo_wait_ctx(bo, ctx);
514                 if (ret)
515                         goto fail;
516
517                 vmw_ttm_unbind(bo->bdev, bo->ttm);
518                 ttm_resource_free(bo, &bo->resource);
519                 ttm_bo_assign_mem(bo, new_mem);
520                 return 0;
521         } else {
522                 ret = ttm_bo_move_memcpy(bo, ctx, new_mem);
523                 if (ret)
524                         goto fail;
525         }
526         return 0;
527 fail:
528         vmw_move_notify(bo, new_mem, bo->resource);
529         return ret;
530 }
531
532 struct ttm_device_funcs vmw_bo_driver = {
533         .ttm_tt_create = &vmw_ttm_tt_create,
534         .ttm_tt_populate = &vmw_ttm_populate,
535         .ttm_tt_unpopulate = &vmw_ttm_unpopulate,
536         .ttm_tt_destroy = &vmw_ttm_destroy,
537         .eviction_valuable = ttm_bo_eviction_valuable,
538         .evict_flags = vmw_evict_flags,
539         .move = vmw_move,
540         .swap_notify = vmw_swap_notify,
541         .io_mem_reserve = &vmw_ttm_io_mem_reserve,
542 };
543
544 int vmw_bo_create_and_populate(struct vmw_private *dev_priv,
545                                size_t bo_size, u32 domain,
546                                struct vmw_bo **bo_p)
547 {
548         struct ttm_operation_ctx ctx = {
549                 .interruptible = false,
550                 .no_wait_gpu = false
551         };
552         struct vmw_bo *vbo;
553         int ret;
554         struct vmw_bo_params bo_params = {
555                 .domain = domain,
556                 .busy_domain = domain,
557                 .bo_type = ttm_bo_type_kernel,
558                 .size = bo_size,
559                 .pin = true
560         };
561
562         ret = vmw_bo_create(dev_priv, &bo_params, &vbo);
563         if (unlikely(ret != 0))
564                 return ret;
565
566         ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL);
567         BUG_ON(ret != 0);
568         ret = vmw_ttm_populate(vbo->tbo.bdev, vbo->tbo.ttm, &ctx);
569         if (likely(ret == 0)) {
570                 struct vmw_ttm_tt *vmw_tt =
571                         container_of(vbo->tbo.ttm, struct vmw_ttm_tt, dma_ttm);
572                 ret = vmw_ttm_map_dma(vmw_tt);
573         }
574
575         ttm_bo_unreserve(&vbo->tbo);
576
577         if (likely(ret == 0))
578                 *bo_p = vbo;
579         return ret;
580 }