/*
 * Copyright (C) 2021 Alibaba Group Holding Limited
 * Author: Shenwuyi <shenwuyi.swy@alibaba-inc.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#ifndef __VI_PRE_H__
#define __VI_PRE_H__

#include <linux/io.h>
#include <linux/of.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/of_irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_dma.h>
#include <linux/device.h>
#include <linux/videodev2.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>

#define VI_PRE_DEV_NAME			"vi_pre"
#define VI_PRE_NAME "vipre"
#define VI_PRE_MAXCNT 1

#define HDRPRO_CTRL(n)	(0x0094 + (n-1) * 4)
#define HDRPRO_COE(n)	(0x009c + (n-1) * 4)
#define HDRPRO_LINW(n)	(0x00b0 + (n-1) * 4)
#define HDRPRO_LINA(n)	(0x00d0 + (n-1) * 4)
#define HDRPRO_LINB(n)	(0x0110 + (n-1) * 4)
#define MIPI2DMA_CTRL(n) (0x0198 + (n) * 4)


#define VIPRE_BUS_ERR (1 << 5)
#define VIPRE_FIFO_OVER (1 << 4)
#define VIPRE_IDLE_DONE (1 << 3)
#define VIPRE_NMOVERFLOW (1 << 2)
#define VIPRE_LINE_DONE (1 << 1)
#define VIPRE_FRAME_DONE (1 << 0)

/* mipi2dma ctrl0  */
enum mipi2dma_ctrl0_regval {
	//RAWMOD
	MIPI2DMA_CTRL0_RAW6 = 0 << 4,
	MIPI2DMA_CTRL0_RAW7 = 1 << 4,
	MIPI2DMA_CTRL0_RAW8 = 2 << 4,
	MIPI2DMA_CTRL0_RAW10 = 3 << 4,
	MIPI2DMA_CTRL0_RAW12 = 4 << 4,

	//RAWPOS
	MIPI2DMA_CTRL0_LOW_BIT_MODE = 0 << 3,
	MIPI2DMA_CTRL0_HIGH_BIT_MODE = 1 << 3,
	//mnum
	MIPI2DMA_CTRL0_1_FRAME = 0 << 1,
	MIPI2DMA_CTRL0_2_FRAME = 1 << 1,
	MIPI2DMA_CTRL0_3_FRAME = 2 << 1,
	MIPI2DMA_CTRL0_4_FRAME = 3 << 1,
	//mnmod
	MIPI2DMA_CTRL0_MODE_M_FRAME = 0 << 0,
	MIPI2DMA_CTRL0_MODE_N_LINE = 1 << 0,
};

/* mipi2dma ctrl1  */
enum mipi2dma_ctrl1_regval {
	//MIPI2DMA_WBURSTLEN
	MIPI2DMA_CTRL1_WBURSTLEN_4 = 3 << 16,
	MIPI2DMA_CTRL1_WBURSTLEN_8 = 7 << 16,
	MIPI2DMA_CTRL1_WBURSTLEN_16 = 15 << 16,
};

/* mipi2dma ctrl10  */
enum mipi2dma_ctrl10_regval {
	MIPI2DMA_START = 1 << 0,
	MIPI2DMA_STOP = 0 << 0,
};

/* mipi2dma ctrl51  */
enum mipi2dma_ctrl51_regval {
	MIPI2DMA_CTRL51_CROSS_4K_EN = 1 << 0,
	MIPI2DMA_CTRL51_CROSS_4K_DIS = 0 << 0,
};

//MIPI2DMA
#define MIPI2DMA_CTRL1_WOSNUM_SHIFT 0

#define MIPI2DMA_CTRL3_VERTICAL_SHIFT 16
#define MIPI2DMA_CTRL3_HORIZON_SHIFT 0

#define MIPI2DMA_CTRL4_BURSTREM_SHIFT 27
#define MIPI2DMA_CTRL4_READNUM_SHIFT 16
#define MIPI2DMA_CTRL4_HORIZON_CNT128_SHIFT 0

