xref: /OK3568_Linux_fs/kernel/drivers/media/platform/exynos4-is/fimc-is.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Authors: Younghwan Joo <yhwan.joo@samsung.com>
8*4882a593Smuzhiyun  *          Sylwester Nawrocki <s.nawrocki@samsung.com>
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun #ifndef FIMC_IS_H_
11*4882a593Smuzhiyun #define FIMC_IS_H_
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <asm/barrier.h>
14*4882a593Smuzhiyun #include <linux/clk.h>
15*4882a593Smuzhiyun #include <linux/device.h>
16*4882a593Smuzhiyun #include <linux/kernel.h>
17*4882a593Smuzhiyun #include <linux/pinctrl/consumer.h>
18*4882a593Smuzhiyun #include <linux/platform_device.h>
19*4882a593Smuzhiyun #include <linux/sizes.h>
20*4882a593Smuzhiyun #include <linux/spinlock.h>
21*4882a593Smuzhiyun #include <linux/types.h>
22*4882a593Smuzhiyun #include <media/videobuf2-v4l2.h>
23*4882a593Smuzhiyun #include <media/v4l2-ctrls.h>
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include "fimc-isp.h"
26*4882a593Smuzhiyun #include "fimc-is-command.h"
27*4882a593Smuzhiyun #include "fimc-is-sensor.h"
28*4882a593Smuzhiyun #include "fimc-is-param.h"
29*4882a593Smuzhiyun #include "fimc-is-regs.h"
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #define FIMC_IS_DRV_NAME		"exynos4-fimc-is"
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define FIMC_IS_FW_FILENAME		"exynos4_fimc_is_fw.bin"
34*4882a593Smuzhiyun #define FIMC_IS_SETFILE_6A3		"exynos4_s5k6a3_setfile.bin"
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #define FIMC_IS_FW_LOAD_TIMEOUT		1000 /* ms */
37*4882a593Smuzhiyun #define FIMC_IS_POWER_ON_TIMEOUT	1000 /* us */
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define FIMC_IS_SENSORS_NUM		2
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /* Memory definitions */
42*4882a593Smuzhiyun #define FIMC_IS_CPU_MEM_SIZE		(0xa00000)
43*4882a593Smuzhiyun #define FIMC_IS_CPU_BASE_MASK		((1 << 26) - 1)
44*4882a593Smuzhiyun #define FIMC_IS_REGION_SIZE		0x5000
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun #define FIMC_IS_DEBUG_REGION_OFFSET	0x0084b000
47*4882a593Smuzhiyun #define FIMC_IS_SHARED_REGION_OFFSET	0x008c0000
48*4882a593Smuzhiyun #define FIMC_IS_FW_INFO_LEN		31
49*4882a593Smuzhiyun #define FIMC_IS_FW_VER_LEN		7
50*4882a593Smuzhiyun #define FIMC_IS_FW_DESC_LEN		(FIMC_IS_FW_INFO_LEN + \
51*4882a593Smuzhiyun 					 FIMC_IS_FW_VER_LEN)
52*4882a593Smuzhiyun #define FIMC_IS_SETFILE_INFO_LEN	39
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define FIMC_IS_EXTRA_MEM_SIZE		(FIMC_IS_EXTRA_FW_SIZE + \
55*4882a593Smuzhiyun 					 FIMC_IS_EXTRA_SETFILE_SIZE + 0x1000)
56*4882a593Smuzhiyun #define FIMC_IS_EXTRA_FW_SIZE		0x180000
57*4882a593Smuzhiyun #define FIMC_IS_EXTRA_SETFILE_SIZE	0x4b000
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /* TODO: revisit */
60*4882a593Smuzhiyun #define FIMC_IS_FW_ADDR_MASK		((1 << 26) - 1)
61*4882a593Smuzhiyun #define FIMC_IS_FW_SIZE_MAX		(SZ_4M)
62*4882a593Smuzhiyun #define FIMC_IS_FW_SIZE_MIN		(SZ_32K)
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define ATCLK_MCUISP_FREQUENCY		100000000UL
65*4882a593Smuzhiyun #define ACLK_AXI_FREQUENCY		100000000UL
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun enum {
68*4882a593Smuzhiyun 	ISS_CLK_PPMUISPX,
69*4882a593Smuzhiyun 	ISS_CLK_PPMUISPMX,
70*4882a593Smuzhiyun 	ISS_CLK_LITE0,
71*4882a593Smuzhiyun 	ISS_CLK_LITE1,
72*4882a593Smuzhiyun 	ISS_CLK_MPLL,
73*4882a593Smuzhiyun 	ISS_CLK_ISP,
74*4882a593Smuzhiyun 	ISS_CLK_DRC,
75*4882a593Smuzhiyun 	ISS_CLK_FD,
76*4882a593Smuzhiyun 	ISS_CLK_MCUISP,
77*4882a593Smuzhiyun 	ISS_CLK_GICISP,
78*4882a593Smuzhiyun 	ISS_CLK_PWM_ISP,
79*4882a593Smuzhiyun 	ISS_CLK_MCUCTL_ISP,
80*4882a593Smuzhiyun 	ISS_CLK_UART,
81*4882a593Smuzhiyun 	ISS_GATE_CLKS_MAX,
82*4882a593Smuzhiyun 	ISS_CLK_ISP_DIV0 = ISS_GATE_CLKS_MAX,
83*4882a593Smuzhiyun 	ISS_CLK_ISP_DIV1,
84*4882a593Smuzhiyun 	ISS_CLK_MCUISP_DIV0,
85*4882a593Smuzhiyun 	ISS_CLK_MCUISP_DIV1,
86*4882a593Smuzhiyun 	ISS_CLK_ACLK200,
87*4882a593Smuzhiyun 	ISS_CLK_ACLK200_DIV,
88*4882a593Smuzhiyun 	ISS_CLK_ACLK400MCUISP,
89*4882a593Smuzhiyun 	ISS_CLK_ACLK400MCUISP_DIV,
90*4882a593Smuzhiyun 	ISS_CLKS_MAX
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun /* The driver's internal state flags */
94*4882a593Smuzhiyun enum {
95*4882a593Smuzhiyun 	IS_ST_IDLE,
96*4882a593Smuzhiyun 	IS_ST_PWR_ON,
97*4882a593Smuzhiyun 	IS_ST_A5_PWR_ON,
98*4882a593Smuzhiyun 	IS_ST_FW_LOADED,
99*4882a593Smuzhiyun 	IS_ST_OPEN_SENSOR,
100*4882a593Smuzhiyun 	IS_ST_SETFILE_LOADED,
101*4882a593Smuzhiyun 	IS_ST_INIT_DONE,
102*4882a593Smuzhiyun 	IS_ST_STREAM_ON,
103*4882a593Smuzhiyun 	IS_ST_STREAM_OFF,
104*4882a593Smuzhiyun 	IS_ST_CHANGE_MODE,
105*4882a593Smuzhiyun 	IS_ST_BLOCK_CMD_CLEARED,
106*4882a593Smuzhiyun 	IS_ST_SET_ZOOM,
107*4882a593Smuzhiyun 	IS_ST_PWR_SUBIP_ON,
108*4882a593Smuzhiyun 	IS_ST_END,
109*4882a593Smuzhiyun };
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun enum af_state {
112*4882a593Smuzhiyun 	FIMC_IS_AF_IDLE		= 0,
113*4882a593Smuzhiyun 	FIMC_IS_AF_SETCONFIG	= 1,
114*4882a593Smuzhiyun 	FIMC_IS_AF_RUNNING	= 2,
115*4882a593Smuzhiyun 	FIMC_IS_AF_LOCK		= 3,
116*4882a593Smuzhiyun 	FIMC_IS_AF_ABORT	= 4,
117*4882a593Smuzhiyun 	FIMC_IS_AF_FAILED	= 5,
118*4882a593Smuzhiyun };
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun enum af_lock_state {
121*4882a593Smuzhiyun 	FIMC_IS_AF_UNLOCKED	= 0,
122*4882a593Smuzhiyun 	FIMC_IS_AF_LOCKED	= 2
123*4882a593Smuzhiyun };
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun enum ae_lock_state {
126*4882a593Smuzhiyun 	FIMC_IS_AE_UNLOCKED	= 0,
127*4882a593Smuzhiyun 	FIMC_IS_AE_LOCKED	= 1
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun enum awb_lock_state {
131*4882a593Smuzhiyun 	FIMC_IS_AWB_UNLOCKED	= 0,
132*4882a593Smuzhiyun 	FIMC_IS_AWB_LOCKED	= 1
133*4882a593Smuzhiyun };
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun enum {
136*4882a593Smuzhiyun 	IS_METERING_CONFIG_CMD,
137*4882a593Smuzhiyun 	IS_METERING_CONFIG_WIN_POS_X,
138*4882a593Smuzhiyun 	IS_METERING_CONFIG_WIN_POS_Y,
139*4882a593Smuzhiyun 	IS_METERING_CONFIG_WIN_WIDTH,
140*4882a593Smuzhiyun 	IS_METERING_CONFIG_WIN_HEIGHT,
141*4882a593Smuzhiyun 	IS_METERING_CONFIG_MAX
142*4882a593Smuzhiyun };
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun struct is_setfile {
145*4882a593Smuzhiyun 	const struct firmware *info;
146*4882a593Smuzhiyun 	int state;
147*4882a593Smuzhiyun 	u32 sub_index;
148*4882a593Smuzhiyun 	u32 base;
149*4882a593Smuzhiyun 	size_t size;
150*4882a593Smuzhiyun };
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun struct is_fd_result_header {
153*4882a593Smuzhiyun 	u32 offset;
154*4882a593Smuzhiyun 	u32 count;
155*4882a593Smuzhiyun 	u32 index;
156*4882a593Smuzhiyun 	u32 curr_index;
157*4882a593Smuzhiyun 	u32 width;
158*4882a593Smuzhiyun 	u32 height;
159*4882a593Smuzhiyun };
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun struct is_af_info {
162*4882a593Smuzhiyun 	u16 mode;
163*4882a593Smuzhiyun 	u32 af_state;
164*4882a593Smuzhiyun 	u32 af_lock_state;
165*4882a593Smuzhiyun 	u32 ae_lock_state;
166*4882a593Smuzhiyun 	u32 awb_lock_state;
167*4882a593Smuzhiyun 	u16 pos_x;
168*4882a593Smuzhiyun 	u16 pos_y;
169*4882a593Smuzhiyun 	u16 prev_pos_x;
170*4882a593Smuzhiyun 	u16 prev_pos_y;
171*4882a593Smuzhiyun 	u16 use_af;
172*4882a593Smuzhiyun };
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun struct fimc_is_firmware {
175*4882a593Smuzhiyun 	const struct firmware *f_w;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	dma_addr_t paddr;
178*4882a593Smuzhiyun 	void *vaddr;
179*4882a593Smuzhiyun 	unsigned int size;
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	char info[FIMC_IS_FW_INFO_LEN + 1];
182*4882a593Smuzhiyun 	char version[FIMC_IS_FW_VER_LEN + 1];
183*4882a593Smuzhiyun 	char setfile_info[FIMC_IS_SETFILE_INFO_LEN + 1];
184*4882a593Smuzhiyun 	u8 state;
185*4882a593Smuzhiyun };
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun struct fimc_is_memory {
188*4882a593Smuzhiyun 	/* physical base address */
189*4882a593Smuzhiyun 	dma_addr_t paddr;
190*4882a593Smuzhiyun 	/* virtual base address */
191*4882a593Smuzhiyun 	void *vaddr;
192*4882a593Smuzhiyun 	/* total length */
193*4882a593Smuzhiyun 	unsigned int size;
194*4882a593Smuzhiyun };
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun #define FIMC_IS_I2H_MAX_ARGS	12
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun struct i2h_cmd {
199*4882a593Smuzhiyun 	u32 cmd;
200*4882a593Smuzhiyun 	u32 sensor_id;
201*4882a593Smuzhiyun 	u16 num_args;
202*4882a593Smuzhiyun 	u32 args[FIMC_IS_I2H_MAX_ARGS];
203*4882a593Smuzhiyun };
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun struct h2i_cmd {
206*4882a593Smuzhiyun 	u16 cmd_type;
207*4882a593Smuzhiyun 	u32 entry_id;
208*4882a593Smuzhiyun };
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun #define FIMC_IS_DEBUG_MSG	0x3f
211*4882a593Smuzhiyun #define FIMC_IS_DEBUG_LEVEL	3
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun struct fimc_is_setfile {
214*4882a593Smuzhiyun 	const struct firmware *info;
215*4882a593Smuzhiyun 	unsigned int state;
216*4882a593Smuzhiyun 	unsigned int size;
217*4882a593Smuzhiyun 	u32 sub_index;
218*4882a593Smuzhiyun 	u32 base;
219*4882a593Smuzhiyun };
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun struct chain_config {
222*4882a593Smuzhiyun 	struct global_param	global;
223*4882a593Smuzhiyun 	struct sensor_param	sensor;
224*4882a593Smuzhiyun 	struct isp_param	isp;
225*4882a593Smuzhiyun 	struct drc_param	drc;
226*4882a593Smuzhiyun 	struct fd_param		fd;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	unsigned long		p_region_index[2];
229*4882a593Smuzhiyun };
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun /**
232*4882a593Smuzhiyun  * struct fimc_is - fimc-is data structure
233*4882a593Smuzhiyun  * @pdev: pointer to FIMC-IS platform device
234*4882a593Smuzhiyun  * @pctrl: pointer to pinctrl structure for this device
235*4882a593Smuzhiyun  * @v4l2_dev: pointer to top the level v4l2_device
236*4882a593Smuzhiyun  * @lock: mutex serializing video device and the subdev operations
237*4882a593Smuzhiyun  * @slock: spinlock protecting this data structure and the hw registers
238*4882a593Smuzhiyun  * @clocks: FIMC-LITE gate clock
239*4882a593Smuzhiyun  * @regs: MCUCTL mmapped registers region
240*4882a593Smuzhiyun  * @pmu_regs: PMU ISP mmapped registers region
241*4882a593Smuzhiyun  * @irq_queue: interrupt handling waitqueue
242*4882a593Smuzhiyun  * @lpm: low power mode flag
243*4882a593Smuzhiyun  * @state: internal driver's state flags
244*4882a593Smuzhiyun  */
245*4882a593Smuzhiyun struct fimc_is {
246*4882a593Smuzhiyun 	struct platform_device		*pdev;
247*4882a593Smuzhiyun 	struct pinctrl			*pctrl;
248*4882a593Smuzhiyun 	struct v4l2_device		*v4l2_dev;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	struct fimc_is_firmware		fw;
251*4882a593Smuzhiyun 	struct fimc_is_memory		memory;
252*4882a593Smuzhiyun 	struct firmware			*f_w;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	struct fimc_isp			isp;
255*4882a593Smuzhiyun 	struct fimc_is_sensor		sensor[FIMC_IS_SENSORS_NUM];
256*4882a593Smuzhiyun 	struct fimc_is_setfile		setfile;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	struct v4l2_ctrl_handler	ctrl_handler;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	struct mutex			lock;
261*4882a593Smuzhiyun 	spinlock_t			slock;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	struct clk			*clocks[ISS_CLKS_MAX];
264*4882a593Smuzhiyun 	void __iomem			*regs;
265*4882a593Smuzhiyun 	void __iomem			*pmu_regs;
266*4882a593Smuzhiyun 	int				irq;
267*4882a593Smuzhiyun 	wait_queue_head_t		irq_queue;
268*4882a593Smuzhiyun 	u8				lpm;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	unsigned long			state;
271*4882a593Smuzhiyun 	unsigned int			sensor_index;
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	struct i2h_cmd			i2h_cmd;
274*4882a593Smuzhiyun 	struct h2i_cmd			h2i_cmd;
275*4882a593Smuzhiyun 	struct is_fd_result_header	fd_header;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	struct chain_config		config[IS_SC_MAX];
278*4882a593Smuzhiyun 	unsigned			config_index;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	struct is_region		*is_p_region;
281*4882a593Smuzhiyun 	dma_addr_t			is_dma_p_region;
282*4882a593Smuzhiyun 	struct is_share_region		*is_shared_region;
283*4882a593Smuzhiyun 	struct is_af_info		af;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	struct dentry			*debugfs_entry;
286*4882a593Smuzhiyun };
287*4882a593Smuzhiyun 
fimc_isp_to_is(struct fimc_isp * isp)288*4882a593Smuzhiyun static inline struct fimc_is *fimc_isp_to_is(struct fimc_isp *isp)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun 	return container_of(isp, struct fimc_is, isp);
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun 
__get_curr_is_config(struct fimc_is * is)293*4882a593Smuzhiyun static inline struct chain_config *__get_curr_is_config(struct fimc_is *is)
294*4882a593Smuzhiyun {
295*4882a593Smuzhiyun 	return &is->config[is->config_index];
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun 
fimc_is_mem_barrier(void)298*4882a593Smuzhiyun static inline void fimc_is_mem_barrier(void)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun 	mb();
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun 
fimc_is_set_param_bit(struct fimc_is * is,int num)303*4882a593Smuzhiyun static inline void fimc_is_set_param_bit(struct fimc_is *is, int num)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun 	struct chain_config *cfg = &is->config[is->config_index];
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	set_bit(num, &cfg->p_region_index[0]);
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun 
fimc_is_set_param_ctrl_cmd(struct fimc_is * is,int cmd)310*4882a593Smuzhiyun static inline void fimc_is_set_param_ctrl_cmd(struct fimc_is *is, int cmd)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun 	is->is_p_region->parameter.isp.control.cmd = cmd;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun 
mcuctl_write(u32 v,struct fimc_is * is,unsigned int offset)315*4882a593Smuzhiyun static inline void mcuctl_write(u32 v, struct fimc_is *is, unsigned int offset)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun 	writel(v, is->regs + offset);
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun 
mcuctl_read(struct fimc_is * is,unsigned int offset)320*4882a593Smuzhiyun static inline u32 mcuctl_read(struct fimc_is *is, unsigned int offset)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun 	return readl(is->regs + offset);
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun 
pmuisp_write(u32 v,struct fimc_is * is,unsigned int offset)325*4882a593Smuzhiyun static inline void pmuisp_write(u32 v, struct fimc_is *is, unsigned int offset)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun 	writel(v, is->pmu_regs + offset);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun 
pmuisp_read(struct fimc_is * is,unsigned int offset)330*4882a593Smuzhiyun static inline u32 pmuisp_read(struct fimc_is *is, unsigned int offset)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun 	return readl(is->pmu_regs + offset);
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun int fimc_is_wait_event(struct fimc_is *is, unsigned long bit,
336*4882a593Smuzhiyun 		       unsigned int state, unsigned int timeout);
337*4882a593Smuzhiyun int fimc_is_cpu_set_power(struct fimc_is *is, int on);
338*4882a593Smuzhiyun int fimc_is_start_firmware(struct fimc_is *is);
339*4882a593Smuzhiyun int fimc_is_hw_initialize(struct fimc_is *is);
340*4882a593Smuzhiyun void fimc_is_log_dump(const char *level, const void *buf, size_t len);
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun #endif /* FIMC_IS_H_ */
343