kernel_samsung_a34x-permissive/drivers/misc/mediatek/pseudo_m4u/pseudo_m4u.h
2024-04-28 15:51:13 +02:00

380 lines
10 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#ifndef __PSEUDO_M4U_PORT_H__
#define __PSEUDO_M4U_PORT_H__
#include <linux/ioctl.h>
#include <linux/fs.h>
#include <linux/list.h>
#ifdef CONFIG_ARM64
#include <linux/iova.h>
#endif
#include <linux/iommu.h>
#define M4U_PAGE_SIZE 0x1000
#define M4U_GET_PAGE_NUM(va, size) \
(((((unsigned long)va)&(M4U_PAGE_SIZE-1)) +\
(size)+(M4U_PAGE_SIZE-1)) >> 12)
#define NORMAL_M4U_NUMBER 1
#define TOTAL_M4U_NUM 2
#define M4U_REG_SIZE 0x5e0
#define M4U_PORT_NR 28
#define SMI_LARB_NR 9
#define M4U_PAGE_MASK 0xfff
/* public flags */
/* engine access this buffer in sequncial way. */
#define M4U_FLAGS_SEQ_ACCESS (1<<0)
/* fix allocation, we will use mva user specified. */
#define M4U_FLAGS_FIX_MVA (1<<1)
#define M4U_FLAGS_SEC_SHAREABLE (1<<2) /* the mva will share in SWd */
/* the allocator will search free mva from user specified. */
#define M4U_FLAGS_START_FROM (1<<3)
#define M4U_FLAGS_SG_READY (1<<4)
/* optimized, recommand to use */
enum M4U_CACHE_SYNC_ENUM {
M4U_CACHE_CLEAN_BY_RANGE,
M4U_CACHE_INVALID_BY_RANGE,
M4U_CACHE_FLUSH_BY_RANGE,
M4U_CACHE_CLEAN_ALL,
M4U_CACHE_INVALID_ALL,
M4U_CACHE_FLUSH_ALL,
};
/* port related: virtuality, security, distance */
struct M4U_PORT_STRUCT {
/*hardware port ID, defined in M4U_PORT_ID_ENUM*/
int ePortID;
unsigned int Virtuality;
unsigned int Security;
unsigned int domain; /*domain : 0 1 2 3*/
unsigned int Distance;
unsigned int Direction; /* 0:- 1:+*/
};
enum M4U_DMA_DIR_ENUM {
M4U_DMA_READ_WRITE = 0,
M4U_DMA_READ = 1,
M4U_DMA_WRITE = 2,
M4U_DMA_NONE_OP = 3,
};
/* module related: alloc/dealloc MVA buffer */
struct M4U_MOUDLE_STRUCT {
int port;
unsigned long BufAddr;
unsigned int BufSize;
unsigned int prot;
unsigned int MVAStart;
unsigned int MVAEnd;
unsigned int flags;
};
enum M4U_DMA_TYPE {
M4U_DMA_MAP_AREA,
M4U_DMA_UNMAP_AREA,
M4U_DMA_FLUSH_BY_RANGE,
};
enum M4U_DMA_DIR {
M4U_DMA_FROM_DEVICE,
M4U_DMA_TO_DEVICE,
M4U_DMA_BIDIRECTIONAL,
};
struct M4U_CACHE_STRUCT {
int port;
enum M4U_CACHE_SYNC_ENUM eCacheSync;
unsigned long va;
unsigned int size;
unsigned int mva;
};
struct M4U_DMA_STRUCT {
int port;
enum M4U_DMA_TYPE eDMAType;
enum M4U_DMA_DIR eDMADir;
unsigned long va;
unsigned int size;
unsigned int mva;
};
struct M4U_PERF_COUNT {
unsigned int transaction_cnt;
unsigned int main_tlb_miss_cnt;
unsigned int pfh_tlb_miss_cnt;
unsigned int pfh_cnt;
};
struct mva_info_t {
struct list_head link;
unsigned long bufAddr;
unsigned int mvaStart;
unsigned int size;
int eModuleId;
unsigned int flags;
int security;
int cache_coherent;
unsigned int mapped_kernel_va_for_debug;
};
struct m4u_buf_info_t {
struct list_head link;
unsigned long va;
unsigned int mva;
unsigned int size;
int port;
unsigned int prot;
unsigned int flags;
struct sg_table *sg_table;
unsigned int mva_align;
unsigned int size_align;
int seq_id;
unsigned long mapped_kernel_va_for_debug;
};
struct m4u_client_t {
/* mutex to protect mvaList */
/* should get this mutex whenever add/delete/interate mvaList */
struct mutex dataMutex;
pid_t open_pid;
pid_t open_tgid;
struct list_head mvaList;
};
struct port_mva_info_t {
int emoduleid;
unsigned long va;
unsigned int buf_size;
int security;
int cache_coherent;
unsigned int flags;
unsigned int iova_start;
unsigned int iova_end;
unsigned int mva;
};
struct m4u_device {
/*struct miscdevice dev;*/
struct proc_dir_entry *m4u_dev_proc_entry;
};
/* we use this for trace the mva<-->sg_table relation ship */
struct mva_sglist {
struct list_head list;
unsigned int mva;
struct iova *iova;
struct sg_table *table;
};
struct pseudo_device {
struct device *dev; /* record the device for config mmu use. */
int larbid; /* the larb id of this device*/
bool mmuen; /* whether this larb have been configed or not. */
};
struct m4u_port_array {
#define M4U_PORT_ATTR_EN (1<<0)
#define M4U_PORT_ATTR_VIRTUAL (1<<1)
#define M4U_PORT_ATTR_SEC (1<<2)
unsigned char ports[M4U_PORT_NR];
};
extern unsigned long max_pfn;
extern unsigned char *pMlock_cnt;
extern unsigned int mlock_cnt_size;
extern unsigned long pagetable_pa;
#ifndef dmac_map_area
#ifdef CONFIG_ARM64
#define dmac_map_area __dma_map_area
#else
#define dmac_map_area v7_dma_map_area
extern void dmac_map_area(const void *, size_t, int);
#endif
#endif
#ifndef dmac_unmap_area
#ifdef CONFIG_ARM64
#define dmac_unmap_area __dma_unmap_area
#else
#define dmac_unmap_area v7_dma_unmap_area
extern void dmac_unmap_area(const void *, size_t, int);
#endif
#endif
#ifndef dmac_flush_range
#define dmac_flush_range __dma_flush_range
#endif
/* function prototype */
#ifndef outer_clean_all
#define outer_clean_all(...)
#endif
#ifndef outer_flush_all
#define outer_flush_all(...)
#endif
#ifndef IOVA_PFN
#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
#endif
#if ((defined(CONFIG_MTK_IN_HOUSE_TEE_SUPPORT)) &&\
(defined(CONFIG_MTK_SEC_VIDEO_PATH_SUPPORT)))
#define M4U_TEE_SERVICE_ENABLE
#endif
#ifdef M4U_TEE_SERVICE_ENABLE
unsigned int mtk_init_tz_m4u(void);
#endif
int m4u_config_port(struct M4U_PORT_STRUCT *pM4uPort);
struct device *m4u_get_larbdev(int portid);
struct sg_table *m4u_find_sgtable(unsigned int mva);
struct sg_table *m4u_del_sgtable(unsigned int mva);
struct sg_table *m4u_add_sgtable(struct mva_sglist *mva_sg);
int m4u_va_align(unsigned long *addr, unsigned int *size);
int m4u_alloc_mva(int eModuleID,
unsigned long BufAddr,
unsigned int BufSize,
int security, int cache_coherent, unsigned int *pRetMVABuf);
/* struct sg_table *pseudo_get_sg(int portid, unsigned long va, int size); */
struct sg_table *m4u_create_sgtable(unsigned long va, unsigned int size);
int pseudo_alloc_mva(struct m4u_client_t *client, int port,
unsigned long va, struct sg_table *sg_table,
unsigned int size, unsigned int prot,
unsigned int flags, unsigned int *pMva);
int pseudo_dealloc_mva(struct m4u_client_t *client, int port,
unsigned int mva);
int __m4u_dealloc_mva(int eModuleID, const unsigned long BufAddr,
const unsigned int BufSize, const unsigned int MVA,
struct sg_table *sg_table);
int m4u_dealloc_mva(int eModuleID,
const unsigned long BufAddr, const unsigned int BufSize,
const unsigned int MVA);
int m4u_dealloc_mva_sg(int eModuleID,
struct sg_table *sg_table,
const unsigned int BufSize, const unsigned int MVA);
int m4u_alloc_mva_sg(struct port_mva_info_t *port_info,
struct sg_table *sg_table);
int pseudo_config_port_tee(int kernelport);
int m4u_mva_map_kernel(unsigned int mva,
unsigned long size, unsigned long *map_va,
unsigned int *map_size);
int m4u_mva_unmap_kernel(unsigned int mva,
unsigned long size, unsigned long map_va);
extern void smp_inner_dcache_flush_all(void);
extern phys_addr_t mtkfb_get_fb_base(void);
extern size_t mtkfb_get_fb_size(void);
#ifdef CONFIG_ARM64
struct iova *__alloc_iova(struct iova_domain *iovad, size_t size,
dma_addr_t dma_limit);
void __free_iova(struct iova_domain *iovad, struct iova *iova);
#endif
void __iommu_dma_unmap(struct iommu_domain *domain, dma_addr_t dma_addr);
static inline int mtk_smi_vp_setting(bool osd_4k)
{
return 0;
}
static inline int mtk_smi_init_setting(void)
{
return 0;
}
extern unsigned long mtk_get_pgt_base(void);
bool m4u_portid_valid(const int portID);
const char *m4u_get_port_name(const int portID);
/* IOCTL commnad */
#define MTK_M4U_MAGICNO 'g'
#define MTK_M4U_T_POWER_ON _IOW(MTK_M4U_MAGICNO, 0, int)
#define MTK_M4U_T_POWER_OFF _IOW(MTK_M4U_MAGICNO, 1, int)
#define MTK_M4U_T_DUMP_REG _IOW(MTK_M4U_MAGICNO, 2, int)
#define MTK_M4U_T_DUMP_INFO _IOW(MTK_M4U_MAGICNO, 3, int)
#define MTK_M4U_T_ALLOC_MVA _IOWR(MTK_M4U_MAGICNO, 4, int)
#define MTK_M4U_T_DEALLOC_MVA _IOW(MTK_M4U_MAGICNO, 5, int)
#define MTK_M4U_T_INSERT_TLB_RANGE _IOW(MTK_M4U_MAGICNO, 6, int)
#define MTK_M4U_T_INVALID_TLB_RANGE _IOW(MTK_M4U_MAGICNO, 7, int)
#define MTK_M4U_T_INVALID_TLB_ALL _IOW(MTK_M4U_MAGICNO, 8, int)
#define MTK_M4U_T_MANUAL_INSERT_ENTRY _IOW(MTK_M4U_MAGICNO, 9, int)
#define MTK_M4U_T_CACHE_SYNC _IOW(MTK_M4U_MAGICNO, 10, int)
#define MTK_M4U_T_CONFIG_PORT _IOW(MTK_M4U_MAGICNO, 11, int)
#define MTK_M4U_T_CONFIG_ASSERT _IOW(MTK_M4U_MAGICNO, 12, int)
#define MTK_M4U_T_INSERT_WRAP_RANGE _IOW(MTK_M4U_MAGICNO, 13, int)
#define MTK_M4U_T_MONITOR_START _IOW(MTK_M4U_MAGICNO, 14, int)
#define MTK_M4U_T_MONITOR_STOP _IOW(MTK_M4U_MAGICNO, 15, int)
#define MTK_M4U_T_RESET_MVA_RELEASE_TLB _IOW(MTK_M4U_MAGICNO, 16, int)
#define MTK_M4U_T_CONFIG_PORT_ROTATOR _IOW(MTK_M4U_MAGICNO, 17, int)
#define MTK_M4U_T_QUERY_MVA _IOW(MTK_M4U_MAGICNO, 18, int)
#define MTK_M4U_T_M4UDrv_CONSTRUCT _IOW(MTK_M4U_MAGICNO, 19, int)
#define MTK_M4U_T_M4UDrv_DECONSTRUCT _IOW(MTK_M4U_MAGICNO, 20, int)
#define MTK_M4U_T_DUMP_PAGETABLE _IOW(MTK_M4U_MAGICNO, 21, int)
#define MTK_M4U_T_REGISTER_BUFFER _IOW(MTK_M4U_MAGICNO, 22, int)
#define MTK_M4U_T_CACHE_FLUSH_ALL _IOW(MTK_M4U_MAGICNO, 23, int)
#define MTK_M4U_T_CONFIG_PORT_ARRAY _IOW(MTK_M4U_MAGICNO, 26, int)
#define MTK_M4U_T_CONFIG_MAU _IOW(MTK_M4U_MAGICNO, 27, int)
#define MTK_M4U_T_CONFIG_TF _IOW(MTK_M4U_MAGICNO, 28, int)
#define MTK_M4U_T_DMA_OP _IOW(MTK_M4U_MAGICNO, 29, int)
#if IS_ENABLED(CONFIG_COMPAT)
struct COMPAT_M4U_MOUDLE_STRUCT {
compat_uint_t port;
compat_ulong_t BufAddr;
compat_uint_t BufSize;
compat_uint_t prot;
compat_uint_t MVAStart;
compat_uint_t MVAEnd;
compat_uint_t flags;
};
struct COMPAT_M4U_CACHE_STRUCT {
compat_uint_t port;
compat_uint_t eCacheSync;
compat_ulong_t va;
compat_uint_t size;
compat_uint_t mva;
};
#define COMPAT_MTK_M4U_T_ALLOC_MVA _IOWR(MTK_M4U_MAGICNO, 4, int)
#define COMPAT_MTK_M4U_T_DEALLOC_MVA _IOW(MTK_M4U_MAGICNO, 5, int)
#define COMPAT_MTK_M4U_T_CACHE_SYNC _IOW(MTK_M4U_MAGICNO, 10, int)
#endif
#ifdef M4U_TEE_SERVICE_ENABLE
extern bool m4u_tee_en;
int smi_reg_restore_sec(void);
int smi_reg_backup_sec(void);
/*int m4u_config_port_array_tee(unsigned char* port_array);*/
int m4u_dump_secpgd(unsigned int larbid, unsigned int portid,
unsigned long fault_mva);
#endif
#endif