Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 
0003 #ifndef __DRM_GEM_SHMEM_HELPER_H__
0004 #define __DRM_GEM_SHMEM_HELPER_H__
0005 
0006 #include <linux/fs.h>
0007 #include <linux/mm.h>
0008 #include <linux/mutex.h>
0009 
0010 #include <drm/drm_file.h>
0011 #include <drm/drm_gem.h>
0012 #include <drm/drm_ioctl.h>
0013 #include <drm/drm_prime.h>
0014 
0015 struct dma_buf_attachment;
0016 struct drm_mode_create_dumb;
0017 struct drm_printer;
0018 struct sg_table;
0019 
0020 /**
0021  * struct drm_gem_shmem_object - GEM object backed by shmem
0022  */
0023 struct drm_gem_shmem_object {
0024     /**
0025      * @base: Base GEM object
0026      */
0027     struct drm_gem_object base;
0028 
0029     /**
0030      * @pages_lock: Protects the page table and use count
0031      */
0032     struct mutex pages_lock;
0033 
0034     /**
0035      * @pages: Page table
0036      */
0037     struct page **pages;
0038 
0039     /**
0040      * @pages_use_count:
0041      *
0042      * Reference count on the pages table.
0043      * The pages are put when the count reaches zero.
0044      */
0045     unsigned int pages_use_count;
0046 
0047     /**
0048      * @madv: State for madvise
0049      *
0050      * 0 is active/inuse.
0051      * A negative value is the object is purged.
0052      * Positive values are driver specific and not used by the helpers.
0053      */
0054     int madv;
0055 
0056     /**
0057      * @madv_list: List entry for madvise tracking
0058      *
0059      * Typically used by drivers to track purgeable objects
0060      */
0061     struct list_head madv_list;
0062 
0063     /**
0064      * @pages_mark_dirty_on_put:
0065      *
0066      * Mark pages as dirty when they are put.
0067      */
0068     unsigned int pages_mark_dirty_on_put    : 1;
0069 
0070     /**
0071      * @pages_mark_accessed_on_put:
0072      *
0073      * Mark pages as accessed when they are put.
0074      */
0075     unsigned int pages_mark_accessed_on_put : 1;
0076 
0077     /**
0078      * @sgt: Scatter/gather table for imported PRIME buffers
0079      */
0080     struct sg_table *sgt;
0081 
0082     /**
0083      * @vmap_lock: Protects the vmap address and use count
0084      */
0085     struct mutex vmap_lock;
0086 
0087     /**
0088      * @vaddr: Kernel virtual address of the backing memory
0089      */
0090     void *vaddr;
0091 
0092     /**
0093      * @vmap_use_count:
0094      *
0095      * Reference count on the virtual address.
0096      * The address are un-mapped when the count reaches zero.
0097      */
0098     unsigned int vmap_use_count;
0099 
0100     /**
0101      * @map_wc: map object write-combined (instead of using shmem defaults).
0102      */
0103     bool map_wc;
0104 };
0105 
0106 #define to_drm_gem_shmem_obj(obj) \
0107     container_of(obj, struct drm_gem_shmem_object, base)
0108 
0109 struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size);
0110 void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem);
0111 
0112 int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem);
0113 void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem);
0114 int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem);
0115 void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem);
0116 int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem,
0117                struct iosys_map *map);
0118 void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem,
0119               struct iosys_map *map);
0120 int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma);
0121 
0122 int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv);
0123 
0124 static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem)
0125 {
0126     return (shmem->madv > 0) &&
0127         !shmem->vmap_use_count && shmem->sgt &&
0128         !shmem->base.dma_buf && !shmem->base.import_attach;
0129 }
0130 
0131 void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem);
0132 bool drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem);
0133 
0134 struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem);
0135 struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem);
0136 
0137 void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem,
0138                   struct drm_printer *p, unsigned int indent);
0139 
0140 extern const struct vm_operations_struct drm_gem_shmem_vm_ops;
0141 
0142 /*
0143  * GEM object functions
0144  */
0145 
0146 /**
0147  * drm_gem_shmem_object_free - GEM object function for drm_gem_shmem_free()
0148  * @obj: GEM object to free
0149  *
0150  * This function wraps drm_gem_shmem_free(). Drivers that employ the shmem helpers
0151  * should use it as their &drm_gem_object_funcs.free handler.
0152  */
0153 static inline void drm_gem_shmem_object_free(struct drm_gem_object *obj)
0154 {
0155     struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
0156 
0157     drm_gem_shmem_free(shmem);
0158 }
0159 
0160 /**
0161  * drm_gem_shmem_object_print_info() - Print &drm_gem_shmem_object info for debugfs
0162  * @p: DRM printer
0163  * @indent: Tab indentation level
0164  * @obj: GEM object
0165  *
0166  * This function wraps drm_gem_shmem_print_info(). Drivers that employ the shmem helpers should
0167  * use this function as their &drm_gem_object_funcs.print_info handler.
0168  */
0169 static inline void drm_gem_shmem_object_print_info(struct drm_printer *p, unsigned int indent,
0170                            const struct drm_gem_object *obj)
0171 {
0172     const struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
0173 
0174     drm_gem_shmem_print_info(shmem, p, indent);
0175 }
0176 
0177 /**
0178  * drm_gem_shmem_object_pin - GEM object function for drm_gem_shmem_pin()
0179  * @obj: GEM object
0180  *
0181  * This function wraps drm_gem_shmem_pin(). Drivers that employ the shmem helpers should
0182  * use it as their &drm_gem_object_funcs.pin handler.
0183  */
0184 static inline int drm_gem_shmem_object_pin(struct drm_gem_object *obj)
0185 {
0186     struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
0187 
0188     return drm_gem_shmem_pin(shmem);
0189 }
0190 
0191 /**
0192  * drm_gem_shmem_object_unpin - GEM object function for drm_gem_shmem_unpin()
0193  * @obj: GEM object
0194  *
0195  * This function wraps drm_gem_shmem_unpin(). Drivers that employ the shmem helpers should
0196  * use it as their &drm_gem_object_funcs.unpin handler.
0197  */
0198 static inline void drm_gem_shmem_object_unpin(struct drm_gem_object *obj)
0199 {
0200     struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
0201 
0202     drm_gem_shmem_unpin(shmem);
0203 }
0204 
0205 /**
0206  * drm_gem_shmem_object_get_sg_table - GEM object function for drm_gem_shmem_get_sg_table()
0207  * @obj: GEM object
0208  *
0209  * This function wraps drm_gem_shmem_get_sg_table(). Drivers that employ the shmem helpers should
0210  * use it as their &drm_gem_object_funcs.get_sg_table handler.
0211  *
0212  * Returns:
0213  * A pointer to the scatter/gather table of pinned pages or NULL on failure.
0214  */
0215 static inline struct sg_table *drm_gem_shmem_object_get_sg_table(struct drm_gem_object *obj)
0216 {
0217     struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
0218 
0219     return drm_gem_shmem_get_sg_table(shmem);
0220 }
0221 
0222 /*
0223  * drm_gem_shmem_object_vmap - GEM object function for drm_gem_shmem_vmap()
0224  * @obj: GEM object
0225  * @map: Returns the kernel virtual address of the SHMEM GEM object's backing store.
0226  *
0227  * This function wraps drm_gem_shmem_vmap(). Drivers that employ the shmem helpers should
0228  * use it as their &drm_gem_object_funcs.vmap handler.
0229  *
0230  * Returns:
0231  * 0 on success or a negative error code on failure.
0232  */
0233 static inline int drm_gem_shmem_object_vmap(struct drm_gem_object *obj,
0234                         struct iosys_map *map)
0235 {
0236     struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
0237 
0238     return drm_gem_shmem_vmap(shmem, map);
0239 }
0240 
0241 /*
0242  * drm_gem_shmem_object_vunmap - GEM object function for drm_gem_shmem_vunmap()
0243  * @obj: GEM object
0244  * @map: Kernel virtual address where the SHMEM GEM object was mapped
0245  *
0246  * This function wraps drm_gem_shmem_vunmap(). Drivers that employ the shmem helpers should
0247  * use it as their &drm_gem_object_funcs.vunmap handler.
0248  */
0249 static inline void drm_gem_shmem_object_vunmap(struct drm_gem_object *obj,
0250                            struct iosys_map *map)
0251 {
0252     struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
0253 
0254     drm_gem_shmem_vunmap(shmem, map);
0255 }
0256 
0257 /**
0258  * drm_gem_shmem_object_mmap - GEM object function for drm_gem_shmem_mmap()
0259  * @obj: GEM object
0260  * @vma: VMA for the area to be mapped
0261  *
0262  * This function wraps drm_gem_shmem_mmap(). Drivers that employ the shmem helpers should
0263  * use it as their &drm_gem_object_funcs.mmap handler.
0264  *
0265  * Returns:
0266  * 0 on success or a negative error code on failure.
0267  */
0268 static inline int drm_gem_shmem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
0269 {
0270     struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
0271 
0272     return drm_gem_shmem_mmap(shmem, vma);
0273 }
0274 
0275 /*
0276  * Driver ops
0277  */
0278 
0279 struct drm_gem_object *
0280 drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
0281                     struct dma_buf_attachment *attach,
0282                     struct sg_table *sgt);
0283 int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
0284                   struct drm_mode_create_dumb *args);
0285 
0286 /**
0287  * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
0288  *
0289  * This macro provides a shortcut for setting the shmem GEM operations in
0290  * the &drm_driver structure.
0291  */
0292 #define DRM_GEM_SHMEM_DRIVER_OPS \
0293     .prime_handle_to_fd = drm_gem_prime_handle_to_fd, \
0294     .prime_fd_to_handle = drm_gem_prime_fd_to_handle, \
0295     .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
0296     .gem_prime_mmap     = drm_gem_prime_mmap, \
0297     .dumb_create        = drm_gem_shmem_dumb_create
0298 
0299 #endif /* __DRM_GEM_SHMEM_HELPER_H__ */