#define MIPI2DMA_CTRL5_N_NLINENUM_SHIFT 16
#define MIPI2DMA_CTRL5_N_LINENUM_SHIFT 0

#define MIPI2DMA_CTRL6_N_STRIDE_SHIFT 0

#define MIPI2DMA_CTRL7_M0_STRIDE_SHIFT 16
#define MIPI2DMA_CTRL7_M1_STRIDE_SHIFT 0

#define MIPI2DMA_CTRL8_M2_STRIDE_SHIFT 16
#define MIPI2DMA_CTRL8_M3_STRIDE_SHIFT 0

#define MIPI2DMA_CTRL15_N_SADDR_ID0_H_SHIFT 0
#define MIPI2DMA_CTRL16_N_SADDR_ID0_L_SHIFT 0
#define MIPI2DMA_CTRL17_N_SADDR_ID1_H_SHIFT 0
#define MIPI2DMA_CTRL18_N_SADDR_ID1_L_SHIFT 0
#define MIPI2DMA_CTRL19_N_SADDR_ID2_H_SHIFT 0
#define MIPI2DMA_CTRL20_N_SADDR_ID2_L_SHIFT 0

#define MIPI2DMA_CTRL25_M0_SADDR_ID0_H_SHIFT 0
#define MIPI2DMA_CTRL26_M0_SADDR_ID0_L_SHIFT 0
#define MIPI2DMA_CTRL27_M0_SADDR_ID1_H_SHIFT 0
#define MIPI2DMA_CTRL28_M0_SADDR_ID1_L_SHIFT 0
#define MIPI2DMA_CTRL29_M0_SADDR_ID2_H_SHIFT 0
#define MIPI2DMA_CTRL30_M0_SADDR_ID2_L_SHIFT 0

#define MIPI2DMA_CTRL31_M1_SADDR_ID0_H_SHIFT 0
#define MIPI2DMA_CTRL32_M1_SADDR_ID0_L_SHIFT 0
#define MIPI2DMA_CTRL33_M1_SADDR_ID1_H_SHIFT 0
#define MIPI2DMA_CTRL34_M1_SADDR_ID1_L_SHIFT 0
#define MIPI2DMA_CTRL35_M1_SADDR_ID2_H_SHIFT 0
#define MIPI2DMA_CTRL36_M1_SADDR_ID2_L_SHIFT 0

#define MIPI2DMA_CTRL37_M2_SADDR_ID0_H_SHIFT 0
#define MIPI2DMA_CTRL38_M2_SADDR_ID0_L_SHIFT 0
#define MIPI2DMA_CTRL39_M2_SADDR_ID1_H_SHIFT 0
#define MIPI2DMA_CTRL40_M2_SADDR_ID1_L_SHIFT 0
#define MIPI2DMA_CTRL41_M2_SADDR_ID2_H_SHIFT 0
#define MIPI2DMA_CTRL42_M2_SADDR_ID2_L_SHIFT 0

#define MIPI2DMA_CTRL44_BUSERR_MASK_SHIFT 21
#define MIPI2DMA_CTRL44_FIFO_OVERERR_MASK_SHIFT 20
#define MIPI2DMA_CTRL44_IDLE_DONE_MASK_SHIFT 19
#define MIPI2DMA_CTRL44_MN_OVERERR_MASK_SHIFT 18
#define MIPI2DMA_CTRL44_NLINE_DONE_MASK_SHIFT 17
#define MIPI2DMA_CTRL44_MFRAME_DONE_MASK_SHIFT 16

#define MIPI2DMA_CTRL45_M3_SADDR_ID0_H_SHIFT 0
#define MIPI2DMA_CTRL46_M3_SADDR_ID0_L_SHIFT 0
#define MIPI2DMA_CTRL47_M3_SADDR_ID1_H_SHIFT 0
#define MIPI2DMA_CTRL48_M3_SADDR_ID1_L_SHIFT 0
#define MIPI2DMA_CTRL49_M3_SADDR_ID2_H_SHIFT 0
#define MIPI2DMA_CTRL50_M3_SADDR_ID2_L_SHIFT 0

