1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * camss-vfe-4-1.c
4  *
5  * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.1
6  *
7  * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
8  * Copyright (C) 2015-2018 Linaro Ltd.
9  */
10 
11 #include <linux/interrupt.h>
12 #include <linux/io.h>
13 #include <linux/iopoll.h>
14 
15 #include "camss.h"
16 #include "camss-vfe.h"
17 
18 #define VFE_0_HW_VERSION		0x000
19 
20 #define VFE_0_GLOBAL_RESET_CMD		0x00c
21 #define VFE_0_GLOBAL_RESET_CMD_CORE	BIT(0)
22 #define VFE_0_GLOBAL_RESET_CMD_CAMIF	BIT(1)
23 #define VFE_0_GLOBAL_RESET_CMD_BUS	BIT(2)
24 #define VFE_0_GLOBAL_RESET_CMD_BUS_BDG	BIT(3)
25 #define VFE_0_GLOBAL_RESET_CMD_REGISTER	BIT(4)
26 #define VFE_0_GLOBAL_RESET_CMD_TIMER	BIT(5)
27 #define VFE_0_GLOBAL_RESET_CMD_PM	BIT(6)
28 #define VFE_0_GLOBAL_RESET_CMD_BUS_MISR	BIT(7)
29 #define VFE_0_GLOBAL_RESET_CMD_TESTGEN	BIT(8)
30 
31 #define VFE_0_MODULE_CFG		0x018
32 #define VFE_0_MODULE_CFG_DEMUX			BIT(2)
33 #define VFE_0_MODULE_CFG_CHROMA_UPSAMPLE	BIT(3)
34 #define VFE_0_MODULE_CFG_SCALE_ENC		BIT(23)
35 #define VFE_0_MODULE_CFG_CROP_ENC		BIT(27)
36 
37 #define VFE_0_CORE_CFG			0x01c
38 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR	0x4
39 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB	0x5
40 #define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY	0x6
41 #define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY	0x7
42 
43 #define VFE_0_IRQ_CMD			0x024
44 #define VFE_0_IRQ_CMD_GLOBAL_CLEAR	BIT(0)
45 
46 #define VFE_0_IRQ_MASK_0		0x028
47 #define VFE_0_IRQ_MASK_0_CAMIF_SOF			BIT(0)
48 #define VFE_0_IRQ_MASK_0_CAMIF_EOF			BIT(1)
49 #define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)		BIT((n) + 5)
50 #define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n)		\
51 	((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n))
52 #define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n)	BIT((n) + 8)
53 #define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n)	BIT((n) + 25)
54 #define VFE_0_IRQ_MASK_0_RESET_ACK			BIT(31)
55 #define VFE_0_IRQ_MASK_1		0x02c
56 #define VFE_0_IRQ_MASK_1_CAMIF_ERROR			BIT(0)
57 #define VFE_0_IRQ_MASK_1_VIOLATION			BIT(7)
58 #define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK		BIT(8)
59 #define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n)	BIT((n) + 9)
60 #define VFE_0_IRQ_MASK_1_RDIn_SOF(n)			BIT((n) + 29)
61 
62 #define VFE_0_IRQ_CLEAR_0		0x030
63 #define VFE_0_IRQ_CLEAR_1		0x034
64 
65 #define VFE_0_IRQ_STATUS_0		0x038
66 #define VFE_0_IRQ_STATUS_0_CAMIF_SOF			BIT(0)
67 #define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)		BIT((n) + 5)
68 #define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n)		\
69 	((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n))
70 #define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n)	BIT((n) + 8)
71 #define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n)	BIT((n) + 25)
72 #define VFE_0_IRQ_STATUS_0_RESET_ACK			BIT(31)
73 #define VFE_0_IRQ_STATUS_1		0x03c
74 #define VFE_0_IRQ_STATUS_1_VIOLATION			BIT(7)
75 #define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK		BIT(8)
76 #define VFE_0_IRQ_STATUS_1_RDIn_SOF(n)			BIT((n) + 29)
77 
78 #define VFE_0_IRQ_COMPOSITE_MASK_0	0x40
79 #define VFE_0_VIOLATION_STATUS		0x48
80 
81 #define VFE_0_BUS_CMD			0x4c
82 #define VFE_0_BUS_CMD_Mx_RLD_CMD(x)	BIT(x)
83 
84 #define VFE_0_BUS_CFG			0x050
85 
86 #define VFE_0_BUS_XBAR_CFG_x(x)		(0x58 + 0x4 * ((x) / 2))
87 #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN			BIT(1)
88 #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA	(0x3 << 4)
89 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT		8
90 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA		0
91 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0	5
92 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1	6
93 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2	7
94 
95 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n)		(0x06c + 0x24 * (n))
96 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT	0
97 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT	1
98 #define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n)	(0x070 + 0x24 * (n))
99 #define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n)	(0x074 + 0x24 * (n))
100 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n)		(0x078 + 0x24 * (n))
101 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT	2
102 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK	(0x1f << 2)
103 
104 #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n)		(0x07c + 0x24 * (n))
105 #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT	16
106 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n)	(0x080 + 0x24 * (n))
107 #define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n)	(0x084 + 0x24 * (n))
108 #define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n)	\
109 							(0x088 + 0x24 * (n))
110 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n)	\
111 							(0x08c + 0x24 * (n))
112 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF	0xffffffff
113 
114 #define VFE_0_BUS_PING_PONG_STATUS	0x268
115 
116 #define VFE_0_BUS_BDG_CMD		0x2c0
117 #define VFE_0_BUS_BDG_CMD_HALT_REQ	1
118 
119 #define VFE_0_BUS_BDG_QOS_CFG_0		0x2c4
120 #define VFE_0_BUS_BDG_QOS_CFG_0_CFG	0xaaa5aaa5
121 #define VFE_0_BUS_BDG_QOS_CFG_1		0x2c8
122 #define VFE_0_BUS_BDG_QOS_CFG_2		0x2cc
123 #define VFE_0_BUS_BDG_QOS_CFG_3		0x2d0
124 #define VFE_0_BUS_BDG_QOS_CFG_4		0x2d4
125 #define VFE_0_BUS_BDG_QOS_CFG_5		0x2d8
126 #define VFE_0_BUS_BDG_QOS_CFG_6		0x2dc
127 #define VFE_0_BUS_BDG_QOS_CFG_7		0x2e0
128 #define VFE_0_BUS_BDG_QOS_CFG_7_CFG	0x0001aaa5
129 
130 #define VFE_0_RDI_CFG_x(x)		(0x2e8 + (0x4 * (x)))
131 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT	28
132 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK	(0xf << 28)
133 #define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT	4
134 #define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK		(0xf << 4)
135 #define VFE_0_RDI_CFG_x_RDI_EN_BIT		BIT(2)
136 #define VFE_0_RDI_CFG_x_MIPI_EN_BITS		0x3
137 #define VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(r)	BIT(16 + (r))
138 
139 #define VFE_0_CAMIF_CMD				0x2f4
140 #define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY	0
141 #define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY	1
142 #define VFE_0_CAMIF_CMD_NO_CHANGE		3
143 #define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS	BIT(2)
144 #define VFE_0_CAMIF_CFG				0x2f8
145 #define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN		BIT(6)
146 #define VFE_0_CAMIF_FRAME_CFG			0x300
147 #define VFE_0_CAMIF_WINDOW_WIDTH_CFG		0x304
148 #define VFE_0_CAMIF_WINDOW_HEIGHT_CFG		0x308
149 #define VFE_0_CAMIF_SUBSAMPLE_CFG_0		0x30c
150 #define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN	0x314
151 #define VFE_0_CAMIF_STATUS			0x31c
152 #define VFE_0_CAMIF_STATUS_HALT			BIT(31)
153 
154 #define VFE_0_REG_UPDATE			0x378
155 #define VFE_0_REG_UPDATE_RDIn(n)		BIT(1 + (n))
156 #define VFE_0_REG_UPDATE_line_n(n)		\
157 			((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n))
158 
159 #define VFE_0_DEMUX_CFG				0x424
160 #define VFE_0_DEMUX_CFG_PERIOD			0x3
161 #define VFE_0_DEMUX_GAIN_0			0x428
162 #define VFE_0_DEMUX_GAIN_0_CH0_EVEN		(0x80 << 0)
163 #define VFE_0_DEMUX_GAIN_0_CH0_ODD		(0x80 << 16)
164 #define VFE_0_DEMUX_GAIN_1			0x42c
165 #define VFE_0_DEMUX_GAIN_1_CH1			(0x80 << 0)
166 #define VFE_0_DEMUX_GAIN_1_CH2			(0x80 << 16)
167 #define VFE_0_DEMUX_EVEN_CFG			0x438
168 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV	0x9cac
169 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU	0xac9c
170 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY	0xc9ca
171 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY	0xcac9
172 #define VFE_0_DEMUX_ODD_CFG			0x43c
173 #define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV	0x9cac
174 #define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU	0xac9c
175 #define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY	0xc9ca
176 #define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY	0xcac9
177 
178 #define VFE_0_SCALE_ENC_Y_CFG			0x75c
179 #define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE		0x760
180 #define VFE_0_SCALE_ENC_Y_H_PHASE		0x764
181 #define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE		0x76c
182 #define VFE_0_SCALE_ENC_Y_V_PHASE		0x770
183 #define VFE_0_SCALE_ENC_CBCR_CFG		0x778
184 #define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE	0x77c
185 #define VFE_0_SCALE_ENC_CBCR_H_PHASE		0x780
186 #define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE	0x790
187 #define VFE_0_SCALE_ENC_CBCR_V_PHASE		0x794
188 
189 #define VFE_0_CROP_ENC_Y_WIDTH			0x854
190 #define VFE_0_CROP_ENC_Y_HEIGHT			0x858
191 #define VFE_0_CROP_ENC_CBCR_WIDTH		0x85c
192 #define VFE_0_CROP_ENC_CBCR_HEIGHT		0x860
193 
194 #define VFE_0_CLAMP_ENC_MAX_CFG			0x874
195 #define VFE_0_CLAMP_ENC_MAX_CFG_CH0		(0xff << 0)
196 #define VFE_0_CLAMP_ENC_MAX_CFG_CH1		(0xff << 8)
197 #define VFE_0_CLAMP_ENC_MAX_CFG_CH2		(0xff << 16)
198 #define VFE_0_CLAMP_ENC_MIN_CFG			0x878
199 #define VFE_0_CLAMP_ENC_MIN_CFG_CH0		(0x0 << 0)
200 #define VFE_0_CLAMP_ENC_MIN_CFG_CH1		(0x0 << 8)
201 #define VFE_0_CLAMP_ENC_MIN_CFG_CH2		(0x0 << 16)
202 
203 #define VFE_0_CGC_OVERRIDE_1			0x974
204 #define VFE_0_CGC_OVERRIDE_1_IMAGE_Mx_CGC_OVERRIDE(x)	BIT(x)
205 
206 #define CAMIF_TIMEOUT_SLEEP_US 1000
207 #define CAMIF_TIMEOUT_ALL_US 1000000
208 
209 #define MSM_VFE_VFE0_UB_SIZE 1023
210 #define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3)
211 
212 static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev)
213 {
214 	u32 hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION);
215 
216 	dev_dbg(dev, "VFE HW Version = 0x%08x\n", hw_version);
217 }
218 
219 static u16 vfe_get_ub_size(u8 vfe_id)
220 {
221 	if (vfe_id == 0)
222 		return MSM_VFE_VFE0_UB_SIZE_RDI;
223 
224 	return 0;
225 }
226 
227 static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)
228 {
229 	u32 bits = readl_relaxed(vfe->base + reg);
230 
231 	writel_relaxed(bits & ~clr_bits, vfe->base + reg);
232 }
233 
234 static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
235 {
236 	u32 bits = readl_relaxed(vfe->base + reg);
237 
238 	writel_relaxed(bits | set_bits, vfe->base + reg);
239 }
240 
241 static void vfe_global_reset(struct vfe_device *vfe)
242 {
243 	u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_TESTGEN		|
244 			 VFE_0_GLOBAL_RESET_CMD_BUS_MISR	|
245 			 VFE_0_GLOBAL_RESET_CMD_PM		|
246 			 VFE_0_GLOBAL_RESET_CMD_TIMER		|
247 			 VFE_0_GLOBAL_RESET_CMD_REGISTER	|
248 			 VFE_0_GLOBAL_RESET_CMD_BUS_BDG		|
249 			 VFE_0_GLOBAL_RESET_CMD_BUS		|
250 			 VFE_0_GLOBAL_RESET_CMD_CAMIF		|
251 			 VFE_0_GLOBAL_RESET_CMD_CORE;
252 
253 	writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD);
254 }
255 
256 static void vfe_halt_request(struct vfe_device *vfe)
257 {
258 	writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ,
259 		       vfe->base + VFE_0_BUS_BDG_CMD);
260 }
261 
262 static void vfe_halt_clear(struct vfe_device *vfe)
263 {
264 	writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD);
265 }
266 
267 static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)
268 {
269 	if (enable)
270 		vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
271 			    1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT);
272 	else
273 		vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
274 			    1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT);
275 }
276 
277 static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable)
278 {
279 	if (enable)
280 		vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
281 			1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT);
282 	else
283 		vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
284 			1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT);
285 }
286 
287 #define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N))
288 
289 static int vfe_word_per_line(u32 format, u32 pixel_per_line)
290 {
291 	int val = 0;
292 
293 	switch (format) {
294 	case V4L2_PIX_FMT_NV12:
295 	case V4L2_PIX_FMT_NV21:
296 	case V4L2_PIX_FMT_NV16:
297 	case V4L2_PIX_FMT_NV61:
298 		val = CALC_WORD(pixel_per_line, 1, 8);
299 		break;
300 	case V4L2_PIX_FMT_YUYV:
301 	case V4L2_PIX_FMT_YVYU:
302 	case V4L2_PIX_FMT_UYVY:
303 	case V4L2_PIX_FMT_VYUY:
304 		val = CALC_WORD(pixel_per_line, 2, 8);
305 		break;
306 	}
307 
308 	return val;
309 }
310 
311 static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane,
312 			     u16 *width, u16 *height, u16 *bytesperline)
313 {
314 	switch (pix->pixelformat) {
315 	case V4L2_PIX_FMT_NV12:
316 	case V4L2_PIX_FMT_NV21:
317 		*width = pix->width;
318 		*height = pix->height;
319 		*bytesperline = pix->plane_fmt[0].bytesperline;
320 		if (plane == 1)
321 			*height /= 2;
322 		break;
323 	case V4L2_PIX_FMT_NV16:
324 	case V4L2_PIX_FMT_NV61:
325 		*width = pix->width;
326 		*height = pix->height;
327 		*bytesperline = pix->plane_fmt[0].bytesperline;
328 		break;
329 	}
330 }
331 
332 static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm,
333 			      struct v4l2_pix_format_mplane *pix,
334 			      u8 plane, u32 enable)
335 {
336 	u32 reg;
337 
338 	if (enable) {
339 		u16 width = 0, height = 0, bytesperline = 0, wpl;
340 
341 		vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline);
342 
343 		wpl = vfe_word_per_line(pix->pixelformat, width);
344 
345 		reg = height - 1;
346 		reg |= ((wpl + 1) / 2 - 1) << 16;
347 
348 		writel_relaxed(reg, vfe->base +
349 			       VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
350 
351 		wpl = vfe_word_per_line(pix->pixelformat, bytesperline);
352 
353 		reg = 0x3;
354 		reg |= (height - 1) << 4;
355 		reg |= wpl << 16;
356 
357 		writel_relaxed(reg, vfe->base +
358 			       VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
359 	} else {
360 		writel_relaxed(0, vfe->base +
361 			       VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
362 		writel_relaxed(0, vfe->base +
363 			       VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
364 	}
365 }
366 
367 static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per)
368 {
369 	u32 reg;
370 
371 	reg = readl_relaxed(vfe->base +
372 			    VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
373 
374 	reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK);
375 
376 	reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT)
377 		& VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK;
378 
379 	writel_relaxed(reg,
380 		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
381 }
382 
383 static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm,
384 					 u32 pattern)
385 {
386 	writel_relaxed(pattern,
387 	       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm));
388 }
389 
390 static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm,
391 			      u16 offset, u16 depth)
392 {
393 	u32 reg;
394 
395 	reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) |
396 		depth;
397 	writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm));
398 }
399 
400 static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm)
401 {
402 	wmb();
403 	writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD);
404 	wmb();
405 }
406 
407 static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr)
408 {
409 	writel_relaxed(addr,
410 		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm));
411 }
412 
413 static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr)
414 {
415 	writel_relaxed(addr,
416 		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm));
417 }
418 
419 static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm)
420 {
421 	u32 reg;
422 
423 	reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS);
424 
425 	return (reg >> wm) & 0x1;
426 }
427 
428 static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable)
429 {
430 	if (enable)
431 		writel_relaxed(0x10000009, vfe->base + VFE_0_BUS_CFG);
432 	else
433 		writel_relaxed(0, vfe->base + VFE_0_BUS_CFG);
434 }
435 
436 static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm,
437 				      enum vfe_line_id id)
438 {
439 	u32 reg;
440 
441 	reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
442 	reg |= VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(id);
443 	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg);
444 
445 	reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
446 	reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) &
447 		VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK;
448 	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg);
449 
450 	switch (id) {
451 	case VFE_LINE_RDI0:
452 	default:
453 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
454 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
455 		break;
456 	case VFE_LINE_RDI1:
457 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
458 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
459 		break;
460 	case VFE_LINE_RDI2:
461 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
462 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
463 		break;
464 	}
465 
466 	if (wm % 2 == 1)
467 		reg <<= 16;
468 
469 	vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
470 }
471 
472 static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm)
473 {
474 	writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF,
475 		       vfe->base +
476 		       VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm));
477 }
478 
479 static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm,
480 					   enum vfe_line_id id)
481 {
482 	u32 reg;
483 
484 	reg = VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(id);
485 	vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(0), reg);
486 
487 	reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
488 	vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg);
489 
490 	switch (id) {
491 	case VFE_LINE_RDI0:
492 	default:
493 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
494 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
495 		break;
496 	case VFE_LINE_RDI1:
497 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
498 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
499 		break;
500 	case VFE_LINE_RDI2:
501 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
502 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
503 		break;
504 	}
505 
506 	if (wm % 2 == 1)
507 		reg <<= 16;
508 
509 	vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
510 }
511 
512 static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output,
513 			     u8 enable)
514 {
515 	struct vfe_line *line = container_of(output, struct vfe_line, output);
516 	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
517 	u32 reg;
518 	unsigned int i;
519 
520 	for (i = 0; i < output->wm_num; i++) {
521 		if (i == 0) {
522 			reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA <<
523 				VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
524 		} else if (i == 1) {
525 			reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
526 			if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16)
527 				reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
528 		} else {
529 			/* On current devices output->wm_num is always <= 2 */
530 			break;
531 		}
532 
533 		if (output->wm_idx[i] % 2 == 1)
534 			reg <<= 16;
535 
536 		if (enable)
537 			vfe_reg_set(vfe,
538 				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[i]),
539 				    reg);
540 		else
541 			vfe_reg_clr(vfe,
542 				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[i]),
543 				    reg);
544 	}
545 }
546 
547 static void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line,
548 				u8 enable)
549 {
550 	/* empty */
551 }
552 static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid)
553 {
554 	vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id),
555 		    VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK);
556 
557 	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id),
558 		    cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT);
559 }
560 
561 static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
562 {
563 	vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id);
564 	wmb();
565 	writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE);
566 	wmb();
567 }
568 
569 static inline void vfe_reg_update_clear(struct vfe_device *vfe,
570 					enum vfe_line_id line_id)
571 {
572 	vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id);
573 }
574 
575 static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm,
576 				   enum vfe_line_id line_id, u8 enable)
577 {
578 	u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) |
579 		      VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
580 	u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) |
581 		      VFE_0_IRQ_MASK_1_RDIn_SOF(line_id);
582 
583 	if (enable) {
584 		vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
585 		vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
586 	} else {
587 		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
588 		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
589 	}
590 }
591 
592 static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp,
593 				    enum vfe_line_id line_id, u8 enable)
594 {
595 	struct vfe_output *output = &vfe->line[line_id].output;
596 	unsigned int i;
597 	u32 irq_en0;
598 	u32 irq_en1;
599 	u32 comp_mask = 0;
600 
601 	irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF;
602 	irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF;
603 	irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp);
604 	irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
605 	irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR;
606 	for (i = 0; i < output->wm_num; i++) {
607 		irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(
608 							output->wm_idx[i]);
609 		comp_mask |= (1 << output->wm_idx[i]) << comp * 8;
610 	}
611 
612 	if (enable) {
613 		vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
614 		vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
615 		vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
616 	} else {
617 		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
618 		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
619 		vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
620 	}
621 }
622 
623 static void vfe_enable_irq_common(struct vfe_device *vfe)
624 {
625 	u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK;
626 	u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION |
627 		      VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK;
628 
629 	vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
630 	vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
631 }
632 
633 static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)
634 {
635 	u32 val, even_cfg, odd_cfg;
636 
637 	writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG);
638 
639 	val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD;
640 	writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0);
641 
642 	val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2;
643 	writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);
644 
645 	switch (line->fmt[MSM_VFE_PAD_SINK].code) {
646 	case MEDIA_BUS_FMT_YUYV8_2X8:
647 		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;
648 		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;
649 		break;
650 	case MEDIA_BUS_FMT_YVYU8_2X8:
651 		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;
652 		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;
653 		break;
654 	case MEDIA_BUS_FMT_UYVY8_2X8:
655 	default:
656 		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;
657 		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;
658 		break;
659 	case MEDIA_BUS_FMT_VYUY8_2X8:
660 		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;
661 		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;
662 		break;
663 	}
664 
665 	writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG);
666 	writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG);
667 }
668 
669 static inline u8 vfe_calc_interp_reso(u16 input, u16 output)
670 {
671 	if (input / output >= 16)
672 		return 0;
673 
674 	if (input / output >= 8)
675 		return 1;
676 
677 	if (input / output >= 4)
678 		return 2;
679 
680 	return 3;
681 }
682 
683 static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line)
684 {
685 	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
686 	u32 reg;
687 	u16 input, output;
688 	u8 interp_reso;
689 	u32 phase_mult;
690 
691 	writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG);
692 
693 	input = line->fmt[MSM_VFE_PAD_SINK].width;
694 	output = line->compose.width;
695 	reg = (output << 16) | input;
696 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE);
697 
698 	interp_reso = vfe_calc_interp_reso(input, output);
699 	phase_mult = input * (1 << (13 + interp_reso)) / output;
700 	reg = (interp_reso << 20) | phase_mult;
701 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE);
702 
703 	input = line->fmt[MSM_VFE_PAD_SINK].height;
704 	output = line->compose.height;
705 	reg = (output << 16) | input;
706 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE);
707 
708 	interp_reso = vfe_calc_interp_reso(input, output);
709 	phase_mult = input * (1 << (13 + interp_reso)) / output;
710 	reg = (interp_reso << 20) | phase_mult;
711 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE);
712 
713 	writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG);
714 
715 	input = line->fmt[MSM_VFE_PAD_SINK].width;
716 	output = line->compose.width / 2;
717 	reg = (output << 16) | input;
718 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE);
719 
720 	interp_reso = vfe_calc_interp_reso(input, output);
721 	phase_mult = input * (1 << (13 + interp_reso)) / output;
722 	reg = (interp_reso << 20) | phase_mult;
723 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE);
724 
725 	input = line->fmt[MSM_VFE_PAD_SINK].height;
726 	output = line->compose.height;
727 	if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21)
728 		output = line->compose.height / 2;
729 	reg = (output << 16) | input;
730 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE);
731 
732 	interp_reso = vfe_calc_interp_reso(input, output);
733 	phase_mult = input * (1 << (13 + interp_reso)) / output;
734 	reg = (interp_reso << 20) | phase_mult;
735 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE);
736 }
737 
738 static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line)
739 {
740 	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
741 	u32 reg;
742 	u16 first, last;
743 
744 	first = line->crop.left;
745 	last = line->crop.left + line->crop.width - 1;
746 	reg = (first << 16) | last;
747 	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH);
748 
749 	first = line->crop.top;
750 	last = line->crop.top + line->crop.height - 1;
751 	reg = (first << 16) | last;
752 	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT);
753 
754 	first = line->crop.left / 2;
755 	last = line->crop.left / 2 + line->crop.width / 2 - 1;
756 	reg = (first << 16) | last;
757 	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH);
758 
759 	first = line->crop.top;
760 	last = line->crop.top + line->crop.height - 1;
761 	if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) {
762 		first = line->crop.top / 2;
763 		last = line->crop.top / 2 + line->crop.height / 2 - 1;
764 	}
765 	reg = (first << 16) | last;
766 	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT);
767 }
768 
769 static void vfe_set_clamp_cfg(struct vfe_device *vfe)
770 {
771 	u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 |
772 		VFE_0_CLAMP_ENC_MAX_CFG_CH1 |
773 		VFE_0_CLAMP_ENC_MAX_CFG_CH2;
774 
775 	writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG);
776 
777 	val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 |
778 		VFE_0_CLAMP_ENC_MIN_CFG_CH1 |
779 		VFE_0_CLAMP_ENC_MIN_CFG_CH2;
780 
781 	writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG);
782 }
783 
784 static void vfe_set_qos(struct vfe_device *vfe)
785 {
786 	u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG;
787 	u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG;
788 
789 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0);
790 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1);
791 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2);
792 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3);
793 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4);
794 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5);
795 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6);
796 	writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);
797 }
798 
799 static void vfe_set_ds(struct vfe_device *vfe)
800 {
801 	/* empty */
802 }
803 
804 static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable)
805 {
806 	u32 val = VFE_0_CGC_OVERRIDE_1_IMAGE_Mx_CGC_OVERRIDE(wm);
807 
808 	if (enable)
809 		vfe_reg_set(vfe, VFE_0_CGC_OVERRIDE_1, val);
810 	else
811 		vfe_reg_clr(vfe, VFE_0_CGC_OVERRIDE_1, val);
812 
813 	wmb();
814 }
815 
816 static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)
817 {
818 	u32 val;
819 
820 	switch (line->fmt[MSM_VFE_PAD_SINK].code) {
821 	case MEDIA_BUS_FMT_YUYV8_2X8:
822 		val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;
823 		break;
824 	case MEDIA_BUS_FMT_YVYU8_2X8:
825 		val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;
826 		break;
827 	case MEDIA_BUS_FMT_UYVY8_2X8:
828 	default:
829 		val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;
830 		break;
831 	case MEDIA_BUS_FMT_VYUY8_2X8:
832 		val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;
833 		break;
834 	}
835 
836 	writel_relaxed(val, vfe->base + VFE_0_CORE_CFG);
837 
838 	val = line->fmt[MSM_VFE_PAD_SINK].width * 2;
839 	val |= line->fmt[MSM_VFE_PAD_SINK].height << 16;
840 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG);
841 
842 	val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
843 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG);
844 
845 	val = line->fmt[MSM_VFE_PAD_SINK].height - 1;
846 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG);
847 
848 	val = 0xffffffff;
849 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG_0);
850 
851 	val = 0xffffffff;
852 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN);
853 
854 	val = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
855 	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val);
856 
857 	val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN;
858 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG);
859 }
860 
861 static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable)
862 {
863 	u32 cmd;
864 
865 	cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE;
866 	writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
867 	wmb();
868 
869 	if (enable)
870 		cmd = VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY;
871 	else
872 		cmd = VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY;
873 
874 	writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
875 }
876 
877 static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable)
878 {
879 	u32 val = VFE_0_MODULE_CFG_DEMUX |
880 		  VFE_0_MODULE_CFG_CHROMA_UPSAMPLE |
881 		  VFE_0_MODULE_CFG_SCALE_ENC |
882 		  VFE_0_MODULE_CFG_CROP_ENC;
883 
884 	if (enable)
885 		writel_relaxed(val, vfe->base + VFE_0_MODULE_CFG);
886 	else
887 		writel_relaxed(0x0, vfe->base + VFE_0_MODULE_CFG);
888 }
889 
890 static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)
891 {
892 	u32 val;
893 	int ret;
894 
895 	ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS,
896 				 val,
897 				 (val & VFE_0_CAMIF_STATUS_HALT),
898 				 CAMIF_TIMEOUT_SLEEP_US,
899 				 CAMIF_TIMEOUT_ALL_US);
900 	if (ret < 0)
901 		dev_err(dev, "%s: camif stop timeout\n", __func__);
902 
903 	return ret;
904 }
905 
906 static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
907 {
908 	*value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
909 	*value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
910 
911 	writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
912 	writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
913 
914 	wmb();
915 	writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
916 }
917 
918 static void vfe_violation_read(struct vfe_device *vfe)
919 {
920 	u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
921 
922 	pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
923 }
924 
925 /*
926  * vfe_isr - VFE module interrupt handler
927  * @irq: Interrupt line
928  * @dev: VFE device
929  *
930  * Return IRQ_HANDLED on success
931  */
932 static irqreturn_t vfe_isr(int irq, void *dev)
933 {
934 	struct vfe_device *vfe = dev;
935 	u32 value0, value1;
936 	int i, j;
937 
938 	vfe->ops->isr_read(vfe, &value0, &value1);
939 
940 	dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
941 		value0, value1);
942 
943 	if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
944 		vfe->isr_ops.reset_ack(vfe);
945 
946 	if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
947 		vfe->ops->violation_read(vfe);
948 
949 	if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
950 		vfe->isr_ops.halt_ack(vfe);
951 
952 	for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++)
953 		if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
954 			vfe->isr_ops.reg_update(vfe, i);
955 
956 	if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
957 		vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
958 
959 	for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
960 		if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
961 			vfe->isr_ops.sof(vfe, i);
962 
963 	for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
964 		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
965 			vfe->isr_ops.comp_done(vfe, i);
966 			for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
967 				if (vfe->wm_output_map[j] == VFE_LINE_PIX)
968 					value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
969 		}
970 
971 	for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
972 		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
973 			vfe->isr_ops.wm_done(vfe, i);
974 
975 	return IRQ_HANDLED;
976 }
977 
978 const struct vfe_hw_ops vfe_ops_4_1 = {
979 	.hw_version_read = vfe_hw_version_read,
980 	.get_ub_size = vfe_get_ub_size,
981 	.global_reset = vfe_global_reset,
982 	.halt_request = vfe_halt_request,
983 	.halt_clear = vfe_halt_clear,
984 	.wm_enable = vfe_wm_enable,
985 	.wm_frame_based = vfe_wm_frame_based,
986 	.wm_line_based = vfe_wm_line_based,
987 	.wm_set_framedrop_period = vfe_wm_set_framedrop_period,
988 	.wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern,
989 	.wm_set_ub_cfg = vfe_wm_set_ub_cfg,
990 	.bus_reload_wm = vfe_bus_reload_wm,
991 	.wm_set_ping_addr = vfe_wm_set_ping_addr,
992 	.wm_set_pong_addr = vfe_wm_set_pong_addr,
993 	.wm_get_ping_pong_status = vfe_wm_get_ping_pong_status,
994 	.bus_enable_wr_if = vfe_bus_enable_wr_if,
995 	.bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
996 	.wm_set_subsample = vfe_wm_set_subsample,
997 	.bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
998 	.set_xbar_cfg = vfe_set_xbar_cfg,
999 	.set_realign_cfg = vfe_set_realign_cfg,
1000 	.set_rdi_cid = vfe_set_rdi_cid,
1001 	.reg_update = vfe_reg_update,
1002 	.reg_update_clear = vfe_reg_update_clear,
1003 	.enable_irq_wm_line = vfe_enable_irq_wm_line,
1004 	.enable_irq_pix_line = vfe_enable_irq_pix_line,
1005 	.enable_irq_common = vfe_enable_irq_common,
1006 	.set_demux_cfg = vfe_set_demux_cfg,
1007 	.set_scale_cfg = vfe_set_scale_cfg,
1008 	.set_crop_cfg = vfe_set_crop_cfg,
1009 	.set_clamp_cfg = vfe_set_clamp_cfg,
1010 	.set_qos = vfe_set_qos,
1011 	.set_ds = vfe_set_ds,
1012 	.set_cgc_override = vfe_set_cgc_override,
1013 	.set_camif_cfg = vfe_set_camif_cfg,
1014 	.set_camif_cmd = vfe_set_camif_cmd,
1015 	.set_module_cfg = vfe_set_module_cfg,
1016 	.camif_wait_for_stop = vfe_camif_wait_for_stop,
1017 	.isr_read = vfe_isr_read,
1018 	.violation_read = vfe_violation_read,
1019 	.isr = vfe_isr,
1020 };
1021