Merge tag 'dmaengine-fix-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul...
[platform/kernel/linux-rpi.git] / drivers / accel / ivpu / ivpu_gem.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2020-2023 Intel Corporation
4  */
5 #ifndef __IVPU_GEM_H__
6 #define __IVPU_GEM_H__
7
8 #include <drm/drm_gem.h>
9 #include <drm/drm_mm.h>
10
11 #define DRM_IVPU_BO_NOSNOOP       0x10000000
12
13 struct dma_buf;
14 struct ivpu_bo_ops;
15 struct ivpu_file_priv;
16
17 struct ivpu_bo {
18         struct drm_gem_object base;
19         const struct ivpu_bo_ops *ops;
20
21         struct ivpu_mmu_context *ctx;
22         struct list_head ctx_node;
23         struct drm_mm_node mm_node;
24
25         struct mutex lock; /* Protects: pages, sgt, mmu_mapped */
26         struct sg_table *sgt;
27         struct page **pages;
28         bool mmu_mapped;
29
30         void *kvaddr;
31         u64 vpu_addr;
32         u32 handle;
33         u32 flags;
34         uintptr_t user_ptr;
35         u32 job_status;
36 };
37
38 enum ivpu_bo_type {
39         IVPU_BO_TYPE_SHMEM = 1,
40         IVPU_BO_TYPE_INTERNAL,
41         IVPU_BO_TYPE_PRIME,
42 };
43
44 struct ivpu_bo_ops {
45         enum ivpu_bo_type type;
46         const char *name;
47         int (*alloc_pages)(struct ivpu_bo *bo);
48         void (*free_pages)(struct ivpu_bo *bo);
49         int (*map_pages)(struct ivpu_bo *bo);
50         void (*unmap_pages)(struct ivpu_bo *bo);
51 };
52
53 int ivpu_bo_pin(struct ivpu_bo *bo);
54 void ivpu_bo_remove_all_bos_from_context(struct ivpu_mmu_context *ctx);
55 void ivpu_bo_list(struct drm_device *dev, struct drm_printer *p);
56 void ivpu_bo_list_print(struct drm_device *dev);
57
58 struct ivpu_bo *
59 ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 flags);
60 void ivpu_bo_free_internal(struct ivpu_bo *bo);
61 struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf);
62 void ivpu_bo_unmap_sgt_and_remove_from_context(struct ivpu_bo *bo);
63
64 int ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
65 int ivpu_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
66 int ivpu_bo_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
67
68 static inline struct ivpu_bo *to_ivpu_bo(struct drm_gem_object *obj)
69 {
70         return container_of(obj, struct ivpu_bo, base);
71 }
72
73 static inline struct page *ivpu_bo_get_page(struct ivpu_bo *bo, u64 offset)
74 {
75         if (offset > bo->base.size || !bo->pages)
76                 return NULL;
77
78         return bo->pages[offset / PAGE_SIZE];
79 }
80
81 static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)
82 {
83         return bo->flags & DRM_IVPU_BO_CACHE_MASK;
84 }
85
86 static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
87 {
88         if (bo->flags & DRM_IVPU_BO_NOSNOOP)
89                 return false;
90
91         return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
92 }
93
94 static inline pgprot_t ivpu_bo_pgprot(struct ivpu_bo *bo, pgprot_t prot)
95 {
96         if (bo->flags & DRM_IVPU_BO_WC)
97                 return pgprot_writecombine(prot);
98
99         if (bo->flags & DRM_IVPU_BO_UNCACHED)
100                 return pgprot_noncached(prot);
101
102         return prot;
103 }
104
105 static inline struct ivpu_device *ivpu_bo_to_vdev(struct ivpu_bo *bo)
106 {
107         return to_ivpu_device(bo->base.dev);
108 }
109
110 static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr)
111 {
112         if (vpu_addr < bo->vpu_addr)
113                 return NULL;
114
115         if (vpu_addr >= (bo->vpu_addr + bo->base.size))
116                 return NULL;
117
118         return bo->kvaddr + (vpu_addr - bo->vpu_addr);
119 }
120
121 static inline u32 cpu_to_vpu_addr(struct ivpu_bo *bo, void *cpu_addr)
122 {
123         if (cpu_addr < bo->kvaddr)
124                 return 0;
125
126         if (cpu_addr >= (bo->kvaddr + bo->base.size))
127                 return 0;
128
129         return bo->vpu_addr + (cpu_addr - bo->kvaddr);
130 }
131
132 #endif /* __IVPU_GEM_H__ */