//HDRPRO
#define HDRPRO_CTRL1_HDRPRO_RAWMOD_MASK		0x00e00000
#define HDRPRO_CTRL1_BAYER_MODSEL_MASK		0x00180000
#define HDRPRO_CTRL1_COLOR_MODSEL_MASK		0x00070000
#define HDRPRO_CTRL1_LAST_DELAY_MASK		0x0000fff8
#define HDRPRO_CTRL1_HDRPRO_ID_MASK			0x00000006
#define HDRPRO_CTRL1_HDRPRO_EN_MASK			0x00000001

#define HDRPRO_CTRL1_HDRPRO_ID_SHIFT 1

#define HDRPRO_CTRL2_VERTICAL_MASK 0x1fff0000
#define HDRPRO_CTRL2_HORIZON_MASK 0x00001fff

#define HDRPRO_CTRL2_VERTICAL_SHIFT 16
#define HDRPRO_CTRL2_HORIZON_SHIFT 0

#define HDRPRO_COE1_BE_BLACK_WR_MASK		0xf0000000
#define HDRPRO_COE1_BE_BLACK_WB_MASK		0x0f000000
#define HDRPRO_COE1_BE_BLACK_WG0_MASK		0x00f00000
#define HDRPRO_COE1_BE_BLACK_WG1_MASK		0x000f0000
#define HDRPRO_COE1_BE_COLOR_WG0_00_MASK	0x0000f000
#define HDRPRO_COE1_BE_COLOR_WG0_01_MASK	0x00000f00
#define HDRPRO_COE1_BE_COLOR_WG0_02_MASK	0x000000f0
#define HDRPRO_COE1_BE_COLOR_WG0_10_MASK	0x0000000f

#define HDRPRO_COE1_BE_BLACK_WR_SHIFT 28
#define HDRPRO_COE1_BE_BLACK_WB_SHIFT 24
#define HDRPRO_COE1_BE_BLACK_WG0_SHIFT 20
#define HDRPRO_COE1_BE_BLACK_WG1_SHIFT 16
#define HDRPRO_COE1_BE_COLOR_WG0_00_SHIFT 12
#define HDRPRO_COE1_BE_COLOR_WG0_01_SHIFT 8
#define HDRPRO_COE1_BE_COLOR_WG0_02_SHIFT 4
#define HDRPRO_COE1_BE_COLOR_WG0_10_SHIFT 0

#define HDRPRO_COE2_BE_COLOR_WG0_11_SHIFT 28
#define HDRPRO_COE2_BE_COLOR_WG0_12_SHIFT 24
#define HDRPRO_COE2_BE_COLOR_WG0_20_SHIFT 20
#define HDRPRO_COE2_BE_COLOR_WG0_21_SHIFT 16
#define HDRPRO_COE2_BE_COLOR_WG0_22_SHIFT 12
#define HDRPRO_COE2_BE_COLOR_WG1_00_SHIFT 8
#define HDRPRO_COE2_BE_COLOR_WG1_01_SHIFT 4
#define HDRPRO_COE2_BE_COLOR_WG1_02_SHIFT 0

#define HDRPRO_COE3_BE_COLOR_WG1_10_SHIFT 28
#define HDRPRO_COE3_BE_COLOR_WG1_11_SHIFT 24
#define HDRPRO_COE3_BE_COLOR_WG1_12_SHIFT 20
#define HDRPRO_COE3_BE_COLOR_WG1_20_SHIFT 16
#define HDRPRO_COE3_BE_COLOR_WG1_21_SHIFT 12
#define HDRPRO_COE3_BE_COLOR_WG1_22_SHIFT 8
#define HDRPRO_COE3_BE_COLOR_WR_00_SHIFT 4
#define HDRPRO_COE3_BE_COLOR_WR_01_SHIFT 0

