Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) Rockchip Electronics Co.Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Author: Felix Zeng <felix.zeng@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #ifndef __LINUX_RKNPU_GEM_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #define __LINUX_RKNPU_GEM_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/mm_types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/version.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <drm/drm_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <drm/drm_vma_manager.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <drm/drm_gem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <drm/drm_mode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #if KERNEL_VERSION(4, 14, 0) > LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <drm/drm_mem_util.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "rknpu_mm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define to_rknpu_obj(x) container_of(x, struct rknpu_gem_object, base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * rknpu drm buffer structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * @base: a gem object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *	- a new handle to this gem object would be created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *	by drm_gem_handle_create().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * @flags: indicate memory type to allocated buffer and cache attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * @size: size requested from user, in bytes and this size is aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *	in page unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * @cookie: cookie returned by dma_alloc_attrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * @kv_addr: kernel virtual address to allocated memory region.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * @dma_addr: bus address(accessed by dma) to allocated memory region.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *	- this address could be physical address without IOMMU and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *	device address with IOMMU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * @pages: Array of backing pages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * @sgt: Imported sg_table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * P.S. this object would be transferred to user as kms_bo.handle so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  *	user can access the buffer through kms_bo.handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) struct rknpu_gem_object {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	struct drm_gem_object base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	unsigned long sram_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	struct rknpu_mm_obj *sram_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	dma_addr_t iova_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	unsigned long iova_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	void *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	void __iomem *kv_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	dma_addr_t dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	unsigned long dma_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	unsigned long num_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct sg_table *sgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	struct drm_mm_node mm_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) /* create a new buffer with gem object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) struct rknpu_gem_object *rknpu_gem_object_create(struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 						 unsigned int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 						 unsigned long size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 						 unsigned long sram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) /* destroy a buffer with gem object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) void rknpu_gem_object_destroy(struct rknpu_gem_object *rknpu_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) /* request gem object creation and buffer allocation as the size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) int rknpu_gem_create_ioctl(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			   struct drm_file *file_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) /* get fake-offset of gem object that can be used with mmap. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) int rknpu_gem_map_ioctl(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			struct drm_file *file_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) int rknpu_gem_destroy_ioctl(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			    struct drm_file *file_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * get rknpu drm object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * gem object reference count would be increased.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static inline void rknpu_gem_object_get(struct drm_gem_object *obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) #if KERNEL_VERSION(4, 13, 0) < LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	drm_gem_object_get(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	drm_gem_object_reference(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * put rknpu drm object acquired from rknpu_gem_object_find() or rknpu_gem_object_get(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * gem object reference count would be decreased.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline void rknpu_gem_object_put(struct drm_gem_object *obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	drm_gem_object_put(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #elif KERNEL_VERSION(4, 13, 0) < LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	drm_gem_object_put_unlocked(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	drm_gem_object_unreference_unlocked(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * get rknpu drm object from gem handle, this function could be used for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * other drivers such as 2d/3d acceleration drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * with this function call, gem object reference count would be increased.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static inline struct rknpu_gem_object *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) rknpu_gem_object_find(struct drm_file *filp, unsigned int handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	struct drm_gem_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	obj = drm_gem_object_lookup(filp, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (!obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		// DRM_ERROR("failed to lookup gem object.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	rknpu_gem_object_put(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	return to_rknpu_obj(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* get buffer information to memory region allocated by gem. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int rknpu_gem_get_ioctl(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			struct drm_file *file_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* free gem object. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) void rknpu_gem_free_object(struct drm_gem_object *obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* create memory region for drm framebuffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int rknpu_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			  struct drm_mode_create_dumb *args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #if KERNEL_VERSION(4, 19, 0) > LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* map memory region for drm framebuffer to user space. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int rknpu_gem_dumb_map_offset(struct drm_file *file_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			      struct drm_device *dev, uint32_t handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			      uint64_t *offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* page fault handler and mmap fault address(virtual) to physical memory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) vm_fault_t rknpu_gem_fault(struct vm_fault *vmf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #elif KERNEL_VERSION(4, 14, 0) <= LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int rknpu_gem_fault(struct vm_fault *vmf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int rknpu_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* set vm_flags and we can change the vm attribute to other one at here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int rknpu_gem_mmap(struct file *filp, struct vm_area_struct *vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* low-level interface prime helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #if KERNEL_VERSION(4, 13, 0) <= LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct drm_gem_object *rknpu_gem_prime_import(struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 					      struct dma_buf *dma_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct sg_table *rknpu_gem_prime_get_sg_table(struct drm_gem_object *obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct drm_gem_object *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) rknpu_gem_prime_import_sg_table(struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 				struct dma_buf_attachment *attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 				struct sg_table *sgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) void *rknpu_gem_prime_vmap(struct drm_gem_object *obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) void rknpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int rknpu_gem_prime_mmap(struct drm_gem_object *obj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			 struct vm_area_struct *vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int rknpu_gem_sync_ioctl(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			 struct drm_file *file_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static inline void *rknpu_gem_alloc_page(size_t nr_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #if KERNEL_VERSION(4, 13, 0) <= LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	return kvmalloc_array(nr_pages, sizeof(struct page *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			      GFP_KERNEL | __GFP_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	return drm_calloc_large(nr_pages, sizeof(struct page *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static inline void rknpu_gem_free_page(void *pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #if KERNEL_VERSION(4, 13, 0) <= LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	kvfree(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	drm_free_large(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #endif