1
0
mirror of https://github.com/physwizz/a155-U-u1.git synced 2025-09-05 12:50:27 +00:00
Files
physwizz 99537be4e2 first
2024-03-11 06:53:12 +11:00

392 lines
11 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#ifndef MTK_HCP_H
#define MTK_HCP_H
#include <linux/fdtable.h>
#include <linux/platform_device.h>
#include <uapi/linux/dma-heap.h>
#include <linux/dma-heap.h>
#include <linux/dma-direction.h>
#include <linux/scatterlist.h>
#include <linux/dma-buf.h>
#include "mtk-img-ipi.h"
//#include "scp_ipi.h"
/**
* HCP (Hetero Control Processor ) is a tiny processor controlling
* the methodology of register programming. If the module support
* to run on CM4 then it will send data to CM4 to program register.
* Or it will send the data to user library and let RED to program
* register.
*
**/
typedef void (*hcp_handler_t) (void *data,
unsigned int len,
void *priv);
/**
* hcp ID definition
*/
enum hcp_id {
HCP_INIT_ID = 0,
HCP_ISP_CMD_ID,
HCP_ISP_FRAME_ID,
HCP_DIP_INIT_ID, //CHRISTBD
HCP_IMGSYS_INIT_ID = HCP_DIP_INIT_ID,
HCP_DIP_FRAME_ID,
HCP_IMGSYS_FRAME_ID = HCP_DIP_FRAME_ID,
HCP_DIP_HW_TIMEOUT_ID,
HCP_IMGSYS_HW_TIMEOUT_ID = HCP_DIP_HW_TIMEOUT_ID,
HCP_IMGSYS_SW_TIMEOUT_ID,
HCP_DIP_DEQUE_DUMP_ID,
HCP_IMGSYS_DEQUE_DONE_ID,
HCP_IMGSYS_DEINIT_ID,
HCP_IMGSYS_IOVA_FDS_ADD_ID,
HCP_IMGSYS_IOVA_FDS_DEL_ID,
HCP_IMGSYS_UVA_FDS_ADD_ID,
HCP_IMGSYS_UVA_FDS_DEL_ID,
HCP_IMGSYS_SET_CONTROL_ID,
HCP_IMGSYS_GET_CONTROL_ID,
HCP_IMGSYS_CLEAR_HWTOKEN_ID,
HCP_FD_CMD_ID,
HCP_FD_FRAME_ID,
HCP_RSC_INIT_ID,
HCP_RSC_FRAME_ID,
HCP_MAX_ID,
};
/**
* module ID definition
*/
enum module_id {
MODULE_ISP = 0,
MODULE_DIP,
MODULE_IMG = MODULE_DIP,
MODULE_FD,
MODULE_RSC,
MODULE_MAX_ID,
};
/**
* mtk_hcp_register - register an hcp function
*
* @pdev: HCP platform device
* @id: HCP ID
* @handler: HCP handler
* @name: HCP name
* @priv: private data for HCP handler
*
* Return: Return 0 if hcp registers successfully, otherwise it is failed.
*/
int mtk_hcp_register(struct platform_device *pdev, enum hcp_id id,
hcp_handler_t handler, const char *name, void *priv);
/**
* mtk_hcp_unregister - unregister an hcp function
*
* @pdev: HCP platform device
* @id: HCP ID
*
* Return: Return 0 if hcp unregisters successfully, otherwise it is failed.
*/
int mtk_hcp_unregister(struct platform_device *pdev, enum hcp_id id);
/**
* mtk_hcp_send - send data from camera kernel driver to HCP and wait the
* command send to demand.
*
* @pdev: HCP platform device
* @id: HCP ID
* @buf: the data buffer
* @len: the data buffer length
* @frame_no: frame number
*
* This function is thread-safe. When this function returns,
* HCP has received the data and save the data in the workqueue.
* After that it will schedule work to dequeue to send data to CM4 or
* RED for programming register.
* Return: Return 0 if sending data successfully, otherwise it is failed.
**/
int mtk_hcp_send(struct platform_device *pdev,
enum hcp_id id, void *buf,
unsigned int len, int req_fd);
/**
* mtk_hcp_send_async - send data from camera kernel driver to HCP without
* waiting demand receives the command.
*
* @pdev: HCP platform device
* @id: HCP ID
* @buf: the data buffer
* @len: the data buffer length
* @frame_no: frame number
*
* This function is thread-safe. When this function returns,
* HCP has received the data and save the data in the workqueue.
* After that it will schedule work to dequeue to send data to CM4 or
* RED for programming register.
* Return: Return 0 if sending data successfully, otherwise it is failed.
**/
int mtk_hcp_send_async(struct platform_device *pdev,
enum hcp_id id, void *buf,
unsigned int len, int frame_no);
/**
* Callback from v4l2 layer to notify daemon apu dc status
*/
int mtk_hcp_set_apu_dc(struct platform_device *pdev,
int32_t value, size_t size);
/**
* mtk_hcp_get_plat_device - get HCP's platform device
*
* @pdev: the platform device of the module requesting HCP platform
* device for using HCP API.
*
* Return: Return NULL if it is failed.
* otherwise it is HCP's platform device
**/
struct platform_device *mtk_hcp_get_plat_device(struct platform_device *pdev);
/**
* mtk_hcp_get_current_task - get hcp driver's task struct.
*
* @pdev: HCP platform device
*
* This function returns the current task inside HCP platform device,
* which is initialized when hcp device being opened.
**/
struct task_struct *mtk_hcp_get_current_task(struct platform_device *pdev);
/**
* mtk_hcp_allocate_working_buffer - allocate driver working buffer.
*
* @pdev: HCP platform device
*
* This function allocate working buffers and store the information
* in mtk_hcp_reserve_mblock.
**/
int mtk_hcp_allocate_working_buffer(struct platform_device *pdev, unsigned int mode);
/**
* mtk_hcp_release_working_buffer - release driver working buffer.
*
* @pdev: HCP platform device
*
* This function release working buffers
**/
int mtk_hcp_release_working_buffer(struct platform_device *pdev);
void *mtk_hcp_get_gce_mem_virt(struct platform_device *pdev);
void *mtk_hcp_get_hwid_mem_virt(struct platform_device *pdev);
int mtk_hcp_get_init_info(struct platform_device *pdev, struct img_init_info *info);
int mtk_hcp_get_gce_buffer(struct platform_device *pdev);
int mtk_hcp_put_gce_buffer(struct platform_device *pdev);
/**
* mtk_hcp_purge_msg - purge messages
*
* @pdev: HCP platform device
*
* This function purges messages
**/
void mtk_hcp_purge_msg(struct platform_device *pdev);
/**
* struct hcp_mem - HCP memory information
*
* @d_va: the kernel virtual memory address of HCP extended data memory
* @d_pa: the physical memory address of HCP extended data memory
* @d_len: the length of extended data
*/
struct hcp_mem {
void *d_va;
dma_addr_t d_pa;
unsigned long d_len;
};
/**
* struct hcp_desc - hcp descriptor
*
* @handler: IPI handler
* @name: the name of IPI handler
* @priv: the private data of IPI handler
*/
struct hcp_desc {
hcp_handler_t handler;
const char *name;
void *priv;
};
struct object_id {
union {
struct send {
uint32_t hcp: 5;
uint32_t ack: 1;
uint32_t req: 10;
uint32_t seq: 16;
} __packed send;
uint32_t cmd;
};
} __packed;
#define HCP_SHARE_BUF_SIZE 388
/**
* struct share_buf - DTCM (Data Tightly-Coupled Memory) buffer shared with
* RED and HCP
*
* @id: hcp id
* @len: share buffer length
* @share_buf: share buffer data
*/
struct share_buf {
uint32_t id;
uint32_t len;
uint8_t share_data[HCP_SHARE_BUF_SIZE];
struct object_id info;
};
/**
* struct mtk_hcp - hcp driver data
* @extmem: hcp extended memory information
* @hcp_desc: hcp descriptor
* @dev: hcp struct device
* @mem_ops: memory operations
* @hcp_mutex: protect mtk_hcp (except recv_buf) and ensure only
* one client to use hcp service at a time.
* @data_mutex: protect shared buffer between kernel user send and
* user thread get&read/copy
* @file: hcp daemon file pointer
* @is_open: the flag to indicate if hcp device is open.
* @ack_wq: the wait queue for each client. When sleeping
* processes wake up, they will check the condition
* "hcp_id_ack" to run the corresponding action or
* go back to sleep.
* @hcp_id_ack: The ACKs for registered HCP function.
* @ipi_got: The flags for IPI message polling from user.
* @ipi_done: The flags for IPI message polling from user again,
* which means the previous messages has been dispatched
* done in daemon.
* @user_obj: Temporary share_buf used for hcp_msg_get.
* @hcp_devno: The hcp_devno for hcp init hcp character device
* @hcp_cdev: The point of hcp character device.
* @hcp_class: The class_create for create hcp device
* @hcp_device: hcp struct device
* @hcpname: hcp struct device name in dtsi
* @ cm4_support_list to indicate which module can run in cm4 or it will send
* to user space for running action.
* @ current_task hcp current task struct
*/
struct mtk_hcp {
atomic_t have_slb;
struct hcp_mem extmem;
struct hcp_desc hcp_desc_table[HCP_MAX_ID];
struct device *dev;
const struct vb2_mem_ops *mem_ops;
const struct mtk_hcp_data *data;
/* for protecting vcu data structure */
struct file *file;
bool is_open;
atomic_t seq;
wait_queue_head_t ack_wq[MODULE_MAX_ID];
atomic_t hcp_id_ack[HCP_MAX_ID];
wait_queue_head_t get_wq[MODULE_MAX_ID];
wait_queue_head_t poll_wq[MODULE_MAX_ID];
struct list_head chans[MODULE_MAX_ID];
struct list_head msg_list;
spinlock_t msglock;
wait_queue_head_t msg_wq;
dev_t hcp_devno;
struct cdev hcp_cdev;
struct class *hcp_class;
struct device *hcp_device;
const char *hcpname;
bool cm4_support_list[MODULE_MAX_ID];
struct task_struct *current_task;
struct workqueue_struct *daemon_notify_wq[MODULE_MAX_ID];
};
struct mtk_hcp_data {
struct mtk_hcp_reserve_mblock *mblock;
struct mtk_hcp_reserve_mblock *smblock;
unsigned int block_num;
int (*allocate)(struct mtk_hcp *hcp_dev, unsigned int smvr);
int (*release)(struct mtk_hcp *hcp_dev);
int (*get_init_info)(struct img_init_info *info);
void* (*get_gce_virt)(void);
int (*get_gce)(void);
int (*put_gce)(void);
void* (*get_hwid_virt)(void);
};
#define HCP_RESERVED_MEM (1)
#define MTK_CM4_SUPPORT (0)
#if HCP_RESERVED_MEM
/**
* struct mtk_hcp_reserve_mblock - info about memory buffer allocated in kernel
*
* @num: vb2_dc_buf
* @start_phys: starting addr(phy/iova) about allocated buffer
* @start_virt: starting addr(kva) about allocated buffer
* @start_dma: starting addr(iova) about allocated buffer
* @size: allocated buffer size
* @is_dma_buf: attribute: is_dma_buf or not
* @mmap_cnt: counter about mmap times
* @mem_priv: vb2_dc_buf
* @d_buf: dma_buf
* @fd: buffer fd
*/
struct mtk_hcp_reserve_mblock {
const char *name;
unsigned int num;
phys_addr_t start_phys;
void *start_virt;
phys_addr_t start_dma;
phys_addr_t size;
uint8_t is_dma_buf;
/*new add*/
int mmap_cnt;
void *mem_priv;
struct dma_buf *d_buf;
int fd;
struct ion_handle *pIonHandle;
struct dma_buf_attachment *attach;
struct sg_table *sgt;
struct kref kref;
};
int mtk_hcp_set_apu_dc(struct platform_device *pdev,
int32_t value, size_t size);
extern phys_addr_t mtk_hcp_get_reserve_mem_phys(
unsigned int id);
extern void *mtk_hcp_get_reserve_mem_virt(unsigned int id);
extern void mtk_hcp_set_reserve_mem_virt(unsigned int id,
void *virmem);
extern phys_addr_t mtk_hcp_get_reserve_mem_dma(
unsigned int id);
extern phys_addr_t mtk_hcp_get_reserve_mem_size(
unsigned int id);
extern uint32_t mtk_hcp_get_reserve_mem_fd(
unsigned int id);
extern void mtk_hcp_set_reserve_mem_fd(unsigned int id,
uint32_t fd);
#endif
#endif /* _MTK_HCP_H */