#define HDRPRO_COE4_BE_COLOR_WR_02_SHIFT 28
#define HDRPRO_COE4_BE_COLOR_WR_10_SHIFT 24
#define HDRPRO_COE4_BE_COLOR_WR_11_SHIFT 20
#define HDRPRO_COE4_BE_COLOR_WR_12_SHIFT 16
#define HDRPRO_COE4_BE_COLOR_WR_20_SHIFT 12
#define HDRPRO_COE4_BE_COLOR_WR_21_SHIFT 8
#define HDRPRO_COE4_BE_COLOR_WR_22_SHIFT 4
#define HDRPRO_COE4_BE_COLOR_WB_00_SHIFT 0

#define HDRPRO_COE5_BE_COLOR_WB_01_SHIFT 28
#define HDRPRO_COE5_BE_COLOR_WB_02_SHIFT 24
#define HDRPRO_COE5_BE_COLOR_WB_10_SHIFT 20
#define HDRPRO_COE5_BE_COLOR_WB_11_SHIFT 16
#define HDRPRO_COE5_BE_COLOR_WB_12_SHIFT 12
#define HDRPRO_COE5_BE_COLOR_WB_20_SHIFT 8
#define HDRPRO_COE5_BE_COLOR_WB_21_SHIFT 4
#define HDRPRO_COE5_BE_COLOR_WB_22_SHIFT 0

#define HDRPRO_LINW1_W1_MASK	0x0fff0000
#define HDRPRO_LINW1_W2_MASK	0x00000fff
#define HDRPRO_LINW2_W3_MASK	0x0fff0000
#define HDRPRO_LINW2_W4_MASK	0x00000fff
#define HDRPRO_LINW3_W5_MASK	0x0fff0000
#define HDRPRO_LINW3_W6_MASK	0x00000fff
#define HDRPRO_LINW4_W7_MASK	0x0fff0000
#define HDRPRO_LINW4_W8_MASK	0x00000fff
#define HDRPRO_LINW5_W9_MASK	0x0fff0000
#define HDRPRO_LINW5_W10_MASK 	0x00000fff
#define HDRPRO_LINW6_W11_MASK 	0x0fff0000
#define HDRPRO_LINW6_W12_MASK 	0x00000fff
#define HDRPRO_LINW7_W13_MASK 	0x0fff0000
#define HDRPRO_LINW7_W14_MASK 	0x00000fff
#define HDRPRO_LINW8_W15_MASK 	0x0fff0000
#define HDRPRO_LINW8_W16_MASK 	0x00000fff

#define HDRPRO_LINW1_W1_SHIFT	16
#define HDRPRO_LINW1_W2_SHIFT	0
#define HDRPRO_LINW2_W3_SHIFT	16
#define HDRPRO_LINW2_W4_SHIFT	0
#define HDRPRO_LINW3_W5_SHIFT	16
#define HDRPRO_LINW3_W6_SHIFT	0
#define HDRPRO_LINW4_W7_SHIFT	16
#define HDRPRO_LINW4_W8_SHIFT	0
#define HDRPRO_LINW5_W9_SHIFT	16
#define HDRPRO_LINW5_W10_SHIFT 0
#define HDRPRO_LINW6_W11_SHIFT 16
#define HDRPRO_LINW6_W12_SHIFT 0
#define HDRPRO_LINW7_W13_SHIFT 16
#define HDRPRO_LINW7_W14_SHIFT 0
#define HDRPRO_LINW8_W15_SHIFT 16
#define HDRPRO_LINW8_W16_SHIFT 0

#define HDRPRO_LINA1_A1_MASK 0x000fffff
#define HDRPRO_LINA2_A2_MASK 0x000fffff
#define HDRPRO_LINA3_A3_MASK 0x000fffff
#define HDRPRO_LINA4_A4_MASK 0x000fffff
#define HDRPRO_LINA5_A5_MASK 0x000fffff
#define HDRPRO_LINA6_A6_MASK 0x000fffff
#define HDRPRO_LINA7_A7_MASK 0x000fffff
#define HDRPRO_LINA8_A8_MASK 0x000fffff
#define HDRPRO_LINA9_A9_MASK 0x000fffff
#define HDRPRO_LINA10_A10_MASK 0x000fffff
#define HDRPRO_LINA11_A11_MASK 0x000fffff
#define HDRPRO_LINA12_A12_MASK 0x000fffff
#define HDRPRO_LINA13_A13_MASK 0x000fffff
#define HDRPRO_LINA14_A14_MASK 0x000fffff
#define HDRPRO_LINA15_A15_MASK 0x000fffff
#define HDRPRO_LINA16_A16_MASK 0x000fffff

