linux/drivers/gpu/drm/nouveau/nouveau_bo.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: MIT */
   2#ifndef __NOUVEAU_BO_H__
   3#define __NOUVEAU_BO_H__
   4
   5#include <drm/drm_gem.h>
   6
   7struct nouveau_channel;
   8struct nouveau_fence;
   9struct nvkm_vma;
  10
  11struct nouveau_bo {
  12        struct ttm_buffer_object bo;
  13        struct ttm_placement placement;
  14        u32 valid_domains;
  15        struct ttm_place placements[3];
  16        struct ttm_place busy_placements[3];
  17        bool force_coherent;
  18        struct ttm_bo_kmap_obj kmap;
  19        struct list_head head;
  20
  21        /* protected by ttm_bo_reserve() */
  22        struct drm_file *reserved_by;
  23        struct list_head entry;
  24        int pbbo_index;
  25        bool validate_mapped;
  26
  27        struct list_head vma_list;
  28
  29        unsigned contig:1;
  30        unsigned page:5;
  31        unsigned kind:8;
  32        unsigned comp:3;
  33        unsigned zeta:3;
  34        unsigned mode;
  35
  36        struct nouveau_drm_tile *tile;
  37
  38        /* Only valid if allocated via nouveau_gem_new() and iff you hold a
  39         * gem reference to it! For debugging, use gem.filp != NULL to test
  40         * whether it is valid. */
  41        struct drm_gem_object gem;
  42
  43        /* protect by the ttm reservation lock */
  44        int pin_refcnt;
  45
  46        struct ttm_bo_kmap_obj dma_buf_vmap;
  47};
  48
  49static inline struct nouveau_bo *
  50nouveau_bo(struct ttm_buffer_object *bo)
  51{
  52        return container_of(bo, struct nouveau_bo, bo);
  53}
  54
  55static inline int
  56nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo)
  57{
  58        struct nouveau_bo *prev;
  59
  60        if (!pnvbo)
  61                return -EINVAL;
  62        prev = *pnvbo;
  63
  64        if (ref) {
  65                ttm_bo_get(&ref->bo);
  66                *pnvbo = nouveau_bo(&ref->bo);
  67        } else {
  68                *pnvbo = NULL;
  69        }
  70        if (prev)
  71                ttm_bo_put(&prev->bo);
  72
  73        return 0;
  74}
  75
  76extern struct ttm_bo_driver nouveau_bo_driver;
  77
  78void nouveau_bo_move_init(struct nouveau_drm *);
  79int  nouveau_bo_new(struct nouveau_cli *, u64 size, int align, u32 flags,
  80                    u32 tile_mode, u32 tile_flags, struct sg_table *sg,
  81                    struct reservation_object *robj,
  82                    struct nouveau_bo **);
  83int  nouveau_bo_pin(struct nouveau_bo *, u32 flags, bool contig);
  84int  nouveau_bo_unpin(struct nouveau_bo *);
  85int  nouveau_bo_map(struct nouveau_bo *);
  86void nouveau_bo_unmap(struct nouveau_bo *);
  87void nouveau_bo_placement_set(struct nouveau_bo *, u32 type, u32 busy);
  88void nouveau_bo_wr16(struct nouveau_bo *, unsigned index, u16 val);
  89u32  nouveau_bo_rd32(struct nouveau_bo *, unsigned index);
  90void nouveau_bo_wr32(struct nouveau_bo *, unsigned index, u32 val);
  91void nouveau_bo_fence(struct nouveau_bo *, struct nouveau_fence *, bool exclusive);
  92int  nouveau_bo_validate(struct nouveau_bo *, bool interruptible,
  93                         bool no_wait_gpu);
  94void nouveau_bo_sync_for_device(struct nouveau_bo *nvbo);
  95void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo);
  96
  97/* TODO: submit equivalent to TTM generic API upstream? */
  98static inline void __iomem *
  99nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
 100{
 101        bool is_iomem;
 102        void __iomem *ioptr = (void __force __iomem *)ttm_kmap_obj_virtual(
 103                                                &nvbo->kmap, &is_iomem);
 104        WARN_ON_ONCE(ioptr && !is_iomem);
 105        return ioptr;
 106}
 107
 108static inline void
 109nouveau_bo_unmap_unpin_unref(struct nouveau_bo **pnvbo)
 110{
 111        if (*pnvbo) {
 112                nouveau_bo_unmap(*pnvbo);
 113                nouveau_bo_unpin(*pnvbo);
 114                nouveau_bo_ref(NULL, pnvbo);
 115        }
 116}
 117
 118static inline int
 119nouveau_bo_new_pin_map(struct nouveau_cli *cli, u64 size, int align, u32 flags,
 120                       struct nouveau_bo **pnvbo)
 121{
 122        int ret = nouveau_bo_new(cli, size, align, flags,
 123                                 0, 0, NULL, NULL, pnvbo);
 124        if (ret == 0) {
 125                ret = nouveau_bo_pin(*pnvbo, flags, true);
 126                if (ret == 0) {
 127                        ret = nouveau_bo_map(*pnvbo);
 128                        if (ret == 0)
 129                                return ret;
 130                        nouveau_bo_unpin(*pnvbo);
 131                }
 132                nouveau_bo_ref(NULL, pnvbo);
 133        }
 134        return ret;
 135}
 136#endif
 137