blob: ed480e5ebacde8bd6be6f68c1d16b5ef7dfb9b25 [file] [log] [blame]
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#ifndef __MESON_UVM_H
#define __MESON_UVM_H
#include <linux/device.h>
#include <linux/dma-direction.h>
#include <linux/miscdevice.h>
#include <linux/kref.h>
#include <linux/mm_types.h>
#include <linux/mutex.h>
#include <linux/rbtree.h>
#include <linux/sched.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <linux/amlogic/media/vfm/vframe.h>
#define MAX_BUFF_NUMS 4
#define UVM_FAKE_SIZE 4096
enum uvm_alloc_flag {
UVM_IMM_ALLOC,
UVM_DELAY_ALLOC,
UVM_FAKE_ALLOC,
UVM_SECURE_ALLOC,
UVM_SKIP_REALLOC,
UVM_DETACH_FLAG = 30
};
/**
* struct uvm_handle - video dmabuffer wrap vframe
*
* @ref: reference count
* @lock: protects the uvm_handle fields
* @uvm_alloc: buffer alloc info
* @dma_buf: dmabuf structure
* @alloc: non-alloc or allocated
* @size: dmabuf size
* @align: dmabuf align size
* @flags: alloc flag and usage flag
* @vf: builtin vframe
* @vfp: pointer the origin vframe
* @mod_attached: list of attached module
* @n_mod_attached: num of attached module
* @mod_attached_mask: mask of attached module
*/
struct uvm_handle {
struct kref ref;
/* protects the uvm_handle fields */
struct mutex lock;
/* protects the whole operation of detaching hook mod */
struct mutex detachlock;
struct uvm_alloc *ua;
struct dma_buf *dmabuf;
bool alloc;
size_t size;
size_t align;
unsigned long flags;
struct vframe_s vf;
struct vframe_s *vfp;
struct list_head mod_attached;
size_t n_mod_attached;
unsigned long mod_attached_mask;
};
/**
* struct uvm_buf_obj - uvm buffer object
* This structure define the uvm buffer object. uvm do not allocate buffer.
* device that allocate buffer, wrap this structure.
*
* @arg: uvm dmabuf exporter device priv structure
* @dev: uvm dmabuf exporter device
*/
struct uvm_buf_obj {
void *arg;
struct device *dev;
struct dma_buf *dmabuf;
};
/**
* struct uvm_alloc - uvm buffer alloc struct
*
* @sgt: dmabuf sg_table
* @pages: dmabuf page array
* @vaddr: dmabuf kernel address
* @size: dmabuf real size
* @obj: uvm buffer object
* @free: free uvm_buf_obj related
*/
struct uvm_alloc {
struct sg_table *sgt;
struct page **pages;
void *vaddr;
size_t size;
u64 flags;
int scalar;
struct uvm_buf_obj *obj;
void (*free)(struct uvm_buf_obj *obj);
int (*delay_alloc)(struct dma_buf *dmabuf, struct uvm_buf_obj *obj);
int (*gpu_realloc)(struct dma_buf *dmabuf, struct uvm_buf_obj *obj, int scalar);
};
struct uvm_alloc_info {
size_t size;
u64 flags;
int scalar;
struct sg_table *sgt;
struct uvm_buf_obj *obj;
void (*free)(struct uvm_buf_obj *obj);
int (*delay_alloc)(struct dma_buf *dmabuf, struct uvm_buf_obj *obj);
int (*gpu_realloc)(struct dma_buf *dmabuf, struct uvm_buf_obj *obj, int scalar);
};
enum uvm_hook_mod_type {
VF_SRC_DECODER,
VF_SRC_VDIN,
VF_PROCESS_V4LVIDEO,
VF_PROCESS_DI,
VF_PROCESS_VIDEOCOMPOSER,
VF_PROCESS_DECODER,
PROCESS_NN,
PROCESS_GRALLOC,
PROCESS_AIPQ,
PROCESS_INVALID
};
/**
* struct uvm_hook_mod - uvm hook module
*
* @ref: reference count
* @type: module type
* @arg: module private data
* @free: module free function
* @acquire_fence: module acquire fence
* @head: module link node
*/
struct uvm_hook_mod {
struct kref ref;
enum uvm_hook_mod_type type;
void *arg;
void (*free)(void *arg);
int (*getinfo)(void *arg, char *buf);
int (*setinfo)(void *arg, char *buf);
struct sync_fence *acquire_fence;
struct list_head list;
};
struct uvm_hook_mod_info {
enum uvm_hook_mod_type type;
void *arg;
void (*free)(void *arg);
int (*getinfo)(void *arg, char *buf);
int (*setinfo)(void *arg, char *buf);
struct sync_fence *acquire_fence;
};
struct dma_buf *uvm_alloc_dmabuf(size_t len, size_t align, ulong flags);
bool dmabuf_is_uvm(struct dma_buf *dmabuf);
struct uvm_buf_obj *dmabuf_get_uvm_buf_obj(struct dma_buf *dmabuf);
int dmabuf_bind_uvm_alloc(struct dma_buf *dmabuf, struct uvm_alloc_info *info);
int dmabuf_bind_uvm_delay_alloc(struct dma_buf *dmabuf,
struct uvm_alloc_info *info);
/**
* uvm vframe interface
*/
int dmabuf_set_vframe(struct dma_buf *dmabuf, struct vframe_s *vf,
enum uvm_hook_mod_type type);
struct vframe_s *dmabuf_get_vframe(struct dma_buf *dmabuf);
int dmabuf_put_vframe(struct dma_buf *dmabuf);
/**
* uvm hook module interface
*/
int uvm_attach_hook_mod(struct dma_buf *dmabuf,
struct uvm_hook_mod_info *info);
int uvm_detach_hook_mod(struct dma_buf *dmabuf,
int type);
int meson_uvm_getinfo(int shared_fd,
int mode_type, char *buf);
int meson_uvm_setinfo(int shared_fd,
int mode_type, char *buf);
struct uvm_hook_mod *uvm_get_hook_mod(struct dma_buf *dmabuf,
int type);
int uvm_put_hook_mod(struct dma_buf *dmabuf, int type);
bool is_valid_mod_type(struct dma_buf *dmabuf,
enum uvm_hook_mod_type type);
#endif