#define HDRPRO_LINA1_A1_SHIFT 0
#define HDRPRO_LINA2_A2_SHIFT 0
#define HDRPRO_LINA3_A3_SHIFT 0
#define HDRPRO_LINA4_A4_SHIFT 0
#define HDRPRO_LINA5_A5_SHIFT 0
#define HDRPRO_LINA6_A6_SHIFT 0
#define HDRPRO_LINA7_A7_SHIFT 0
#define HDRPRO_LINA8_A8_SHIFT 0
#define HDRPRO_LINA9_A9_SHIFT 0
#define HDRPRO_LINA10_A10_SHIFT 0
#define HDRPRO_LINA11_A11_SHIFT 0
#define HDRPRO_LINA12_A12_SHIFT 0
#define HDRPRO_LINA13_A13_SHIFT 0
#define HDRPRO_LINA14_A14_SHIFT 0
#define HDRPRO_LINA15_A15_SHIFT 0
#define HDRPRO_LINA16_A16_SHIFT 0

#define HDRPRO_LINB1_B1_MASK 0x0000ffff
#define HDRPRO_LINB2_B2_MASK 0x0000ffff
#define HDRPRO_LINB3_B3_MASK 0x0000ffff
#define HDRPRO_LINB4_B4_MASK 0x0000ffff
#define HDRPRO_LINB5_B5_MASK 0x0000ffff
#define HDRPRO_LINB6_B6_MASK 0x0000ffff
#define HDRPRO_LINB7_B7_MASK 0x0000ffff
#define HDRPRO_LINB8_B8_MASK 0x0000ffff
#define HDRPRO_LINB9_B9_MASK 0x0000ffff
#define HDRPRO_LINB10_B10_MASK 0x0000ffff
#define HDRPRO_LINB11_B11_MASK 0x0000ffff
#define HDRPRO_LINB12_B12_MASK 0x0000ffff
#define HDRPRO_LINB13_B13_MASK 0x0000ffff
#define HDRPRO_LINB14_B14_MASK 0x0000ffff
#define HDRPRO_LINB15_B15_MASK 0x0000ffff
#define HDRPRO_LINB16_B16_MASK 0x0000ffff

#define HDRPRO_LINB1_B1_SHIFT 0
#define HDRPRO_LINB2_B2_SHIFT 0
#define HDRPRO_LINB3_B3_SHIFT 0
#define HDRPRO_LINB4_B4_SHIFT 0
#define HDRPRO_LINB5_B5_SHIFT 0
#define HDRPRO_LINB6_B6_SHIFT 0
#define HDRPRO_LINB7_B7_SHIFT 0
#define HDRPRO_LINB8_B8_SHIFT 0
#define HDRPRO_LINB9_B9_SHIFT 0
#define HDRPRO_LINB10_B10_SHIFT 0
#define HDRPRO_LINB11_B11_SHIFT 0
#define HDRPRO_LINB12_B12_SHIFT 0
#define HDRPRO_LINB13_B13_SHIFT 0
#define HDRPRO_LINB14_B14_SHIFT 0
#define HDRPRO_LINB15_B15_SHIFT 0
#define HDRPRO_LINB16_B16_SHIFT 0

struct vi_pre_dev {
	int id;
	int irq;
	dev_t devt;
	struct class *class;
	struct cdev cdev;
    spinlock_t slock; /* interrupt handling lock */
	struct mutex mutex;
	void __iomem *reg_base;
	unsigned long cnt; //used to cnt frame num or line num;
    int update_frame_id;
    int update_vc_id;
	bool is_mframe_mode;
    struct clk *aclk;
    struct clk *pclk;
    struct clk *pixclk;
    struct platform_device *pdev;
};

#endif/*__VI_PRE_H__*/
