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

2093 lines
58 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2015 MediaTek Inc.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/mm_types.h>
#include <linux/mm.h>
#include <linux/jiffies.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <asm/page.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <mt-plat/sync_write.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include "inc/camera_fdvt.h"
#include <asm/cacheflush.h>
#define FDVT_USE_GCE
#ifdef FDVT_USE_GCE
#include <cmdq_core.h>
#include <cmdq_record.h>
#define CMDQ_REG_MASK 0xffffffff
#endif
#if IS_ENABLED(CONFIG_COMPAT)
/* 64 bit */
#include <linux/fs.h>
#include <linux/compat.h>
#endif
#if !IS_ENABLED(CONFIG_MTK_CLKMGR)
#include <linux/clk.h>
#endif
#if IS_ENABLED(CONFIG_MTK_CLKMGR)
#include <mach/mt_clkmgr.h>
#endif
#if IS_ENABLED(CONFIG_PM_SLEEP)
#include <linux/pm_wakeup.h>
#endif
#if IS_ENABLED(CONFIG_PM_SLEEP)
struct wakeup_source fdvt_wake_lock;
#endif
#include <smi_public.h>
#include <m4u.h>
#define FDVT_DEVNAME "camera-fdvt"
#define LOG_VRB(format, args...) \
pr_debug("FDVT [%s] " format, __func__, ##args)
#define LOG_DBG(format, args...) \
pr_debug("FDVT [%s] " format, __func__, ##args)
#define LOG_INF(format, args...) \
pr_info("FDVT [%s] " format, __func__, ##args)
#define LOG_WRN(format, args...) \
pr_info("FDVT [%s] WARNING: " format, __func__, ##args)
#define LOG_ERR(format, args...) \
pr_info("FDVT [%s, line%04d] ERROR: " format, __func__, __LINE__, ##args)
#define LOG_AST(format, args...) \
pr_info("FDVT [%s, line%04d] ASSERT: " format, __func__, __LINE__, ##args)
#define LDVT_EARLY_PORTING_NO_CCF 0
#if LDVT_EARLY_PORTING_NO_CCF
void __iomem *IMGSYS_CONFIG_BASE;
void __iomem *CAMSYS_CONFIG_BASE;
#endif
static dev_t FDVT_devno;
static struct cdev *FDVT_cdev;
static struct class *FDVT_class;
static wait_queue_head_t g_FDVTWQ;
static u32 g_FDVTIRQ = 0, g_FDVTIRQMSK = 0x00000001;
static DEFINE_SPINLOCK(g_spinLock);
static unsigned int g_drvOpened;
static unsigned int g_isSuspend;
static u8 *pBuff;
static u8 *pread_buf;
static u32 buf_size = 1024;
#define FDVT_DRAM_REGCNT 208
#define FDVT_WR32(data, addr) mt_reg_sync_writel(data, addr)
struct FDVTDBuffRegMap {
unsigned int u4Addr[FDVT_DRAM_REGCNT];
unsigned int u4Data[FDVT_DRAM_REGCNT];
unsigned int u4Counter;
};
#define FDVTDBuffRegMap struct FDVTDBuffRegMap
#if IS_ENABLED(CONFIG_OF)
enum {
FDVT_IRQ_IDX = 0,
FDVT_IRQ_IDX_NUM
};
enum {
FDVT_BASE_ADDR = 0,
FDVT_BASEADDR_NUM
};
#if LDVT_EARLY_PORTING_NO_CCF
#else
struct FD_CLK_STRUCT {
struct clk *CG_IMGSYS_FDVT;
} FD_CLK_STRUCT;
struct FD_CLK_STRUCT fd_clk;
#endif
static unsigned long gFDVT_Irq[FDVT_IRQ_IDX_NUM];
static unsigned long gFDVT_Reg[FDVT_BASEADDR_NUM];
/* static void __iomem *g_isp_base_dase; */
/* static void __iomem *g_isp_inner_base_dase; */
/* static void __iomem *g_imgsys_config_base_dase; */
#define FDVT_ADDR (gFDVT_Reg[FDVT_BASE_ADDR])
#else
#define FDVT_ADDR FDVT_BASE
#endif
#define FDVT_BASE_HW 0x1502B000
static FDVTDBuffRegMap pFDVTReadBuffer;
static FDVTDBuffRegMap pFDVTWriteBuffer;
#if (MTK_SECURE_FD_SUPPORT == 1)
static FDVTSecureMeta g_fdvt_secmeta;
#endif
/* register map */
#define FDVT_START (FDVT_ADDR+0x0)
#define FDVT_ENABLE (FDVT_ADDR+0x4)
#define FDVT_RS (FDVT_ADDR+0x8)
#define FDVT_RSCON_BASE_ADR (FDVT_ADDR+0xC)
#define FDVT_RGB2Y0 (FDVT_ADDR+0x10)
#define FDVT_RGB2Y1 (FDVT_ADDR+0x14)
#define FDVT_INVG0 (FDVT_ADDR+0x18)
#define FDVT_INVG1 (FDVT_ADDR+0x1C)
#define FDVT_INVG2 (FDVT_ADDR+0x20)
#define FDVT_FNUM_0 (FDVT_ADDR+0x24)
#define FDVT_FNUM_1 (FDVT_ADDR+0x28)
#define FDVT_FNUM_2 (FDVT_ADDR+0x2C)
#define FDVT_FNUM_3 (FDVT_ADDR+0x30)
#define FDVT_T_FNUM_4 (FDVT_ADDR+0x34)
#define FDVT_T_FNUM_5 (FDVT_ADDR+0x38)
#define FDVT_T_FNUM_6 (FDVT_ADDR+0x3C)
#define FDVT_T_FNUM_7 (FDVT_ADDR+0x40)
#define FDVT_FF_NUM_0 (FDVT_ADDR+0x44)
#define FDVT_FF_NUM_1 (FDVT_ADDR+0x48)
#define FDVT_FF_NUM_2 (FDVT_ADDR+0x4C)
#define FDVT_FF_NUM_3 (FDVT_ADDR+0x50)
#define FDVT_FF_BASE_ADR_0 (FDVT_ADDR+0x54)
#define FDVT_FF_BASE_ADR_1 (FDVT_ADDR+0x58)
#define FDVT_FF_BASE_ADR_2 (FDVT_ADDR+0x5C)
#define FDVT_FF_BASE_ADR_3 (FDVT_ADDR+0x60)
#define FDVT_FF_BASE_ADR_4 (FDVT_ADDR+0x64)
#define FDVT_FF_BASE_ADR_5 (FDVT_ADDR+0x68)
#define FDVT_FF_BASE_ADR_6 (FDVT_ADDR+0x6C)
#define FDVT_FF_BASE_ADR_7 (FDVT_ADDR+0x70)
#define FDVT_RMAP_0 (FDVT_ADDR+0x74)
#define FDVT_RMAP_1 (FDVT_ADDR+0x78)
#define FDVT_FD (FDVT_ADDR+0x7C)
#define FDVT_FD_CON_BASE_ADR (FDVT_ADDR+0x80)
#define FDVT_GFD (FDVT_ADDR+0x84)
#define FDVT_LFD (FDVT_ADDR+0x88)
#define FDVT_GFD_POS_0 (FDVT_ADDR+0x8C)
#define FDVT_GFD_POS_1 (FDVT_ADDR+0x90)
#define FDVT_GFD_DET0 (FDVT_ADDR+0x94)
#define FDVT_GFD_DET1 (FDVT_ADDR+0x98)
#define FDVT_FD_RLT_BASE_ADR (FDVT_ADDR+0x9C)
#define FDVT_LFD_INFO_CTRL_0 (FDVT_ADDR+0xA4)
#define FDVT_LFD_INFO_XPOS_0 (FDVT_ADDR+0xA8)
#define FDVT_LFD_INFO_YPOS_0 (FDVT_ADDR+0xAC)
#define FDVT_LFD_INFO_CTRL_1 (FDVT_ADDR+0xB0)
#define FDVT_LFD_INFO_XPOS_1 (FDVT_ADDR+0xB4)
#define FDVT_LFD_INFO_YPOS_1 (FDVT_ADDR+0xB8)
#define FDVT_LFD_INFO_CTRL_2 (FDVT_ADDR+0xBC)
#define FDVT_LFD_INFO_XPOS_2 (FDVT_ADDR+0xC0)
#define FDVT_LFD_INFO_YPOS_2 (FDVT_ADDR+0xC4)
#define FDVT_LFD_INFO_CTRL_3 (FDVT_ADDR+0xC8)
#define FDVT_LFD_INFO_XPOS_3 (FDVT_ADDR+0xCC)
#define FDVT_LFD_INFO_YPOS_3 (FDVT_ADDR+0xD0)
#define FDVT_LFD_INFO_CTRL_4 (FDVT_ADDR+0xD4)
#define FDVT_LFD_INFO_XPOS_4 (FDVT_ADDR+0xD8)
#define FDVT_LFD_INFO_YPOS_4 (FDVT_ADDR+0xDC)
#define FDVT_LFD_INFO_CTRL_5 (FDVT_ADDR+0xE0)
#define FDVT_LFD_INFO_XPOS_5 (FDVT_ADDR+0xE4)
#define FDVT_LFD_INFO_YPOS_5 (FDVT_ADDR+0xE8)
#define FDVT_LFD_INFO_CTRL_6 (FDVT_ADDR+0xEC)
#define FDVT_LFD_INFO_XPOS_6 (FDVT_ADDR+0xF0)
#define FDVT_LFD_INFO_YPOS_6 (FDVT_ADDR+0xF4)
#define FDVT_LFD_INFO_CTRL_7 (FDVT_ADDR+0xF8)
#define FDVT_LFD_INFO_XPOS_7 (FDVT_ADDR+0xFC)
#define FDVT_LFD_INFO_YPOS_7 (FDVT_ADDR+0x100)
#define FDVT_LFD_INFO_CTRL_8 (FDVT_ADDR+0x104)
#define FDVT_LFD_INFO_XPOS_8 (FDVT_ADDR+0x108)
#define FDVT_LFD_INFO_YPOS_8 (FDVT_ADDR+0x10C)
#define FDVT_LFD_INFO_CTRL_9 (FDVT_ADDR+0x110)
#define FDVT_LFD_INFO_XPOS_9 (FDVT_ADDR+0x114)
#define FDVT_LFD_INFO_YPOS_9 (FDVT_ADDR+0x118)
#define FDVT_LFD_INFO_CTRL_10 (FDVT_ADDR+0x11C)
#define FDVT_LFD_INFO_XPOS_10 (FDVT_ADDR+0x120)
#define FDVT_LFD_INFO_YPOS_10 (FDVT_ADDR+0x124)
#define FDVT_LFD_INFO_CTRL_11 (FDVT_ADDR+0x128)
#define FDVT_LFD_INFO_XPOS_11 (FDVT_ADDR+0x12C)
#define FDVT_LFD_INFO_YPOS_11 (FDVT_ADDR+0x130)
#define FDVT_LFD_INFO_CTRL_12 (FDVT_ADDR+0x134)
#define FDVT_LFD_INFO_XPOS_12 (FDVT_ADDR+0x138)
#define FDVT_LFD_INFO_YPOS_12 (FDVT_ADDR+0x13C)
#define FDVT_LFD_INFO_CTRL_13 (FDVT_ADDR+0x140)
#define FDVT_LFD_INFO_XPOS_13 (FDVT_ADDR+0x144)
#define FDVT_LFD_INFO_YPOS_13 (FDVT_ADDR+0x148)
#define FDVT_LFD_INFO_CTRL_14 (FDVT_ADDR+0x14C)
#define FDVT_LFD_INFO_XPOS_14 (FDVT_ADDR+0x150)
#define FDVT_LFD_INFO_YPOS_14 (FDVT_ADDR+0x154)
#define FDVT_TC_ENABLE_RESULT (FDVT_ADDR+0x158)
#define FDVT_INT_EN (FDVT_ADDR+0x15C)
#define FDVT_SRC_WD_HT (FDVT_ADDR+0x160)
#define FDVT_INT (FDVT_ADDR+0x168)
#define FDVT_DEBUG_INFO_1 (FDVT_ADDR+0x16C)
#define FDVT_DEBUG_INFO_2 (FDVT_ADDR+0x170)
#define FDVT_DEBUG_INFO_3 (FDVT_ADDR+0x174)
#define FDVT_RESULT (FDVT_ADDR+0x178)
#define FDVT_SPARE_CELL (FDVT_ADDR+0x198)
#define FDVT_CTRL (FDVT_ADDR+0x19C)
#define FDVT_VERSION (FDVT_ADDR+0x1A0)
#define FDVT_FF_NUM_4 (FDVT_ADDR+0x1C4)
#define FDVT_FF_NUM_5 (FDVT_ADDR+0x1C8)
#define FDVT_FF_NUM_6 (FDVT_ADDR+0x1CC)
#define FDVT_FF_NUM_7 (FDVT_ADDR+0x1D0)
#define FDVT_FF_NUM_8 (FDVT_ADDR+0x1D4)
#define FDVT_FF_BASE_ADR_8 (FDVT_ADDR+0x1A4)
#define FDVT_FF_BASE_ADR_9 (FDVT_ADDR+0x1A8)
#define FDVT_FF_BASE_ADR_10 (FDVT_ADDR+0x1AC)
#define FDVT_FF_BASE_ADR_11 (FDVT_ADDR+0x1B0)
#define FDVT_FF_BASE_ADR_12 (FDVT_ADDR+0x1B4)
#define FDVT_FF_BASE_ADR_13 (FDVT_ADDR+0x1B8)
#define FDVT_FF_BASE_ADR_14 (FDVT_ADDR+0x1BC)
#define FDVT_FF_BASE_ADR_15 (FDVT_ADDR+0x1C0)
#define FDVT_FF_BASE_ADR_16 (FDVT_ADDR+0x1D8)
#define FDVT_FF_BASE_ADR_17 (FDVT_ADDR+0x1DC)
/* register map for HW usage*/
#define FDVT_START_HW (FDVT_BASE_HW+0x0)
#define FDVT_ENABLE_HW (FDVT_BASE_HW+0x4)
#define FDVT_RS_HW (FDVT_BASE_HW+0x8)
#define FDVT_RSCON_BASE_ADR_HW (FDVT_BASE_HW+0xC)
#define FDVT_RGB2Y0_HW (FDVT_BASE_HW+0x10)
#define FDVT_RGB2Y1_HW (FDVT_BASE_HW+0x14)
#define FDVT_INVG0_HW (FDVT_BASE_HW+0x18)
#define FDVT_INVG1_HW (FDVT_BASE_HW+0x1C)
#define FDVT_INVG2_HW (FDVT_BASE_HW+0x20)
#define FDVT_FNUM_0_HW (FDVT_BASE_HW+0x24)
#define FDVT_FNUM_1_HW (FDVT_BASE_HW+0x28)
#define FDVT_FNUM_2_HW (FDVT_BASE_HW+0x2C)
#define FDVT_FNUM_3_HW (FDVT_BASE_HW+0x30)
#define FDVT_T_FNUM_4_HW (FDVT_BASE_HW+0x34)
#define FDVT_T_FNUM_5_HW (FDVT_BASE_HW+0x38)
#define FDVT_T_FNUM_6_HW (FDVT_BASE_HW+0x3C)
#define FDVT_T_FNUM_7_HW (FDVT_BASE_HW+0x40)
#define FDVT_FF_NUM_0_HW (FDVT_BASE_HW+0x44)
#define FDVT_FF_NUM_1_HW (FDVT_BASE_HW+0x48)
#define FDVT_FF_NUM_2_HW (FDVT_BASE_HW+0x4C)
#define FDVT_FF_NUM_3_HW (FDVT_BASE_HW+0x50)
#define FDVT_FF_BASE_ADR_0_HW (FDVT_BASE_HW+0x54)
#define FDVT_FF_BASE_ADR_1_HW (FDVT_BASE_HW+0x58)
#define FDVT_FF_BASE_ADR_2_HW (FDVT_BASE_HW+0x5C)
#define FDVT_FF_BASE_ADR_3_HW (FDVT_BASE_HW+0x60)
#define FDVT_FF_BASE_ADR_4_HW (FDVT_BASE_HW+0x64)
#define FDVT_FF_BASE_ADR_5_HW (FDVT_BASE_HW+0x68)
#define FDVT_FF_BASE_ADR_6_HW (FDVT_BASE_HW+0x6C)
#define FDVT_FF_BASE_ADR_7_HW (FDVT_BASE_HW+0x70)
#define FDVT_RMAP_0_HW (FDVT_BASE_HW+0x74)
#define FDVT_RMAP_1_HW (FDVT_BASE_HW+0x78)
#define FDVT_FD_HW (FDVT_BASE_HW+0x7C)
#define FDVT_FD_CON_BASE_ADR_HW (FDVT_BASE_HW+0x80)
#define FDVT_GFD_HW (FDVT_BASE_HW+0x84)
#define FDVT_LFD_HW (FDVT_BASE_HW+0x88)
#define FDVT_GFD_POS_0_HW (FDVT_BASE_HW+0x8C)
#define FDVT_GFD_POS_1_HW (FDVT_BASE_HW+0x90)
#define FDVT_GFD_DET0_HW (FDVT_BASE_HW+0x94)
#define FDVT_GFD_DET1_HW (FDVT_BASE_HW+0x98)
#define FDVT_FD_RLT_BASE_ADR_HW (FDVT_BASE_HW+0x9C)
#define FDVT_LFD_INFO_CTRL_0_HW (FDVT_BASE_HW+0xA4)
#define FDVT_LFD_INFO_XPOS_0_HW (FDVT_BASE_HW+0xA8)
#define FDVT_LFD_INFO_YPOS_0_HW (FDVT_BASE_HW+0xAC)
#define FDVT_LFD_INFO_CTRL_1_HW (FDVT_BASE_HW+0xB0)
#define FDVT_LFD_INFO_XPOS_1_HW (FDVT_BASE_HW+0xB4)
#define FDVT_LFD_INFO_YPOS_1_HW (FDVT_BASE_HW+0xB8)
#define FDVT_LFD_INFO_CTRL_2_HW (FDVT_BASE_HW+0xBC)
#define FDVT_LFD_INFO_XPOS_2_HW (FDVT_BASE_HW+0xC0)
#define FDVT_LFD_INFO_YPOS_2_HW (FDVT_BASE_HW+0xC4)
#define FDVT_LFD_INFO_CTRL_3_HW (FDVT_BASE_HW+0xC8)
#define FDVT_LFD_INFO_XPOS_3_HW (FDVT_BASE_HW+0xCC)
#define FDVT_LFD_INFO_YPOS_3_HW (FDVT_BASE_HW+0xD0)
#define FDVT_LFD_INFO_CTRL_4_HW (FDVT_BASE_HW+0xD4)
#define FDVT_LFD_INFO_XPOS_4_HW (FDVT_BASE_HW+0xD8)
#define FDVT_LFD_INFO_YPOS_4_HW (FDVT_BASE_HW+0xDC)
#define FDVT_LFD_INFO_CTRL_5_HW (FDVT_BASE_HW+0xE0)
#define FDVT_LFD_INFO_XPOS_5_HW (FDVT_BASE_HW+0xE4)
#define FDVT_LFD_INFO_YPOS_5_HW (FDVT_BASE_HW+0xE8)
#define FDVT_LFD_INFO_CTRL_6_HW (FDVT_BASE_HW+0xEC)
#define FDVT_LFD_INFO_XPOS_6_HW (FDVT_BASE_HW+0xF0)
#define FDVT_LFD_INFO_YPOS_6_HW (FDVT_BASE_HW+0xF4)
#define FDVT_LFD_INFO_CTRL_7_HW (FDVT_BASE_HW+0xF8)
#define FDVT_LFD_INFO_XPOS_7_HW (FDVT_BASE_HW+0xFC)
#define FDVT_LFD_INFO_YPOS_7_HW (FDVT_BASE_HW+0x100)
#define FDVT_LFD_INFO_CTRL_8_HW (FDVT_BASE_HW+0x104)
#define FDVT_LFD_INFO_XPOS_8_HW (FDVT_BASE_HW+0x108)
#define FDVT_LFD_INFO_YPOS_8_HW (FDVT_BASE_HW+0x10C)
#define FDVT_LFD_INFO_CTRL_9_HW (FDVT_BASE_HW+0x110)
#define FDVT_LFD_INFO_XPOS_9_HW (FDVT_BASE_HW+0x114)
#define FDVT_LFD_INFO_YPOS_9_HW (FDVT_BASE_HW+0x118)
#define FDVT_LFD_INFO_CTRL_10_HW (FDVT_BASE_HW+0x11C)
#define FDVT_LFD_INFO_XPOS_10_HW (FDVT_BASE_HW+0x120)
#define FDVT_LFD_INFO_YPOS_10_HW (FDVT_BASE_HW+0x124)
#define FDVT_LFD_INFO_CTRL_11_HW (FDVT_BASE_HW+0x128)
#define FDVT_LFD_INFO_XPOS_11_HW (FDVT_BASE_HW+0x12C)
#define FDVT_LFD_INFO_YPOS_11_HW (FDVT_BASE_HW+0x130)
#define FDVT_LFD_INFO_CTRL_12_HW (FDVT_BASE_HW+0x134)
#define FDVT_LFD_INFO_XPOS_12_HW (FDVT_BASE_HW+0x138)
#define FDVT_LFD_INFO_YPOS_12_HW (FDVT_BASE_HW+0x13C)
#define FDVT_LFD_INFO_CTRL_13_HW (FDVT_BASE_HW+0x140)
#define FDVT_LFD_INFO_XPOS_13_HW (FDVT_BASE_HW+0x144)
#define FDVT_LFD_INFO_YPOS_13_HW (FDVT_BASE_HW+0x148)
#define FDVT_LFD_INFO_CTRL_14_HW (FDVT_BASE_HW+0x14C)
#define FDVT_LFD_INFO_XPOS_14_HW (FDVT_BASE_HW+0x150)
#define FDVT_LFD_INFO_YPOS_14_HW (FDVT_BASE_HW+0x154)
#define FDVT_TC_ENABLE_RESULT_HW (FDVT_BASE_HW+0x158)
#define FDVT_INT_EN_HW (FDVT_BASE_HW+0x15C)
#define FDVT_SRC_WD_HT_HW (FDVT_BASE_HW+0x160)
#define FDVT_INT_HW (FDVT_BASE_HW+0x168)
#define FDVT_DEBUG_INFO_1_HW (FDVT_BASE_HW+0x16C)
#define FDVT_DEBUG_INFO_2_HW (FDVT_BASE_HW+0x170)
#define FDVT_DEBUG_INFO_3_HW (FDVT_BASE_HW+0x174)
#define FDVT_RESULT_HW (FDVT_BASE_HW+0x178)
#define FDVT_SPARE_CELL_HW (FDVT_BASE_HW+0x198)
#define FDVT_CTRL_HW (FDVT_BASE_HW+0x19C)
#define FDVT_VERSION_HW (FDVT_BASE_HW+0x1A0)
#define FDVT_FF_NUM_4_HW (FDVT_BASE_HW+0x1C4)
#define FDVT_FF_NUM_5_HW (FDVT_BASE_HW+0x1C8)
#define FDVT_FF_NUM_6_HW (FDVT_BASE_HW+0x1CC)
#define FDVT_FF_NUM_7_HW (FDVT_BASE_HW+0x1D0)
#define FDVT_FF_NUM_8_HW (FDVT_BASE_HW+0x1D4)
#define FDVT_FF_BASE_ADR_8_HW (FDVT_BASE_HW+0x1A4)
#define FDVT_FF_BASE_ADR_9_HW (FDVT_BASE_HW+0x1A8)
#define FDVT_FF_BASE_ADR_10_HW (FDVT_BASE_HW+0x1AC)
#define FDVT_FF_BASE_ADR_11_HW (FDVT_BASE_HW+0x1B0)
#define FDVT_FF_BASE_ADR_12_HW (FDVT_BASE_HW+0x1B4)
#define FDVT_FF_BASE_ADR_13_HW (FDVT_BASE_HW+0x1B8)
#define FDVT_FF_BASE_ADR_14_HW (FDVT_BASE_HW+0x1BC)
#define FDVT_FF_BASE_ADR_15_HW (FDVT_BASE_HW+0x1C0)
#define FDVT_FF_BASE_ADR_16_HW (FDVT_BASE_HW+0x1D8)
#define FDVT_FF_BASE_ADR_17_HW (FDVT_BASE_HW+0x1DC)
#define FDVT_MAX_OFFSET 0x1DC
#if IS_ENABLED(CONFIG_OF)
struct fdvt_device {
void __iomem *regs[FDVT_BASEADDR_NUM];
struct device *dev;
int irq[FDVT_IRQ_IDX_NUM];
};
static struct fdvt_device *fdvt_devs;
static int nr_fdvt_devs;
#endif
bool haveConfig;
#if (MTK_SECURE_FD_SUPPORT == 1)
bool g_isSecure;
#endif
void FDVT_basic_config(void)
{
FDVT_WR32(0x00000111, FDVT_ENABLE);
FDVT_WR32(0x0000040C, FDVT_RS);
FDVT_WR32(0x0C000000, FDVT_RSCON_BASE_ADR);
FDVT_WR32(0x02590132, FDVT_RGB2Y0);
FDVT_WR32(0x00000075, FDVT_RGB2Y1);
FDVT_WR32(0x66553520, FDVT_INVG0);
FDVT_WR32(0xB8A28D79, FDVT_INVG1);
FDVT_WR32(0xFFF4E7CF, FDVT_INVG2);
FDVT_WR32(0x02A402EE, FDVT_FNUM_0);
FDVT_WR32(0x02A402EE, FDVT_FNUM_1);
FDVT_WR32(0x0DAC0DAC, FDVT_FNUM_2);
FDVT_WR32(0x0DAC02A4, FDVT_FNUM_3);
FDVT_WR32(0x00000000, FDVT_T_FNUM_4);
FDVT_WR32(0x00000000, FDVT_T_FNUM_5);
FDVT_WR32(0x00000000, FDVT_T_FNUM_6);
FDVT_WR32(0x00000000, FDVT_T_FNUM_7);
FDVT_WR32(0x02EE02A4, FDVT_FF_NUM_0);
FDVT_WR32(0x02A402A4, FDVT_FF_NUM_1);
FDVT_WR32(0x02A402EE, FDVT_FF_NUM_2);
FDVT_WR32(0x02EE02A4, FDVT_FF_NUM_3);
FDVT_WR32(0x000002A4, FDVT_FF_NUM_4);
FDVT_WR32(0x00000000, FDVT_FF_NUM_5);
FDVT_WR32(0x00000000, FDVT_FF_NUM_6);
FDVT_WR32(0x00000000, FDVT_FF_NUM_7);
FDVT_WR32(0x00000000, FDVT_FF_NUM_8);
FDVT_WR32(0x0D000000, FDVT_FF_BASE_ADR_0);
FDVT_WR32(0x0D010000, FDVT_FF_BASE_ADR_1);
FDVT_WR32(0x0D020000, FDVT_FF_BASE_ADR_2);
FDVT_WR32(0x0D030000, FDVT_FF_BASE_ADR_3);
FDVT_WR32(0x0D040000, FDVT_FF_BASE_ADR_4);
FDVT_WR32(0x0D050000, FDVT_FF_BASE_ADR_5);
FDVT_WR32(0x0D060000, FDVT_FF_BASE_ADR_6);
FDVT_WR32(0x0D070000, FDVT_FF_BASE_ADR_7);
FDVT_WR32(0x0D080000, FDVT_FF_BASE_ADR_8);
FDVT_WR32(0x0D090000, FDVT_FF_BASE_ADR_9);
FDVT_WR32(0x0D0A0000, FDVT_FF_BASE_ADR_10);
FDVT_WR32(0x0D0B0000, FDVT_FF_BASE_ADR_11);
FDVT_WR32(0x0D0C0000, FDVT_FF_BASE_ADR_12);
FDVT_WR32(0x0D0D0000, FDVT_FF_BASE_ADR_13);
FDVT_WR32(0x0D0E0000, FDVT_FF_BASE_ADR_14);
FDVT_WR32(0x0D0F0000, FDVT_FF_BASE_ADR_15);
FDVT_WR32(0x0D110000, FDVT_FF_BASE_ADR_16);
FDVT_WR32(0x0D120000, FDVT_FF_BASE_ADR_17);
FDVT_WR32(0x00000000, FDVT_RMAP_0);
FDVT_WR32(0x00000001, FDVT_RMAP_1);
FDVT_WR32(0x0400000C, FDVT_FD);
FDVT_WR32(0x0D100000, FDVT_FD_CON_BASE_ADR);
FDVT_WR32(0x00000000, FDVT_GFD);
FDVT_WR32(0x01130000, FDVT_LFD);
FDVT_WR32(0x00000000, FDVT_GFD_POS_0);
FDVT_WR32(0x012C0190, FDVT_GFD_POS_1);
FDVT_WR32(0x00000207, FDVT_GFD_DET0);
FDVT_WR32(0x00000000, FDVT_GFD_DET1);
FDVT_WR32(0x11223300, FDVT_FD_RLT_BASE_ADR);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_0);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_0);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_0);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_1);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_1);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_1);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_2);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_2);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_2);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_3);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_3);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_3);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_4);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_4);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_4);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_5);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_5);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_5);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_6);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_6);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_6);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_7);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_7);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_7);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_8);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_8);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_8);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_9);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_9);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_9);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_10);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_10);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_10);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_11);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_11);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_11);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_12);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_12);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_12);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_13);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_13);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_13);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_CTRL_14);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_XPOS_14);
FDVT_WR32(0x00000000, FDVT_LFD_INFO_YPOS_14);
FDVT_WR32(0x00000000, FDVT_INT_EN);
FDVT_WR32(0x0190012C, FDVT_SRC_WD_HT);
}
/**************************************************************
*
**************************************************************/
enum m4u_callback_ret_t FDVT_M4U_TranslationFault_callback(int port,
unsigned int mva, void *data)
{
unsigned int u4RegValue = 0;
unsigned int u4Index = 0;
pr_info("[FDVT_M4U]fault call port=%d, mva=0x%x", port, mva);
for (u4Index = 0x0; u4Index < 0x180; u4Index += 4) {
u4RegValue = ioread32((void *)(FDVT_ADDR + u4Index));
LOG_DBG("+0x%x 0x%x\n", u4Index, u4RegValue);
}
return M4U_CALLBACK_HANDLED;
}
/***********************************************************
* Clock to ms
************************************************************/
/*
*static unsigned long ms_to_jiffies(unsigned long ms)
*{
* return (ms * HZ + 512) >> 10;
*}
*/
static unsigned long us_to_jiffies(unsigned long us)
{
return (((us/1000) * HZ + 512) >> 10);
}
/*=======================================================================*/
/* FDVT Clock control Registers */
/*=======================================================================*/
#if LDVT_EARLY_PORTING_NO_CCF
#else
static inline void FD_Prepare_Enable_ccf_clock(void)
{
int ret;
#if (MTK_FD_LARB == 2)
smi_bus_prepare_enable(SMI_LARB2, "camera_fdvt");
#else
smi_bus_prepare_enable(SMI_LARB5, "camera_fdvt");
#endif
ret = clk_prepare_enable(fd_clk.CG_IMGSYS_FDVT);
if (ret)
LOG_ERR("cannot prepare and enable CG_IMGSYS_FDVT clock\n");
}
static inline void FD_Disable_Unprepare_ccf_clock(void)
{
clk_disable_unprepare(fd_clk.CG_IMGSYS_FDVT);
#if (MTK_FD_LARB == 2)
smi_bus_disable_unprepare(SMI_LARB2, "camera_fdvt");
#else
smi_bus_disable_unprepare(SMI_LARB5, "camera_fdvt");
#endif
}
#endif
static int mt_fdvt_clk_ctrl(int en)
{
#if LDVT_EARLY_PORTING_NO_CCF
if (en) {
unsigned int setReg = 0xFFFFFFFF;
FDVT_WR32(setReg, CAMSYS_CONFIG_BASE+0x8);
FDVT_WR32(setReg, IMGSYS_CONFIG_BASE+0x8);
} else {
unsigned int setReg = 0xFFFFFFFF;
FDVT_WR32(setReg, IMGSYS_CONFIG_BASE+0x4);
FDVT_WR32(setReg, CAMSYS_CONFIG_BASE+0x4);
}
#else
if (en)
FD_Prepare_Enable_ccf_clock();
else
FD_Disable_Unprepare_ccf_clock();
#endif
return 0;
}
/*****************************************************************************
*
*****************************************************************************/
#if (MTK_SECURE_FD_SUPPORT == 1)
static inline int FDVT_switchCmdqToSecure(void *handle)
{
enum CMDQ_ENG_ENUM cmdq_engine;
/*enum CMDQ_EVENT_ENUM cmdq_event;*/
/*cmdq_engine = module_to_cmdq_engine(module);*/
cmdq_engine = CMDQ_ENG_FDVT;
/*cmdq_event = CMDQ_EVENT_DVE_EOF;*/
cmdqRecSetSecure(handle, 1);
/* set engine as sec */
cmdqRecSecureEnablePortSecurity(handle, (1LL << cmdq_engine));
//cmdqRecSecureEnableDAPC(handle, (1LL << cmdq_engine));
/* Set fdvt with mtee Task */
cmdq_task_set_mtee(handle, true);
return 0;
}
/*****************************************************************************
*
*****************************************************************************/
static inline int FDVT_switchPortToNonSecure(void)
{
struct cmdqRecStruct *handle;
uint64_t engineFlag = (uint64_t)(1LL << CMDQ_ENG_FDVT);
cmdq_task_create(CMDQ_SCENARIO_ISP_FDVT_OFF, &handle);
cmdq_task_set_secure(handle, true);
cmdqRecSetEngine(handle, engineFlag);
//cmdq_task_secure_enable_dapc(handle, engineFlag);
cmdq_task_secure_enable_port_security(handle, engineFlag);
/* Set fdvt with mtee Task */
cmdq_task_set_mtee(handle, true);
cmdq_task_flush(handle);
return 0;
}
/***********************************************************
* Set FDVT Meta Data
************************************************************/
static int FDVT_SetMetaData(FDVTMetaData *pMetaData)
{
int ret = 0;
/* int i = 0; */
/* FDVTMetaData fdvt_meta; */
if (pMetaData == NULL) {
LOG_DBG("Null input argrment\n");
return -EINVAL;
}
if (copy_from_user(&g_fdvt_secmeta, (void *)pMetaData->SecureMeta,
sizeof(FDVTSecureMeta)) != 0) {
LOG_DBG("secmeta copy_from_user failed\n");
return -EFAULT;
}
/*
*LOG_INF("SecureMeta->fd_mode: %d\n", g_fdvt_secmeta.fd_mode);
*for (i = 0; i < 15; i ++) {
*LOG_INF("SecureMeta->source img width/height[%d]: (%d, %d)\n",
* i,
* g_fdvt_secmeta.source_img_width[i],
* g_fdvt_secmeta.source_img_height[i]);
*}
*LOG_INF("SecureMeta->Learning_Type: %d\n",
* g_fdvt_secmeta.Learning_Type);
*LOG_INF("SecureMeta->RIP_feature: %d\n",
* g_fdvt_secmeta.RIP_feature);
*LOG_INF("SecureMeta->GFD_skip: %d\n",
* g_fdvt_secmeta.GFD_skip);
*LOG_INF("SecureMeta->GFD_skip_V: %d\n",
* g_fdvt_secmeta.GFD_skip_V);
*LOG_INF("SecureMeta->feature_threshold: %d\n",
* g_fdvt_secmeta.feature_threshold);
*LOG_INF("SecureMeta->source_img_fmt: %d\n",
* g_fdvt_secmeta.source_img_fmt);
*LOG_INF("SecureMeta->scale_from_original: %d\n",
* g_fdvt_secmeta.scale_from_original);
*LOG_INF("SecureMeta->scale_manual_mode: %d\n",
* g_fdvt_secmeta.scale_manual_mode);
*LOG_INF("SecureMeta->scale_num_from_user: %d\n",
* g_fdvt_secmeta.scale_num_from_user);
*LOG_INF("SecureMeta->SecMemType: %d\n",
* g_fdvt_secmeta.SecMemType);
*LOG_INF("SecureMeta->ImgSrcY_Handler: 0x%x, Size: %d\n",
* g_fdvt_secmeta.ImgSrcY_Handler,
* g_fdvt_secmeta.ImgSrc_Y_Size);
*LOG_INF("SecureMeta->ImgSrcUV_Handler: 0x%x, Size: %d\n",
* g_fdvt_secmeta.ImgSrcUV_Handler,
* g_fdvt_secmeta.ImgSrc_UV_Size);
*LOG_INF("SecureMeta->RSConfig_Handler: 0x%x, Size: %d\n",
* g_fdvt_secmeta.RSConfig_Handler,
* g_fdvt_secmeta.RSConfigSize);
*LOG_INF("SecureMeta->FDConfig_Handler: 0x%x, Size: %d\n",
* g_fdvt_secmeta.FDConfig_Handler,
* g_fdvt_secmeta.FDConfigSize);
*LOG_INF("SecureMeta->FDResultBuf_PA: 0x%llx, Size: %d\n",
* g_fdvt_secmeta.FDResultBuf_PA,
* g_fdvt_secmeta.FDResultBufSize);
*for (i = 0; i < 18; i ++) {
*LOG_INF("SecureMeta->Learning_Data_Handler[%d]: 0x%x\n",
* i,
* g_fdvt_secmeta.Learning_Data_Handler[i]);
*LOG_INF("SecureMeta->Learning_Data_Handler_Extra[%d]: 0x%x\n",
* i,
* g_fdvt_secmeta.Extra_Learning_Data_Handler[i]);
*LOG_INF("SecureMeta->Learning_Data_Size[%d]: %d\n",
* i,
* g_fdvt_secmeta.Learning_Data_Size[i]);
*LOG_INF("SecureMeta->dynamic_change_model[%d]: %d\n",
* i,
* g_fdvt_secmeta.dynamic_change_model[i]);
*}
*/
return ret;
}
#endif
/*=======================================================================*/
/* FDVT FD Config Registers */
/*=======================================================================*/
void FaceDetecteConfig(void)
{
FDVT_WR32(0x02A402EE, FDVT_FNUM_0);
FDVT_WR32(0x02A402EE, FDVT_FNUM_1);
FDVT_WR32(0x0DAC0DAC, FDVT_FNUM_2);
FDVT_WR32(0x0DAC02A4, FDVT_FNUM_3);
FDVT_WR32(0x00000000, FDVT_T_FNUM_4);
FDVT_WR32(0x00000000, FDVT_T_FNUM_5);
FDVT_WR32(0x00000000, FDVT_T_FNUM_6);
FDVT_WR32(0x00000000, FDVT_T_FNUM_7);
FDVT_WR32(0x02EE02A4, FDVT_FF_NUM_0);
FDVT_WR32(0x02A402A4, FDVT_FF_NUM_1);
FDVT_WR32(0x02A402EE, FDVT_FF_NUM_2);
FDVT_WR32(0x02EE02A4, FDVT_FF_NUM_3);
FDVT_WR32(0x00C802A4, FDVT_FF_NUM_4);/*0x000002A4*/
FDVT_WR32(0x00640064, FDVT_FF_NUM_5);/*0x00000000*/
FDVT_WR32(0x00DC00DC, FDVT_FF_NUM_6);/*0x00000000*/
FDVT_WR32(0x00000000, FDVT_FF_NUM_7);
FDVT_WR32(0x00000000, FDVT_FF_NUM_8);
/* FDVT_WR32(0x000F010B,FDVT_FD); //LDVT Disable */
}
/*=======================================================================*/
/* FDVT SD Config Registers */
/*=======================================================================*/
void SmileDetecteConfig(void)
{
FDVT_WR32(0x01210171, FDVT_FNUM_0);
FDVT_WR32(0x00D10081, FDVT_FNUM_1);
FDVT_WR32(0x00F100D1, FDVT_FNUM_2);
FDVT_WR32(0x00F100D1, FDVT_FNUM_3);
FDVT_WR32(0x00E70127, FDVT_T_FNUM_4);
FDVT_WR32(0x00A70067, FDVT_T_FNUM_5);
FDVT_WR32(0x00C000A7, FDVT_T_FNUM_6);
FDVT_WR32(0x00C000A7, FDVT_T_FNUM_7);
FDVT_WR32(0x00180018, FDVT_FF_NUM_0);
FDVT_WR32(0x00180018, FDVT_FF_NUM_1);
FDVT_WR32(0x00180018, FDVT_FF_NUM_2);
FDVT_WR32(0x00180018, FDVT_FF_NUM_3);
FDVT_WR32(0x000F010B, FDVT_FD);
}
/*=======================================================================*/
/* FDVT Dump Registers */
/*=======================================================================*/
void FDVT_DUMPREG(void)
{
unsigned int u4RegValue = 0;
unsigned int u4Index = 0;
LOG_INF("FDVT REG:\n ********************\n");
/* for(u4Index = 0; u4Index < 0x180; u4Index += 4) { */
for (u4Index = 0x0; u4Index < FDVT_MAX_OFFSET; u4Index += 4) {
u4RegValue = ioread32((void *)(FDVT_ADDR + u4Index));
LOG_INF("+0x%x 0x%x\n", u4Index, u4RegValue);
}
}
/*=======================================================================*/
/* FDVT set reg to HW buffer */
/*=======================================================================*/
static int FDVT_SetRegHW(FDVTRegIO *a_pstCfg)
{
#ifdef FDVT_USE_GCE
struct cmdqRecStruct *handle;
uint64_t engineFlag = (uint64_t)(1LL << CMDQ_ENG_FDVT);
#endif
FDVTRegIO *pREGIO = NULL;
u32 i = 0;
if (a_pstCfg == NULL) {
LOG_DBG("Null input argrment\n");
return -EINVAL;
}
pREGIO = (FDVTRegIO *)a_pstCfg;
if (pREGIO->u4Count > FDVT_DRAM_REGCNT) {
LOG_DBG("Buffer Size Exceeded!\n");
return -EFAULT;
}
if (copy_from_user(
(void *)pFDVTWriteBuffer.u4Addr,
(void *) pREGIO->pAddr,
pREGIO->u4Count * sizeof(u32))) {
LOG_DBG("ioctl copy from user failed\n");
return -EFAULT;
}
if (copy_from_user(
(void *)pFDVTWriteBuffer.u4Data,
(void *) pREGIO->pData,
pREGIO->u4Count * sizeof(u32))) {
LOG_DBG("ioctl copy from user failed\n");
return -EFAULT;
}
#ifdef FDVT_USE_GCE
cmdqRecCreate(CMDQ_SCENARIO_ISP_FDVT, &handle);
#if (MTK_SECURE_FD_SUPPORT == 1)
LOG_DBG("FDVT isSecure: %d\n", g_isSecure);
if (g_isSecure != 0)
FDVT_switchCmdqToSecure(handle);
#endif
cmdqRecSetEngine(handle, engineFlag);
for (i = 0; i < pREGIO->u4Count; i++) {
if ((FDVT_BASE_HW + pFDVTWriteBuffer.u4Addr[i]) >=
FDVT_BASE_HW &&
(FDVT_BASE_HW + pFDVTWriteBuffer.u4Addr[i]) <=
(FDVT_BASE_HW + FDVT_MAX_OFFSET)) {
/*LOG_DBG("Write: FDVT[0x%03lx](0x%08lx) = 0x%08lx\n",*/
/*(unsigned long)pFDVTWriteBuffer.u4Addr[i], */
/*(unsigned long)(FDVT_ADDR + pFDVTWriteBuffer.u4Addr[i]),*/
/*(unsigned long)pFDVTWriteBuffer.u4Data[i]); */
cmdqRecWrite(
handle,
FDVT_BASE_HW + pFDVTWriteBuffer.u4Addr[i],
pFDVTWriteBuffer.u4Data[i],
CMDQ_REG_MASK);
} else {
/* LOG_DBG("Error: Writing Addr(0x%8x) Excess FDVT Range!*/
/* FD Offset: 0x%x\n",*/
/* FDVT_ADDR + pFDVTWriteBuffer.u4Addr[i],*/
/* pFDVTWriteBuffer.u4Addr[i]);*/
}
}
#if (MTK_SECURE_FD_SUPPORT == 1)
if (g_isSecure == 1) {
unsigned int LearningData_Chosen[18];
unsigned int secMemType2MVA = 1;
int ret = 0;
for (i = 0; i < 18; i++) {
LearningData_Chosen[i] =
(g_fdvt_secmeta.dynamic_change_model[i] == 1) ?
(g_fdvt_secmeta.Extra_Learning_Data_Handler[i]) :
(g_fdvt_secmeta.Learning_Data_Handler[i]);
}
if (g_fdvt_secmeta.SecMemType == 2)
secMemType2MVA = CMDQ_SAM_H_2_MVA;
else if (g_fdvt_secmeta.SecMemType == 1)
secMemType2MVA = CMDQ_SAM_PH_2_MVA;
else
LOG_INF("Unknown Sec Mem Type\n");
#if (MTK_FD_LARB == 2)
cmdqRecWriteSecure(handle,
FDVT_RSCON_BASE_ADR_HW,
secMemType2MVA,
g_fdvt_secmeta.RSConfig_Handler,
0,
g_fdvt_secmeta.RSConfigSize,
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FD_CON_BASE_ADR_HW,
secMemType2MVA,
g_fdvt_secmeta.FDConfig_Handler,
0,
g_fdvt_secmeta.FDConfigSize,
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_0_HW,
secMemType2MVA,
LearningData_Chosen[0],
0,
g_fdvt_secmeta.Learning_Data_Size[0],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_1_HW,
secMemType2MVA,
LearningData_Chosen[1],
0,
g_fdvt_secmeta.Learning_Data_Size[1],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_2_HW,
secMemType2MVA,
LearningData_Chosen[2],
0,
g_fdvt_secmeta.Learning_Data_Size[2],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_3_HW,
secMemType2MVA,
LearningData_Chosen[3],
0,
g_fdvt_secmeta.Learning_Data_Size[3],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_4_HW,
secMemType2MVA,
LearningData_Chosen[4],
0,
g_fdvt_secmeta.Learning_Data_Size[4],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_5_HW,
secMemType2MVA,
LearningData_Chosen[5],
0,
g_fdvt_secmeta.Learning_Data_Size[5],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_6_HW,
secMemType2MVA,
LearningData_Chosen[6],
0,
g_fdvt_secmeta.Learning_Data_Size[6],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_7_HW,
secMemType2MVA,
LearningData_Chosen[7],
0,
g_fdvt_secmeta.Learning_Data_Size[7],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_8_HW,
secMemType2MVA,
LearningData_Chosen[8],
0,
g_fdvt_secmeta.Learning_Data_Size[8],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_9_HW,
secMemType2MVA,
LearningData_Chosen[9],
0,
g_fdvt_secmeta.Learning_Data_Size[9],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_10_HW,
secMemType2MVA,
LearningData_Chosen[10],
0,
g_fdvt_secmeta.Learning_Data_Size[10],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_11_HW,
secMemType2MVA,
LearningData_Chosen[11],
0,
g_fdvt_secmeta.Learning_Data_Size[11],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_12_HW,
secMemType2MVA,
LearningData_Chosen[12],
0,
g_fdvt_secmeta.Learning_Data_Size[12],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_13_HW,
secMemType2MVA,
LearningData_Chosen[13],
0,
g_fdvt_secmeta.Learning_Data_Size[13],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_14_HW,
secMemType2MVA,
LearningData_Chosen[14],
0,
g_fdvt_secmeta.Learning_Data_Size[14],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_15_HW,
secMemType2MVA,
LearningData_Chosen[15],
0,
g_fdvt_secmeta.Learning_Data_Size[15],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_16_HW,
secMemType2MVA,
LearningData_Chosen[16],
0,
g_fdvt_secmeta.Learning_Data_Size[16],
M4U_PORT_CAM_FD_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_17_HW,
secMemType2MVA,
LearningData_Chosen[17],
0,
g_fdvt_secmeta.Learning_Data_Size[17],
M4U_PORT_CAM_FD_RB);
#else
cmdqRecWriteSecure(handle,
FDVT_RSCON_BASE_ADR_HW,
secMemType2MVA,
g_fdvt_secmeta.RSConfig_Handler,
0,
g_fdvt_secmeta.RSConfigSize,
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FD_CON_BASE_ADR_HW,
secMemType2MVA,
g_fdvt_secmeta.FDConfig_Handler,
0,
g_fdvt_secmeta.FDConfigSize,
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_0_HW,
secMemType2MVA,
LearningData_Chosen[0],
0,
g_fdvt_secmeta.Learning_Data_Size[0],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_1_HW,
secMemType2MVA,
LearningData_Chosen[1],
0,
g_fdvt_secmeta.Learning_Data_Size[1],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_2_HW,
secMemType2MVA,
LearningData_Chosen[2],
0,
g_fdvt_secmeta.Learning_Data_Size[2],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_3_HW,
secMemType2MVA,
LearningData_Chosen[3],
0,
g_fdvt_secmeta.Learning_Data_Size[3],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_4_HW,
secMemType2MVA,
LearningData_Chosen[4],
0,
g_fdvt_secmeta.Learning_Data_Size[4],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_5_HW,
secMemType2MVA,
LearningData_Chosen[5],
0,
g_fdvt_secmeta.Learning_Data_Size[5],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_6_HW,
secMemType2MVA,
LearningData_Chosen[6],
0,
g_fdvt_secmeta.Learning_Data_Size[6],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_7_HW,
secMemType2MVA,
LearningData_Chosen[7],
0,
g_fdvt_secmeta.Learning_Data_Size[7],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_8_HW,
secMemType2MVA,
LearningData_Chosen[8],
0,
g_fdvt_secmeta.Learning_Data_Size[8],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_9_HW,
secMemType2MVA,
LearningData_Chosen[9],
0,
g_fdvt_secmeta.Learning_Data_Size[9],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_10_HW,
secMemType2MVA,
LearningData_Chosen[10],
0,
g_fdvt_secmeta.Learning_Data_Size[10],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_11_HW,
secMemType2MVA,
LearningData_Chosen[11],
0,
g_fdvt_secmeta.Learning_Data_Size[11],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_12_HW,
secMemType2MVA,
LearningData_Chosen[12],
0,
g_fdvt_secmeta.Learning_Data_Size[12],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_13_HW,
secMemType2MVA,
LearningData_Chosen[13],
0,
g_fdvt_secmeta.Learning_Data_Size[13],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_14_HW,
secMemType2MVA,
LearningData_Chosen[14],
0,
g_fdvt_secmeta.Learning_Data_Size[14],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_15_HW,
secMemType2MVA,
LearningData_Chosen[15],
0,
g_fdvt_secmeta.Learning_Data_Size[15],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_16_HW,
secMemType2MVA,
LearningData_Chosen[16],
0,
g_fdvt_secmeta.Learning_Data_Size[16],
M4U_PORT_CAM_FDVT_RB);
cmdqRecWriteSecure(handle,
FDVT_FF_BASE_ADR_17_HW,
secMemType2MVA,
LearningData_Chosen[17],
0,
g_fdvt_secmeta.Learning_Data_Size[17],
M4U_PORT_CAM_FDVT_RB);
#endif
ret = cmdq_task_set_secure_meta(
handle,
CMDQ_SEC_METAEX_FD,
&(g_fdvt_secmeta),
sizeof(FDVTSecureMeta));
}
#endif
cmdqRecWrite(handle, FDVT_INT_EN_HW, 0x1, CMDQ_REG_MASK);
cmdqRecWrite(handle, FDVT_START_HW, 0x0, CMDQ_REG_MASK);
cmdqRecWrite(handle, FDVT_START_HW, 0x1, CMDQ_REG_MASK);
cmdqRecWrite(handle, FDVT_START_HW, 0x0, CMDQ_REG_MASK);
cmdq_task_flush_async_destroy(handle); /* flush and destroy in cmdq */
#else
/* pFDVTWriteBuffer.u4Counter=pREGIO->u4Count; */
/* LOG_DBG("Count = %d\n", pREGIO->u4Count); */
for (i = 0; i < pREGIO->u4Count; i++) {
if ((FDVT_ADDR + pFDVTWriteBuffer.u4Addr[i]) >=
FDVT_ADDR &&
(FDVT_ADDR + pFDVTWriteBuffer.u4Addr[i]) <=
(FDVT_ADDR + FDVT_MAX_OFFSET)) {
/*LOG_DBG("Write: FDVT[0x%03lx](0x%08lx) = 0x%08lx\n",*/
/*(unsigned long)pFDVTWriteBuffer.u4Addr[i], */
/*(unsigned long)(FDVT_ADDR + pFDVTWriteBuffer.u4Addr[i]),*/
/*(unsigned long)pFDVTWriteBuffer.u4Data[i]); */
FDVT_WR32(pFDVTWriteBuffer.u4Data[i],
FDVT_ADDR + pFDVTWriteBuffer.u4Addr[i]);
} else {
/* LOG_DBG("Error: Writing Addr(0x%8x) Excess FDVT Range!*/
/* FD Offset: 0x%x\n",*/
/* FDVT_ADDR + pFDVTWriteBuffer.u4Addr[i],*/
/* pFDVTWriteBuffer.u4Addr[i]);*/
}
}
#endif
return 0;
}
/***********************************************************
*
************************************************************/
static int FDVT_ReadRegHW(FDVTRegIO *a_pstCfg)
{
int ret = 0;
int size = 0;
int i = 0;
if (a_pstCfg == NULL) {
LOG_DBG("Null input argrment\n");
return -EINVAL;
}
if (a_pstCfg->u4Count > FDVT_DRAM_REGCNT) {
LOG_DBG("Buffer Size Exceeded!\n");
return -EFAULT;
}
size = a_pstCfg->u4Count * 4;
if (copy_from_user(pFDVTReadBuffer.u4Addr, a_pstCfg->pAddr,
size) != 0) {
LOG_DBG("copy_from_user failed\n");
ret = -EFAULT;
goto mt_FDVT_read_reg_exit;
}
for (i = 0; i < a_pstCfg->u4Count; i++) {
if ((FDVT_ADDR + pFDVTReadBuffer.u4Addr[i]) >= FDVT_ADDR &&
(FDVT_ADDR + pFDVTReadBuffer.u4Addr[i]) <=
(FDVT_ADDR + FDVT_MAX_OFFSET)) {
pFDVTReadBuffer.u4Data[i] =
ioread32(
(void *)(FDVT_ADDR + pFDVTReadBuffer.u4Addr[i]));
/*LOG_DBG("Read addr/val: 0x%08x/0x%08x\n",*/
/*(u32) (FDVT_ADDR + pFDVTReadBuffer.u4Addr[i]),*/
/*(u32) pFDVTReadBuffer.u4Data[i]);*/
} else {
/*LOG_DBG("Error: Reading Addr(0x%8x) Excess FDVT Range!*/
/* FD Offset: 0x%x\n",*/
/*FDVT_ADDR + pFDVTReadBuffer.u4Addr[i], */
/*pFDVTReadBuffer.u4Addr[i]);*/
ret = -EFAULT;
goto mt_FDVT_read_reg_exit;
}
}
if (copy_to_user(a_pstCfg->pData, pFDVTReadBuffer.u4Data, size) != 0) {
LOG_DBG("copy_to_user failed\n");
ret = -EFAULT;
goto mt_FDVT_read_reg_exit;
}
mt_FDVT_read_reg_exit:
return ret;
}
/*===============================================*/
/* Wait IRQ, for user space program to wait interrupt */
/* wait for timeout 500ms */
/*===============================================*/
static int FDVT_WaitIRQ(u32 *u4IRQMask)
{
int timeout;
/*timeout = wait_event_interruptible_timeout*/
/*(g_FDVTWQ, (g_FDVTIRQMSK & g_FDVTIRQ),*/
/*ms_to_jiffies(500));*/
timeout = wait_event_interruptible_timeout
(g_FDVTWQ,
(g_FDVTIRQMSK & g_FDVTIRQ),
us_to_jiffies(1000000));
if (timeout == 0) {
LOG_ERR("wait_event_interruptible_timeout timeout, %d, %d\n",
g_FDVTIRQMSK,
g_FDVTIRQ);
FDVT_DUMPREG();
FDVT_WR32(0x00030000, FDVT_START); /* LDVT Disable */
FDVT_WR32(0x00000000, FDVT_START); /* LDVT Disable */
return -EAGAIN;
}
*u4IRQMask = g_FDVTIRQ;
LOG_INF("[FDVT] Receive IRQ : 0x%x\n", g_FDVTIRQ);
/* check if user is interrupted by system signal */
if (timeout != 0 && !(g_FDVTIRQMSK & g_FDVTIRQ)) {
LOG_ERR("interrupted by system signal,return value(%d)\n",
timeout);
return -ERESTARTSYS; /* actually it should be -ERESTARTSYS */
}
if (!(g_FDVTIRQMSK & g_FDVTIRQ)) {
LOG_ERR("wait_event_interruptible Not FDVT, %d, %d\n",
g_FDVTIRQMSK,
g_FDVTIRQ);
FDVT_DUMPREG();
return -1;
}
#if (MTK_SECURE_FD_SUPPORT == 1)
if (g_isSecure != 0)
FDVT_switchPortToNonSecure();
#endif
g_FDVTIRQ = 0;
return 0;
}
static irqreturn_t FDVT_irq(int irq, void *dev_id)
{
/*g_FDVT_interrupt_handler = VAL_TRUE;*/
/*FDVT_ISR();*/
g_FDVTIRQ = ioread32((void *)FDVT_INT);
wake_up_interruptible(&g_FDVTWQ);
return IRQ_HANDLED;
}
static long FDVT_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int ret = 0;
if (_IOC_SIZE(cmd) > buf_size) {
LOG_DBG("Buffer Size Exceeded!\n");
return -EFAULT;
}
if (_IOC_DIR(cmd) != _IOC_NONE) {
/* IO write */
if (_IOC_WRITE & _IOC_DIR(cmd)) {
if (copy_from_user(
pBuff,
(void *)arg,
_IOC_SIZE(cmd))) {
LOG_DBG(" ioctl copy from user failed\n");
return -EFAULT;
}
}
/* else */
/* LOG_DBG(" ioctlnot write command\n"); */
}
/* else */
/* LOG_DBG(" ioctl command = NONE\n"); */
switch (cmd) {
case FDVT_IOC_INIT_SETPARA_CMD:
LOG_DBG("[FDVT] FDVT_INIT_CMD\n");
haveConfig = 0;
FDVT_basic_config();
break;
#if (MTK_SECURE_FD_SUPPORT == 1)
case FDVT_IOC_INIT_SETNORMAL_CMD:
LOG_DBG("[FDVT] FDVT_INIT_SETNORMAL_CMD\n");
g_isSecure = 0;
break;
case FDVT_IOC_INIT_SETSECURE_CMD:
LOG_DBG("[FDVT] FDVT_INIT_SETSECURE_CMD\n");
g_isSecure = 1;
break;
#endif
case FDVT_IOC_STARTFD_CMD:
/* LOG_DBG("[FDVT] FDVTIOC_STARTFD_CMD\n"); */
if (haveConfig) {
#ifdef FDVT_USE_GCE
#else
FDVT_WR32(0x00000001, FDVT_INT_EN);
FDVT_WR32(0x00000000, FDVT_START);
FDVT_WR32(0x00000001, FDVT_START);
FDVT_WR32(0x00000000, FDVT_START);
#endif
haveConfig = 0;
}
/* FDVT_DUMPREG(); */
break;
case FDVT_IOC_G_WAITIRQ:
/* LOG_DBG("[FDVT] FDVT_WaitIRQ\n"); */
ret = FDVT_WaitIRQ((unsigned int *)pBuff);
FDVT_WR32(0x00000000, FDVT_INT_EN);
break;
case FDVT_IOC_T_SET_FDCONF_CMD:
/* LOG_DBG("[FDVT] FDVT set FD config\n"); */
FaceDetecteConfig();
ret = FDVT_SetRegHW((FDVTRegIO *)pBuff);
if (ret == 0)
haveConfig = 1;
else
LOG_DBG("Set FD HW register fail");
break;
case FDVT_IOC_T_SET_SDCONF_CMD:
/* LOG_DBG("[FDVT] FDVT set SD config\n"); */
SmileDetecteConfig();
ret = FDVT_SetRegHW((FDVTRegIO *)pBuff);
if (ret == 0)
haveConfig = 1;
else
LOG_DBG("Set SD HW register fail");
break;
case FDVT_IOC_G_READ_FDREG_CMD:
/* LOG_DBG("[FDVT] FDVT read FD config\n"); */
ret = FDVT_ReadRegHW((FDVTRegIO *)pBuff);
break;
#if (MTK_SECURE_FD_SUPPORT == 1)
case FDVT_IOC_SETMETA_CMD:
LOG_DBG("[FDVT] FDVT set meta data\n");
ret = FDVT_SetMetaData((FDVTMetaData *)pBuff);
break;
#endif
case FDVT_IOC_T_DUMPREG:
LOG_DBG("[FDVT] FDVT_DUMPREG\n");
FDVT_DUMPREG();
break;
default:
LOG_DBG("[FDVT][ERROR] default case\n");
break;
}
/* NOT_REFERENCED(ret); */
/* LOG_DBG("[FDVT] FDVT IOCtrol out\n"); */
if (_IOC_READ & _IOC_DIR(cmd)) {
if (copy_to_user(
(void __user *)arg,
pBuff,
_IOC_SIZE(cmd)) != 0) {
LOG_DBG("copy_to_user failed\n");
return -EFAULT;
}
}
return ret;
}
#if IS_ENABLED(CONFIG_COMPAT)
/***********************************************************
*
************************************************************/
static int compat_FD_get_register_data(
compat_FDVTRegIO __user *data32,
FDVTRegIO __user *data)
{
compat_uint_t count;
compat_uptr_t uptr_Addr;
compat_uptr_t uptr_Data;
int err;
err = get_user(uptr_Addr, &data32->pAddr);
err |= put_user(compat_ptr(uptr_Addr), &data->pAddr);
err |= get_user(uptr_Data, &data32->pData);
err |= put_user(compat_ptr(uptr_Data), &data->pData);
err |= get_user(count, &data32->u4Count);
err |= put_user(count, &data->u4Count);
return err;
}
static int compat_FD_put_register_data(
compat_FDVTRegIO __user *data32,
FDVTRegIO __user *data)
{
compat_uint_t count;
/*compat_uptr_t uptr_Addr;*/
/*compat_uptr_t uptr_Data;*/
int err;
/* Assume data pointer is unchanged. */
/* err = get_user(uptr_Addr, &data->pAddr); */
/* err |= put_user(compat_ptr(uptr_Addr), data32->pAddr); */
/* err |= get_user(uptr_Data, &data->pData); */
/* err |= put_user(compat_ptr(uptr_Data), &data32->pData); */
err = get_user(count, &data->u4Count);
err |= put_user(count, &data32->u4Count);
return err;
}
#if (MTK_SECURE_FD_SUPPORT == 1)
static int compat_FD_get_meta_data(compat_FDVTMetaData __user *data32,
FDVTMetaData __user *data)
{
compat_uptr_t uptr;
int err = 0;
err = get_user(uptr, &data32->SecureMeta);
err |= put_user(compat_ptr(uptr), &data->SecureMeta);
return err;
}
#endif
static long compat_FD_ioctl(
struct file *file, unsigned int cmd, unsigned long arg)
{
long ret;
if (!file->f_op || !file->f_op->unlocked_ioctl)
return -ENOTTY;
switch (cmd) {
#if (MTK_SECURE_FD_SUPPORT == 1)
case COMPAT_FDVT_IOC_INIT_SETSECURE_CMD:
{
return
file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
}
case COMPAT_FDVT_IOC_INIT_SETNORMAL_CMD:
{
return
file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
}
#endif
case COMPAT_FDVT_IOC_INIT_SETPARA_CMD:
{
return
file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
}
case COMPAT_FDVT_IOC_STARTFD_CMD:
{
return
file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
}
case COMPAT_FDVT_IOC_G_WAITIRQ:
{
compat_FDVTRegIO __user *data32;
FDVTRegIO __user *data;
int err;
data32 = compat_ptr(arg);
data = compat_alloc_user_space(sizeof(*data));
if (data == NULL)
return -EFAULT;
err = compat_FD_get_register_data(data32, data);
if (err)
return err;
ret = file->f_op->unlocked_ioctl(
file,
FDVT_IOC_G_WAITIRQ,
(unsigned long)data);
err = compat_FD_put_register_data(data32, data);
return ret ? ret : err;
}
case COMPAT_FDVT_IOC_T_SET_FDCONF_CMD:
{
compat_FDVTRegIO __user *data32;
FDVTRegIO __user *data;
int err;
data32 = compat_ptr(arg);
data = compat_alloc_user_space(sizeof(*data));
if (data == NULL)
return -EFAULT;
err = compat_FD_get_register_data(data32, data);
if (err)
return err;
ret = file->f_op->unlocked_ioctl(
file,
FDVT_IOC_T_SET_FDCONF_CMD,
(unsigned long)data);
return ret ? ret : err;
}
case COMPAT_FDVT_IOC_G_READ_FDREG_CMD:
{
compat_FDVTRegIO __user *data32;
FDVTRegIO __user *data;
int err;
data32 = compat_ptr(arg);
data = compat_alloc_user_space(sizeof(*data));
if (data == NULL)
return -EFAULT;
err = compat_FD_get_register_data(data32, data);
if (err)
return err;
ret = file->f_op->unlocked_ioctl(
file,
FDVT_IOC_G_READ_FDREG_CMD,
(unsigned long)data);
err = compat_FD_put_register_data(data32, data);
return ret ? ret : err;
}
case COMPAT_FDVT_IOC_T_SET_SDCONF_CMD:
{
compat_FDVTRegIO __user *data32;
FDVTRegIO __user *data;
int err;
data32 = compat_ptr(arg);
data = compat_alloc_user_space(sizeof(*data));
if (data == NULL)
return -EFAULT;
err = compat_FD_get_register_data(data32, data);
if (err)
return err;
ret = file->f_op->unlocked_ioctl(
file,
FDVT_IOC_T_SET_SDCONF_CMD,
(unsigned long)data);
return ret ? ret : err;
}
#if (MTK_SECURE_FD_SUPPORT == 1)
case COMPAT_FDVT_IOC_SETMETA_CMD:
{
compat_FDVTMetaData __user *data32;
FDVTMetaData __user *data;
int err;
data32 = compat_ptr(arg);
data = compat_alloc_user_space(sizeof(*data));
if (data == NULL)
return -EFAULT;
err = compat_FD_get_meta_data(data32, data);
if (err)
return err;
ret = file->f_op->unlocked_ioctl(
file,
FDVT_IOC_SETMETA_CMD,
(unsigned long)data);
return ret ? ret : err;
}
#endif
case COMPAT_FDVT_IOC_T_DUMPREG:
{
return
file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
}
default:
return -ENOIOCTLCMD;
/* return ISP_ioctl(filep, cmd, arg); */
}
}
#endif
static int FDVT_open(struct inode *inode, struct file *file)
{
signed int ret = 0;
LOG_DBG("[FDVT_DEBUG]\n");
spin_lock(&g_spinLock);
if (g_drvOpened) {
spin_unlock(&g_spinLock);
LOG_DBG("Opened, return -EBUSY\n");
return -EBUSY;
}
g_drvOpened = 1;
spin_unlock(&g_spinLock);
#if IS_ENABLED(CONFIG_PM_SLEEP)
__pm_stay_awake(&fdvt_wake_lock);
#endif
mt_fdvt_clk_ctrl(1);
#if IS_ENABLED(CONFIG_PM_SLEEP)
__pm_relax(&fdvt_wake_lock);
#endif
if (pBuff != NULL)
LOG_DBG("pBuff is not null\n");
if (pread_buf != NULL)
LOG_DBG("pread_buf is not null\n");
pBuff = kmalloc(buf_size, GFP_KERNEL);
if (pBuff == NULL) {
LOG_DBG(" ioctl allocate mem failed\n");
ret = -ENOMEM;
} else {
LOG_DBG(" ioctl allocate mem ok\n");
}
pread_buf = kmalloc(buf_size, GFP_KERNEL);
if (pread_buf == NULL) {
LOG_DBG(" ioctl allocate mem failed\n");
ret = -ENOMEM;
} else {
LOG_DBG(" ioctl allocate mem ok\n");
}
if (ret < 0) {
/*if (pBuff) {*/
kfree(pBuff);
pBuff = NULL;
/*}*/
/*if (pread_buf) {*/
kfree(pread_buf);
pread_buf = NULL;
/*}*/
}
return 0;
}
/*
*static int FDVT_flush(struct file *file, fl_owner_t id)
*{
* LOG_DBG("[FDVT_DEBUG] FDVT_flush\n");
* return 0;
*}
*/
static int FDVT_release(struct inode *inode, struct file *file)
{
LOG_DBG("[FDVT_DEBUG]\n");
/*if (pBuff) {*/
kfree(pBuff);
pBuff = NULL;
/*}*/
/*if (pread_buf) {*/
kfree(pread_buf);
pread_buf = NULL;
/*}*/
FDVT_WR32(0x00000000, FDVT_INT_EN);
g_FDVTIRQ = ioread32((void *)FDVT_INT);
#if IS_ENABLED(CONFIG_PM_SLEEP)
__pm_stay_awake(&fdvt_wake_lock);
#endif
mt_fdvt_clk_ctrl(0);
#if IS_ENABLED(CONFIG_PM_SLEEP)
__pm_relax(&fdvt_wake_lock);
#endif
spin_lock(&g_spinLock);
g_drvOpened = 0;
spin_unlock(&g_spinLock);
return 0;
}
static const struct file_operations FDVT_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = FDVT_ioctl,
.open = FDVT_open,
.release = FDVT_release,
#if IS_ENABLED(CONFIG_COMPAT)
.compat_ioctl = compat_FD_ioctl,
#endif
};
static int FDVT_probe(struct platform_device *dev)
{
#if LDVT_EARLY_PORTING_NO_CCF
struct device_node *node = NULL;
#endif
struct class_device;
int ret;
int i = 0;
int new_count;
struct class_device *class_dev = NULL;
struct fdvt_device *tempFdvt;
#if IS_ENABLED(CONFIG_OF)
struct fdvt_device *fdvt_dev;
#endif
#if LDVT_EARLY_PORTING_NO_CCF
node = of_find_compatible_node(NULL, NULL, "mediatek,imgsys_config");
if (!node) {
LOG_ERR("find IMGSYS_CONFIG node failed!!!\n");
return -ENODEV;
}
IMGSYS_CONFIG_BASE = of_iomap(node, 0);
if (!IMGSYS_CONFIG_BASE) {
LOG_ERR("unable to map IMGSYS_CONFIG_BASE registers!!!\n");
return -ENODEV;
}
LOG_DBG("[FDVT_DEBUG] IMGSYS_CONFIG_BASE: %lx\n",
(unsigned long)IMGSYS_CONFIG_BASE);
node = of_find_compatible_node(NULL, NULL, "mediatek,camsys_config");
if (!node) {
LOG_ERR("find CAMSYS_CONFIG node failed!!!\n");
return -ENODEV;
}
CAMSYS_CONFIG_BASE = of_iomap(node, 0);
if (!CAMSYS_CONFIG_BASE) {
LOG_ERR("unable to map CAMSYS_CONFIG_BASE registers!!!\n");
return -ENODEV;
}
LOG_DBG("[FDVT_DEBUG] CAMSYS_CONFIG_BASE: %lx\n",
(unsigned long)CAMSYS_CONFIG_BASE);
#endif
nr_fdvt_devs = 0;
LOG_INF("FDVT PROBE!!!\n");
#if IS_ENABLED(CONFIG_OF)
LOG_DBG("[FDVT_DEBUG]\n");
if (dev == NULL) {
dev_info(&dev->dev, "dev is NULL");
return -ENXIO;
}
new_count = nr_fdvt_devs + 1;
tempFdvt = krealloc(
fdvt_devs,
sizeof(struct fdvt_device) * new_count,
GFP_KERNEL);
if (!tempFdvt) {
dev_info(&dev->dev, "Unable to realloc fdvt_devs\n");
return -ENOMEM;
}
fdvt_devs = tempFdvt;
fdvt_dev = &(fdvt_devs[nr_fdvt_devs]);
fdvt_dev->dev = &dev->dev;
/* iomap registers and irq*/
for (i = 0; i < FDVT_BASEADDR_NUM; i++) {
fdvt_dev->regs[i] = of_iomap(dev->dev.of_node, i);
if (!fdvt_dev->regs[i]) {
dev_info(&dev->dev, "of_iomap fail, i=%d\n", i);
return -ENOMEM;
}
gFDVT_Reg[i] = (unsigned long)fdvt_dev->regs[i];
LOG_INF("DT, i=%d, map_addr=0x%lx\n", i, gFDVT_Reg[i]);
}
/* get IRQ ID and request IRQ */
for (i = 0; i < FDVT_IRQ_IDX_NUM; i++) {
fdvt_dev->irq[i] = irq_of_parse_and_map(dev->dev.of_node, i);
gFDVT_Irq[i] = fdvt_dev->irq[i];
if (i == FDVT_IRQ_IDX) {
/* IRQF_TRIGGER_NONE dose not take effect here*/
/* real trigger mode set in dts file */
ret = request_irq(
fdvt_dev->irq[i],
(irq_handler_t)FDVT_irq,
IRQF_TRIGGER_NONE,
FDVT_DEVNAME,
NULL);
/* request_irq( */
/* FD_IRQ_BIT_ID, */
/* (irq_handler_t)FDVT_irq, */
/* IRQF_TRIGGER_LOW, */
/* FDVT_DEVNAME, */
/* NULL) */
}
if (ret) {
dev_info(&dev->dev, "request_irq fail, i=%d, irq=%d\n",
i, fdvt_dev->irq[i]);
return ret;
}
LOG_INF("DT, i=%d, map_irq=%d\n", i, fdvt_dev->irq[i]);
}
nr_fdvt_devs = new_count;
#endif
ret = alloc_chrdev_region(&FDVT_devno, 0, 1, FDVT_DEVNAME);
if (ret)
LOG_DBG("[FDVT_DEBUG]Can't get major number for FDVT device\n");
FDVT_cdev = cdev_alloc();
FDVT_cdev->owner = THIS_MODULE;
FDVT_cdev->ops = &FDVT_fops;
cdev_init(FDVT_cdev, &FDVT_fops);
ret = cdev_add(FDVT_cdev, FDVT_devno, 1);
if (ret < 0) {
LOG_DBG("[FDVT_DEBUG] Attatch file operation failed\n");
return -EFAULT;
}
#if !IS_ENABLED(CONFIG_OF)
/* Register Interrupt */
if (request_irq(
FD_IRQ_BIT_ID,
(irq_handler_t)FDVT_irq,
IRQF_TRIGGER_LOW,
FDVT_DEVNAME,
NULL) < 0)
LOG_DBG("[FDVT_DEBUG][ERROR] error to request FDVT irq\n");
else
LOG_DBG("[FDVT_DEBUG] success to request FDVT irq\n");
#endif
#if LDVT_EARLY_PORTING_NO_CCF
#else
/*CCF: Grab clock pointer (struct clk*) */
fd_clk.CG_IMGSYS_FDVT = devm_clk_get(&dev->dev, "FD_CLK_IMG_FDVT");
if (IS_ERR(fd_clk.CG_IMGSYS_FDVT)) {
LOG_ERR("cannot get CG_IMGSYS_FDVT clock\n");
return PTR_ERR(fd_clk.CG_IMGSYS_FDVT);
}
#endif
FDVT_class = class_create(THIS_MODULE, FDVT_DEVNAME);
class_dev = (struct class_device *)device_create(FDVT_class,
NULL,
FDVT_devno,
NULL,
FDVT_DEVNAME
);
/* Initialize waitqueue */
init_waitqueue_head(&g_FDVTWQ);
#if IS_ENABLED(CONFIG_PM_SLEEP)
wakeup_source_init(
&fdvt_wake_lock,
"fdvt_lock_wakelock");
#endif
LOG_DBG("[FDVT_DEBUG] Done\n");
return 0;
}
static int FDVT_remove(struct platform_device *dev)
{
int i4IRQ = 0;
LOG_DBG("[FDVT_DEBUG] FDVT_driver_exit\n");
FDVT_WR32(0x00000000, FDVT_INT_EN);
g_FDVTIRQ = ioread32((void *)FDVT_INT);
#if IS_ENABLED(CONFIG_PM_SLEEP)
__pm_stay_awake(&fdvt_wake_lock);
#endif
mt_fdvt_clk_ctrl(0);
#if IS_ENABLED(CONFIG_PM_SLEEP)
__pm_relax(&fdvt_wake_lock);
#endif
device_destroy(FDVT_class, FDVT_devno);
class_destroy(FDVT_class);
cdev_del(FDVT_cdev);
unregister_chrdev_region(FDVT_devno, 1);
i4IRQ = platform_get_irq(dev, 0);
free_irq(i4IRQ, NULL);
/*if (pBuff) {*/
kfree(pBuff);
pBuff = NULL;
/*}*/
/*if (pread_buf) {*/
kfree(pread_buf);
pread_buf = NULL;
/*}*/
return 0;
}
static int FDVT_suspend(struct platform_device *dev, pm_message_t state)
{
spin_lock(&g_spinLock);
if (g_drvOpened > 0) {
LOG_INF("[FDVT_DEBUG]\n");
mt_fdvt_clk_ctrl(0);
g_isSuspend = 1;
}
spin_unlock(&g_spinLock);
return 0;
}
static int FDVT_resume(struct platform_device *dev)
{
spin_lock(&g_spinLock);
if (g_isSuspend) {
LOG_INF("[FDVT_DEBUG]\n");
mt_fdvt_clk_ctrl(1);
g_isSuspend = 0;
}
spin_unlock(&g_spinLock);
return 0;
}
#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id fdvt_of_ids[] = {
{ .compatible = "mediatek,fdvt", },
{}
};
#endif
static struct platform_driver FDVT_driver = {
.driver = {
.name = FDVT_DEVNAME,
.owner = THIS_MODULE,
#if IS_ENABLED(CONFIG_OF)
.of_match_table = fdvt_of_ids,
#endif
},
.probe = FDVT_probe,
.remove = FDVT_remove,
.suspend = FDVT_suspend,
.resume = FDVT_resume,
};
/* Device Tree Architecture Don't Use This Struct
*static struct platform_device FDVT_device = {
* .name = FDVT_DEVNAME,
* .id = 0,
*};
*/
#if IS_ENABLED(CONFIG_HAS_EARLYSUSPEND)
static void FDVT_early_suspend(struct early_suspend *h)
{
/* LOG_DBG("[FDVT_DEBUG]\n"); */
/* mt_fdvt_clk_ctrl(0); */
}
static void FDVT_early_resume(struct early_suspend *h)
{
/* LOG_DBG("[FDVT_DEBUG]\n"); */
/* mt_fdvt_clk_ctrl(1); */
}
static struct early_suspend FDVT_early_suspend_desc = {
.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1,
.suspend = FDVT_early_suspend,
.resume = FDVT_early_resume,
};
#endif
static int __init FDVT_driver_init(void)
{
int ret;
LOG_DBG("[FDVT_DEBUG]\n");
if (platform_driver_register(&FDVT_driver)) {
LOG_DBG("[FDVT_DEBUG][ERROR] failed to register FDVT Driver\n");
ret = -ENODEV;
return ret;
}
#if IS_ENABLED(CONFIG_HAS_EARLYSUSPEND)
register_early_suspend(&FDVT_early_suspend_desc);
#endif
#if (MTK_FD_LARB == 2)
m4u_register_fault_callback(M4U_PORT_CAM_FD_RP,
FDVT_M4U_TranslationFault_callback, NULL);
m4u_register_fault_callback(M4U_PORT_CAM_FD_WR,
FDVT_M4U_TranslationFault_callback, NULL);
m4u_register_fault_callback(M4U_PORT_CAM_FD_RB,
FDVT_M4U_TranslationFault_callback, NULL);
#else
m4u_register_fault_callback(M4U_PORT_CAM_FDVT_RP,
FDVT_M4U_TranslationFault_callback, NULL);
m4u_register_fault_callback(M4U_PORT_CAM_FDVT_WR,
FDVT_M4U_TranslationFault_callback, NULL);
m4u_register_fault_callback(M4U_PORT_CAM_FDVT_RB,
FDVT_M4U_TranslationFault_callback, NULL);
#endif
LOG_DBG("[FDVT_DEBUG] Done\n");
return 0;
}
static void __exit FDVT_driver_exit(void)
{
LOG_DBG("[FDVT_DEBUG]\n");
device_destroy(FDVT_class, FDVT_devno);
class_destroy(FDVT_class);
cdev_del(FDVT_cdev);
unregister_chrdev_region(FDVT_devno, 1);
platform_driver_unregister(&FDVT_driver);
}
module_init(FDVT_driver_init);
module_exit(FDVT_driver_exit);
MODULE_AUTHOR("MM/MM3/SW5");
MODULE_DESCRIPTION("FDVT Driver");
MODULE_LICENSE("GPL");