1// SPDX-License-Identifier: GPL-2.0
2/*
3 * camss-vfe-4-8.c
4 *
5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.8
6 *
7 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
8 * Copyright (C) 2015-2021 Linaro Ltd.
9 */
10
11#include <linux/device.h>
12#include <linux/interrupt.h>
13#include <linux/io.h>
14#include <linux/iopoll.h>
15
16#include "camss.h"
17#include "camss-vfe.h"
18#include "camss-vfe-gen1.h"
19
20#define VFE_0_HW_VERSION		0x000
21
22#define VFE_0_GLOBAL_RESET_CMD		0x018
23#define VFE_0_GLOBAL_RESET_CMD_CORE	BIT(0)
24#define VFE_0_GLOBAL_RESET_CMD_CAMIF	BIT(1)
25#define VFE_0_GLOBAL_RESET_CMD_BUS	BIT(2)
26#define VFE_0_GLOBAL_RESET_CMD_BUS_BDG	BIT(3)
27#define VFE_0_GLOBAL_RESET_CMD_REGISTER	BIT(4)
28#define VFE_0_GLOBAL_RESET_CMD_PM	BIT(5)
29#define VFE_0_GLOBAL_RESET_CMD_BUS_MISR	BIT(6)
30#define VFE_0_GLOBAL_RESET_CMD_TESTGEN	BIT(7)
31#define VFE_0_GLOBAL_RESET_CMD_DSP	BIT(8)
32#define VFE_0_GLOBAL_RESET_CMD_IDLE_CGC	BIT(9)
33
34#define VFE_0_MODULE_LENS_EN		0x040
35#define VFE_0_MODULE_LENS_EN_DEMUX		BIT(2)
36#define VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE	BIT(3)
37
38#define VFE_0_MODULE_ZOOM_EN		0x04c
39#define VFE_0_MODULE_ZOOM_EN_SCALE_ENC		BIT(1)
40#define VFE_0_MODULE_ZOOM_EN_CROP_ENC		BIT(2)
41#define VFE_0_MODULE_ZOOM_EN_REALIGN_BUF	BIT(9)
42
43#define VFE_0_CORE_CFG			0x050
44#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR	0x4
45#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB	0x5
46#define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY	0x6
47#define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY	0x7
48#define VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN	BIT(4)
49
50#define VFE_0_IRQ_CMD			0x058
51#define VFE_0_IRQ_CMD_GLOBAL_CLEAR	BIT(0)
52
53#define VFE_0_IRQ_MASK_0		0x05c
54#define VFE_0_IRQ_MASK_0_CAMIF_SOF			BIT(0)
55#define VFE_0_IRQ_MASK_0_CAMIF_EOF			BIT(1)
56#define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)		BIT((n) + 5)
57#define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n)		\
58	((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n))
59#define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n)	BIT((n) + 8)
60#define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n)	BIT((n) + 25)
61#define VFE_0_IRQ_MASK_0_RESET_ACK			BIT(31)
62#define VFE_0_IRQ_MASK_1		0x060
63#define VFE_0_IRQ_MASK_1_CAMIF_ERROR			BIT(0)
64#define VFE_0_IRQ_MASK_1_VIOLATION			BIT(7)
65#define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK		BIT(8)
66#define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n)	BIT((n) + 9)
67#define VFE_0_IRQ_MASK_1_RDIn_SOF(n)			BIT((n) + 29)
68
69#define VFE_0_IRQ_CLEAR_0		0x064
70#define VFE_0_IRQ_CLEAR_1		0x068
71
72#define VFE_0_IRQ_STATUS_0		0x06c
73#define VFE_0_IRQ_STATUS_0_CAMIF_SOF			BIT(0)
74#define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)		BIT((n) + 5)
75#define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n)		\
76	((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n))
77#define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n)	BIT((n) + 8)
78#define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n)	BIT((n) + 25)
79#define VFE_0_IRQ_STATUS_0_RESET_ACK			BIT(31)
80#define VFE_0_IRQ_STATUS_1		0x070
81#define VFE_0_IRQ_STATUS_1_VIOLATION			BIT(7)
82#define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK		BIT(8)
83#define VFE_0_IRQ_STATUS_1_RDIn_SOF(n)			BIT((n) + 29)
84
85#define VFE_0_IRQ_COMPOSITE_MASK_0	0x074
86#define VFE_0_VIOLATION_STATUS		0x07c
87
88#define VFE_0_BUS_CMD			0x80
89#define VFE_0_BUS_CMD_Mx_RLD_CMD(x)	BIT(x)
90
91#define VFE_0_BUS_CFG			0x084
92
93#define VFE_0_BUS_XBAR_CFG_x(x)		(0x90 + 0x4 * ((x) / 2))
94#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN			BIT(2)
95#define VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN			BIT(3)
96#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTRA		(0x1 << 4)
97#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER		(0x2 << 4)
98#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA	(0x3 << 4)
99#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT		8
100#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA		0x0
101#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0	0xc
102#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1	0xd
103#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2	0xe
104
105#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n)		(0x0a0 + 0x2c * (n))
106#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT	0
107#define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n)	(0x0a4 + 0x2c * (n))
108#define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n)	(0x0ac + 0x2c * (n))
109#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n)		(0x0b4 + 0x2c * (n))
110#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT	1
111#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT	2
112#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK	(0x1f << 2)
113#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n)		(0x0b8 + 0x2c * (n))
114#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT	16
115#define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n)	(0x0bc + 0x2c * (n))
116#define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n)	(0x0c0 + 0x2c * (n))
117#define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n)	\
118							(0x0c4 + 0x2c * (n))
119#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n)	\
120							(0x0c8 + 0x2c * (n))
121#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF	0xffffffff
122
123#define VFE_0_BUS_PING_PONG_STATUS	0x338
124
125#define VFE_0_BUS_BDG_CMD		0x400
126#define VFE_0_BUS_BDG_CMD_HALT_REQ	1
127
128#define VFE_0_BUS_BDG_QOS_CFG_0		0x404
129#define VFE_0_BUS_BDG_QOS_CFG_0_CFG	0xaaa5aaa5
130#define VFE_0_BUS_BDG_QOS_CFG_1		0x408
131#define VFE_0_BUS_BDG_QOS_CFG_2		0x40c
132#define VFE_0_BUS_BDG_QOS_CFG_3		0x410
133#define VFE_0_BUS_BDG_QOS_CFG_3_CFG	0xaa55aaa5
134#define VFE_0_BUS_BDG_QOS_CFG_4		0x414
135#define VFE_0_BUS_BDG_QOS_CFG_4_CFG	0xaa55aa55
136#define VFE_0_BUS_BDG_QOS_CFG_5		0x418
137#define VFE_0_BUS_BDG_QOS_CFG_6		0x41c
138#define VFE_0_BUS_BDG_QOS_CFG_7		0x420
139#define VFE_0_BUS_BDG_QOS_CFG_7_CFG	0x0005aa55
140
141#define VFE_0_BUS_BDG_DS_CFG_0		0x424
142#define VFE_0_BUS_BDG_DS_CFG_0_CFG	0xcccc1111
143#define VFE_0_BUS_BDG_DS_CFG_1		0x428
144#define VFE_0_BUS_BDG_DS_CFG_2		0x42c
145#define VFE_0_BUS_BDG_DS_CFG_3		0x430
146#define VFE_0_BUS_BDG_DS_CFG_4		0x434
147#define VFE_0_BUS_BDG_DS_CFG_5		0x438
148#define VFE_0_BUS_BDG_DS_CFG_6		0x43c
149#define VFE_0_BUS_BDG_DS_CFG_7		0x440
150#define VFE_0_BUS_BDG_DS_CFG_8		0x444
151#define VFE_0_BUS_BDG_DS_CFG_9		0x448
152#define VFE_0_BUS_BDG_DS_CFG_10		0x44c
153#define VFE_0_BUS_BDG_DS_CFG_11		0x450
154#define VFE_0_BUS_BDG_DS_CFG_12		0x454
155#define VFE_0_BUS_BDG_DS_CFG_13		0x458
156#define VFE_0_BUS_BDG_DS_CFG_14		0x45c
157#define VFE_0_BUS_BDG_DS_CFG_15		0x460
158#define VFE_0_BUS_BDG_DS_CFG_16		0x464
159#define VFE_0_BUS_BDG_DS_CFG_16_CFG	0x00000110
160
161#define VFE_0_RDI_CFG_x(x)		(0x46c + (0x4 * (x)))
162#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT	28
163#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK	(0xf << 28)
164#define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT	4
165#define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK		(0xf << 4)
166#define VFE_0_RDI_CFG_x_RDI_EN_BIT		BIT(2)
167#define VFE_0_RDI_CFG_x_MIPI_EN_BITS		0x3
168
169#define VFE_0_CAMIF_CMD				0x478
170#define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY	0
171#define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY	1
172#define VFE_0_CAMIF_CMD_NO_CHANGE		3
173#define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS	BIT(2)
174#define VFE_0_CAMIF_CFG				0x47c
175#define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN		BIT(6)
176#define VFE_0_CAMIF_FRAME_CFG			0x484
177#define VFE_0_CAMIF_WINDOW_WIDTH_CFG		0x488
178#define VFE_0_CAMIF_WINDOW_HEIGHT_CFG		0x48c
179#define VFE_0_CAMIF_SUBSAMPLE_CFG		0x490
180#define VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN	0x498
181#define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN	0x49c
182#define VFE_0_CAMIF_STATUS			0x4a4
183#define VFE_0_CAMIF_STATUS_HALT			BIT(31)
184
185#define VFE_0_REG_UPDATE		0x4ac
186#define VFE_0_REG_UPDATE_RDIn(n)		BIT(1 + (n))
187#define VFE_0_REG_UPDATE_line_n(n)		\
188			((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n))
189
190#define VFE_0_DEMUX_CFG				0x560
191#define VFE_0_DEMUX_CFG_PERIOD			0x3
192#define VFE_0_DEMUX_GAIN_0			0x564
193#define VFE_0_DEMUX_GAIN_0_CH0_EVEN		(0x80 << 0)
194#define VFE_0_DEMUX_GAIN_0_CH0_ODD		(0x80 << 16)
195#define VFE_0_DEMUX_GAIN_1			0x568
196#define VFE_0_DEMUX_GAIN_1_CH1			(0x80 << 0)
197#define VFE_0_DEMUX_GAIN_1_CH2			(0x80 << 16)
198#define VFE_0_DEMUX_EVEN_CFG			0x574
199#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV	0x9cac
200#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU	0xac9c
201#define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY	0xc9ca
202#define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY	0xcac9
203#define VFE_0_DEMUX_ODD_CFG			0x578
204#define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV	0x9cac
205#define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU	0xac9c
206#define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY	0xc9ca
207#define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY	0xcac9
208
209#define VFE_0_SCALE_ENC_Y_CFG			0x91c
210#define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE		0x920
211#define VFE_0_SCALE_ENC_Y_H_PHASE		0x924
212#define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE		0x934
213#define VFE_0_SCALE_ENC_Y_V_PHASE		0x938
214#define VFE_0_SCALE_ENC_CBCR_CFG		0x948
215#define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE	0x94c
216#define VFE_0_SCALE_ENC_CBCR_H_PHASE		0x950
217#define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE	0x960
218#define VFE_0_SCALE_ENC_CBCR_V_PHASE		0x964
219
220#define VFE_0_CROP_ENC_Y_WIDTH			0x974
221#define VFE_0_CROP_ENC_Y_HEIGHT			0x978
222#define VFE_0_CROP_ENC_CBCR_WIDTH		0x97c
223#define VFE_0_CROP_ENC_CBCR_HEIGHT		0x980
224
225#define VFE_0_CLAMP_ENC_MAX_CFG			0x984
226#define VFE_0_CLAMP_ENC_MAX_CFG_CH0		(0xff << 0)
227#define VFE_0_CLAMP_ENC_MAX_CFG_CH1		(0xff << 8)
228#define VFE_0_CLAMP_ENC_MAX_CFG_CH2		(0xff << 16)
229#define VFE_0_CLAMP_ENC_MIN_CFG			0x988
230#define VFE_0_CLAMP_ENC_MIN_CFG_CH0		(0x0 << 0)
231#define VFE_0_CLAMP_ENC_MIN_CFG_CH1		(0x0 << 8)
232#define VFE_0_CLAMP_ENC_MIN_CFG_CH2		(0x0 << 16)
233
234#define VFE_0_REALIGN_BUF_CFG			0xaac
235#define VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL     BIT(2)
236#define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL     BIT(3)
237#define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE      BIT(4)
238
239#define VFE_0_BUS_IMAGE_MASTER_CMD		0xcec
240#define VFE_0_BUS_IMAGE_MASTER_n_SHIFT(x)	(2 * (x))
241
242#define CAMIF_TIMEOUT_SLEEP_US 1000
243#define CAMIF_TIMEOUT_ALL_US 1000000
244
245#define MSM_VFE_VFE0_UB_SIZE 2047
246#define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3)
247#define MSM_VFE_VFE1_UB_SIZE 1535
248#define MSM_VFE_VFE1_UB_SIZE_RDI (MSM_VFE_VFE1_UB_SIZE / 3)
249
250static u32 vfe_hw_version(struct vfe_device *vfe)
251{
252	u32 hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION);
253
254	dev_dbg(vfe->camss->dev, "VFE HW Version = 0x%08x\n", hw_version);
255
256	return hw_version;
257}
258
259static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)
260{
261	u32 bits = readl_relaxed(vfe->base + reg);
262
263	writel_relaxed(bits & ~clr_bits, vfe->base + reg);
264}
265
266static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
267{
268	u32 bits = readl_relaxed(vfe->base + reg);
269
270	writel_relaxed(bits | set_bits, vfe->base + reg);
271}
272
273static void vfe_global_reset(struct vfe_device *vfe)
274{
275	u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_IDLE_CGC	|
276			 VFE_0_GLOBAL_RESET_CMD_DSP		|
277			 VFE_0_GLOBAL_RESET_CMD_TESTGEN		|
278			 VFE_0_GLOBAL_RESET_CMD_BUS_MISR	|
279			 VFE_0_GLOBAL_RESET_CMD_PM		|
280			 VFE_0_GLOBAL_RESET_CMD_REGISTER	|
281			 VFE_0_GLOBAL_RESET_CMD_BUS_BDG		|
282			 VFE_0_GLOBAL_RESET_CMD_BUS		|
283			 VFE_0_GLOBAL_RESET_CMD_CAMIF		|
284			 VFE_0_GLOBAL_RESET_CMD_CORE;
285
286	writel_relaxed(BIT(31), vfe->base + VFE_0_IRQ_MASK_0);
287
288	/* Enforce barrier between IRQ mask setup and global reset */
289	wmb();
290	writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD);
291}
292
293static void vfe_halt_request(struct vfe_device *vfe)
294{
295	writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ,
296		       vfe->base + VFE_0_BUS_BDG_CMD);
297}
298
299static void vfe_halt_clear(struct vfe_device *vfe)
300{
301	writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD);
302}
303
304static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable)
305{
306	if (enable)
307		vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm),
308			    1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT);
309	else
310		vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm),
311			    1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT);
312}
313
314#define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N))
315
316static int vfe_word_per_line_by_pixel(u32 format, u32 pixel_per_line)
317{
318	int val = 0;
319
320	switch (format) {
321	case V4L2_PIX_FMT_NV12:
322	case V4L2_PIX_FMT_NV21:
323	case V4L2_PIX_FMT_NV16:
324	case V4L2_PIX_FMT_NV61:
325		val = CALC_WORD(pixel_per_line, 1, 8);
326		break;
327	case V4L2_PIX_FMT_YUYV:
328	case V4L2_PIX_FMT_YVYU:
329	case V4L2_PIX_FMT_UYVY:
330	case V4L2_PIX_FMT_VYUY:
331		val = CALC_WORD(pixel_per_line, 2, 8);
332		break;
333	}
334
335	return val;
336}
337
338static int vfe_word_per_line_by_bytes(u32 bytes_per_line)
339{
340	return CALC_WORD(bytes_per_line, 1, 8);
341}
342
343static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane,
344			     u16 *width, u16 *height, u16 *bytesperline)
345{
346	*width = pix->width;
347	*height = pix->height;
348
349	switch (pix->pixelformat) {
350	case V4L2_PIX_FMT_NV12:
351	case V4L2_PIX_FMT_NV21:
352		*bytesperline = pix->plane_fmt[0].bytesperline;
353		if (plane == 1)
354			*height /= 2;
355		break;
356	case V4L2_PIX_FMT_NV16:
357	case V4L2_PIX_FMT_NV61:
358		*bytesperline = pix->plane_fmt[0].bytesperline;
359		break;
360	case V4L2_PIX_FMT_YUYV:
361	case V4L2_PIX_FMT_YVYU:
362	case V4L2_PIX_FMT_VYUY:
363	case V4L2_PIX_FMT_UYVY:
364		*bytesperline = pix->plane_fmt[plane].bytesperline;
365		break;
366	}
367}
368
369static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm,
370			      struct v4l2_pix_format_mplane *pix,
371			      u8 plane, u32 enable)
372{
373	u32 reg;
374
375	if (enable) {
376		u16 width = 0, height = 0, bytesperline = 0, wpl;
377
378		vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline);
379
380		wpl = vfe_word_per_line_by_pixel(pix->pixelformat, width);
381
382		reg = height - 1;
383		reg |= ((wpl + 3) / 4 - 1) << 16;
384
385		writel_relaxed(reg, vfe->base +
386			       VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
387
388		wpl = vfe_word_per_line_by_bytes(bytesperline);
389
390		reg = 0x3;
391		reg |= (height - 1) << 2;
392		reg |= ((wpl + 1) / 2) << 16;
393
394		writel_relaxed(reg, vfe->base +
395			       VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
396	} else {
397		writel_relaxed(0, vfe->base +
398			       VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
399		writel_relaxed(0, vfe->base +
400			       VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
401	}
402}
403
404static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per)
405{
406	u32 reg;
407
408	reg = readl_relaxed(vfe->base +
409			    VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
410
411	reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK);
412
413	reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT)
414		& VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK;
415
416	writel_relaxed(reg,
417		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
418}
419
420static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm,
421					 u32 pattern)
422{
423	writel_relaxed(pattern, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm));
424}
425
426static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm,
427			      u16 offset, u16 depth)
428{
429	u32 reg;
430
431	reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) |
432	      depth;
433	writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm));
434}
435
436static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm)
437{
438	/* Enforce barrier between any outstanding register write */
439	wmb();
440
441	writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD);
442
443	/* Use barrier to make sure bus reload is issued before anything else */
444	wmb();
445}
446
447static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr)
448{
449	writel_relaxed(addr,
450		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm));
451}
452
453static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr)
454{
455	writel_relaxed(addr,
456		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm));
457}
458
459static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm)
460{
461	u32 reg;
462
463	reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS);
464
465	return (reg >> wm) & 0x1;
466}
467
468static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable)
469{
470	if (enable)
471		writel_relaxed(0x101, vfe->base + VFE_0_BUS_CFG);
472	else
473		writel_relaxed(0, vfe->base + VFE_0_BUS_CFG);
474}
475
476static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm,
477				      enum vfe_line_id id)
478{
479	u32 reg;
480
481	reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
482	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg);
483
484	reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
485	reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) &
486		VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK;
487	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg);
488
489	switch (id) {
490	case VFE_LINE_RDI0:
491	default:
492		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
493		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
494		break;
495	case VFE_LINE_RDI1:
496		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
497		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
498		break;
499	case VFE_LINE_RDI2:
500		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
501		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
502		break;
503	}
504
505	if (wm % 2 == 1)
506		reg <<= 16;
507
508	vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
509}
510
511static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm)
512{
513	writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF,
514		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm));
515}
516
517static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm,
518					   enum vfe_line_id id)
519{
520	u32 reg;
521
522	reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
523	vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg);
524
525	switch (id) {
526	case VFE_LINE_RDI0:
527	default:
528		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
529		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
530		break;
531	case VFE_LINE_RDI1:
532		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
533		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
534		break;
535	case VFE_LINE_RDI2:
536		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
537		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
538		break;
539	}
540
541	if (wm % 2 == 1)
542		reg <<= 16;
543
544	vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
545}
546
547static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output,
548			     u8 enable)
549{
550	struct vfe_line *line = container_of(output, struct vfe_line, output);
551	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
552	u32 reg;
553
554	switch (p) {
555	case V4L2_PIX_FMT_NV12:
556	case V4L2_PIX_FMT_NV21:
557	case V4L2_PIX_FMT_NV16:
558	case V4L2_PIX_FMT_NV61:
559		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA <<
560			VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
561
562		if (output->wm_idx[0] % 2 == 1)
563			reg <<= 16;
564
565		if (enable)
566			vfe_reg_set(vfe,
567				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
568				    reg);
569		else
570			vfe_reg_clr(vfe,
571				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
572				    reg);
573
574		reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
575		if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16)
576			reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
577
578		if (output->wm_idx[1] % 2 == 1)
579			reg <<= 16;
580
581		if (enable)
582			vfe_reg_set(vfe,
583				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]),
584				    reg);
585		else
586			vfe_reg_clr(vfe,
587				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]),
588				    reg);
589		break;
590	case V4L2_PIX_FMT_YUYV:
591	case V4L2_PIX_FMT_YVYU:
592	case V4L2_PIX_FMT_VYUY:
593	case V4L2_PIX_FMT_UYVY:
594		reg = VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN;
595		reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
596
597		if (p == V4L2_PIX_FMT_YUYV || p == V4L2_PIX_FMT_YVYU)
598			reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
599
600		if (output->wm_idx[0] % 2 == 1)
601			reg <<= 16;
602
603		if (enable)
604			vfe_reg_set(vfe,
605				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
606				    reg);
607		else
608			vfe_reg_clr(vfe,
609				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
610				    reg);
611		break;
612	default:
613		break;
614	}
615}
616
617static void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line,
618				u8 enable)
619{
620	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
621	u32 val = VFE_0_MODULE_ZOOM_EN_REALIGN_BUF;
622
623	if (p != V4L2_PIX_FMT_YUYV && p != V4L2_PIX_FMT_YVYU &&
624	    p != V4L2_PIX_FMT_VYUY && p != V4L2_PIX_FMT_UYVY)
625		return;
626
627	if (enable) {
628		vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val);
629	} else {
630		vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val);
631		return;
632	}
633
634	val = VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE;
635
636	if (p == V4L2_PIX_FMT_UYVY || p == V4L2_PIX_FMT_YUYV)
637		val |= VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL;
638	else
639		val |= VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL;
640
641	writel_relaxed(val, vfe->base + VFE_0_REALIGN_BUF_CFG);
642}
643
644static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid)
645{
646	vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id),
647		    VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK);
648
649	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id),
650		    cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT);
651}
652
653static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
654{
655	vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id);
656
657	/* Enforce barrier between line update and commit */
658	wmb();
659
660	writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE);
661
662	/* Make sure register update is issued before further reg writes */
663	wmb();
664}
665
666static inline void vfe_reg_update_clear(struct vfe_device *vfe,
667					enum vfe_line_id line_id)
668{
669	vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id);
670}
671
672static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm,
673				   enum vfe_line_id line_id, u8 enable)
674{
675	u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) |
676		      VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
677	u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) |
678		      VFE_0_IRQ_MASK_1_RDIn_SOF(line_id);
679
680	if (enable) {
681		vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
682		vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
683	} else {
684		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
685		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
686	}
687}
688
689static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp,
690				    enum vfe_line_id line_id, u8 enable)
691{
692	struct vfe_output *output = &vfe->line[line_id].output;
693	unsigned int i;
694	u32 irq_en0;
695	u32 irq_en1;
696	u32 comp_mask = 0;
697
698	irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF;
699	irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF;
700	irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp);
701	irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
702	irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR;
703	for (i = 0; i < output->wm_num; i++) {
704		irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(output->wm_idx[i]);
705		comp_mask |= (1 << output->wm_idx[i]) << comp * 8;
706	}
707
708	if (enable) {
709		vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
710		vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
711		vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
712	} else {
713		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
714		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
715		vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
716	}
717}
718
719static void vfe_enable_irq_common(struct vfe_device *vfe)
720{
721	u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK;
722	u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION |
723		      VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK;
724
725	vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
726	vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
727}
728
729static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)
730{
731	u32 val, even_cfg, odd_cfg;
732
733	writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG);
734
735	val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD;
736	writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0);
737
738	val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2;
739	writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);
740
741	switch (line->fmt[MSM_VFE_PAD_SINK].code) {
742	case MEDIA_BUS_FMT_YUYV8_2X8:
743		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;
744		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;
745		break;
746	case MEDIA_BUS_FMT_YVYU8_2X8:
747		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;
748		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;
749		break;
750	case MEDIA_BUS_FMT_UYVY8_2X8:
751	default:
752		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;
753		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;
754		break;
755	case MEDIA_BUS_FMT_VYUY8_2X8:
756		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;
757		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;
758		break;
759	}
760
761	writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG);
762	writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG);
763}
764
765static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line)
766{
767	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
768	u32 reg;
769	u16 input, output;
770	u8 interp_reso;
771	u32 phase_mult;
772
773	writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG);
774
775	input = line->fmt[MSM_VFE_PAD_SINK].width - 1;
776	output = line->compose.width - 1;
777	reg = (output << 16) | input;
778	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE);
779
780	interp_reso = vfe_calc_interp_reso(input, output);
781	phase_mult = input * (1 << (14 + interp_reso)) / output;
782	reg = (interp_reso << 28) | phase_mult;
783	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE);
784
785	input = line->fmt[MSM_VFE_PAD_SINK].height - 1;
786	output = line->compose.height - 1;
787	reg = (output << 16) | input;
788	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE);
789
790	interp_reso = vfe_calc_interp_reso(input, output);
791	phase_mult = input * (1 << (14 + interp_reso)) / output;
792	reg = (interp_reso << 28) | phase_mult;
793	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE);
794
795	writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG);
796
797	input = line->fmt[MSM_VFE_PAD_SINK].width - 1;
798	output = line->compose.width / 2 - 1;
799	reg = (output << 16) | input;
800	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE);
801
802	interp_reso = vfe_calc_interp_reso(input, output);
803	phase_mult = input * (1 << (14 + interp_reso)) / output;
804	reg = (interp_reso << 28) | phase_mult;
805	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE);
806
807	input = line->fmt[MSM_VFE_PAD_SINK].height - 1;
808	output = line->compose.height - 1;
809	if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21)
810		output = line->compose.height / 2 - 1;
811	reg = (output << 16) | input;
812	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE);
813
814	interp_reso = vfe_calc_interp_reso(input, output);
815	phase_mult = input * (1 << (14 + interp_reso)) / output;
816	reg = (interp_reso << 28) | phase_mult;
817	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE);
818}
819
820static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line)
821{
822	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
823	u32 reg;
824	u16 first, last;
825
826	first = line->crop.left;
827	last = line->crop.left + line->crop.width - 1;
828	reg = (first << 16) | last;
829	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH);
830
831	first = line->crop.top;
832	last = line->crop.top + line->crop.height - 1;
833	reg = (first << 16) | last;
834	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT);
835
836	first = line->crop.left / 2;
837	last = line->crop.left / 2 + line->crop.width / 2 - 1;
838	reg = (first << 16) | last;
839	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH);
840
841	first = line->crop.top;
842	last = line->crop.top + line->crop.height - 1;
843	if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) {
844		first = line->crop.top / 2;
845		last = line->crop.top / 2 + line->crop.height / 2 - 1;
846	}
847	reg = (first << 16) | last;
848	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT);
849}
850
851static void vfe_set_clamp_cfg(struct vfe_device *vfe)
852{
853	u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 |
854		VFE_0_CLAMP_ENC_MAX_CFG_CH1 |
855		VFE_0_CLAMP_ENC_MAX_CFG_CH2;
856
857	writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG);
858
859	val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 |
860		VFE_0_CLAMP_ENC_MIN_CFG_CH1 |
861		VFE_0_CLAMP_ENC_MIN_CFG_CH2;
862
863	writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG);
864}
865
866static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable)
867{
868	/* empty */
869}
870
871static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)
872{
873	u32 val;
874
875	switch (line->fmt[MSM_VFE_PAD_SINK].code) {
876	case MEDIA_BUS_FMT_YUYV8_2X8:
877		val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;
878		break;
879	case MEDIA_BUS_FMT_YVYU8_2X8:
880		val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;
881		break;
882	case MEDIA_BUS_FMT_UYVY8_2X8:
883	default:
884		val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;
885		break;
886	case MEDIA_BUS_FMT_VYUY8_2X8:
887		val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;
888		break;
889	}
890
891	val |= VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN;
892	writel_relaxed(val, vfe->base + VFE_0_CORE_CFG);
893
894	val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
895	val |= (line->fmt[MSM_VFE_PAD_SINK].height - 1) << 16;
896	writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG);
897
898	val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
899	writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG);
900
901	val = line->fmt[MSM_VFE_PAD_SINK].height - 1;
902	writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG);
903
904	val = 0xffffffff;
905	writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG);
906
907	val = 0xffffffff;
908	writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN);
909
910	val = 0xffffffff;
911	writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN);
912
913	val = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
914	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val);
915
916	val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN;
917	writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG);
918}
919
920static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable)
921{
922	u32 cmd;
923
924	cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE;
925	writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
926
927	/* Make sure camif command is issued written before it is changed again */
928	wmb();
929
930	if (enable)
931		cmd = VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY;
932	else
933		cmd = VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY;
934
935	writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
936}
937
938static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable)
939{
940	u32 val_lens = VFE_0_MODULE_LENS_EN_DEMUX |
941		       VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE;
942	u32 val_zoom = VFE_0_MODULE_ZOOM_EN_SCALE_ENC |
943		       VFE_0_MODULE_ZOOM_EN_CROP_ENC;
944
945	if (enable) {
946		vfe_reg_set(vfe, VFE_0_MODULE_LENS_EN, val_lens);
947		vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom);
948	} else {
949		vfe_reg_clr(vfe, VFE_0_MODULE_LENS_EN, val_lens);
950		vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom);
951	}
952}
953
954static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)
955{
956	u32 val;
957	int ret;
958
959	ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS,
960				 val,
961				 (val & VFE_0_CAMIF_STATUS_HALT),
962				 CAMIF_TIMEOUT_SLEEP_US,
963				 CAMIF_TIMEOUT_ALL_US);
964	if (ret < 0)
965		dev_err(dev, "%s: camif stop timeout\n", __func__);
966
967	return ret;
968}
969
970/*
971 * vfe_isr - VFE module interrupt handler
972 * @irq: Interrupt line
973 * @dev: VFE device
974 *
975 * Return IRQ_HANDLED on success
976 */
977static irqreturn_t vfe_isr(int irq, void *dev)
978{
979	struct vfe_device *vfe = dev;
980	u32 value0, value1;
981	int i, j;
982
983	vfe->ops->isr_read(vfe, &value0, &value1);
984
985	dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
986		value0, value1);
987
988	if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
989		vfe->isr_ops.reset_ack(vfe);
990
991	if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
992		vfe->ops->violation_read(vfe);
993
994	if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
995		vfe->isr_ops.halt_ack(vfe);
996
997	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
998		if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
999			vfe->isr_ops.reg_update(vfe, i);
1000
1001	if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
1002		vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
1003
1004	for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
1005		if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
1006			vfe->isr_ops.sof(vfe, i);
1007
1008	for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
1009		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
1010			vfe->isr_ops.comp_done(vfe, i);
1011			for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
1012				if (vfe->wm_output_map[j] == VFE_LINE_PIX)
1013					value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
1014		}
1015
1016	for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
1017		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
1018			vfe->isr_ops.wm_done(vfe, i);
1019
1020	return IRQ_HANDLED;
1021}
1022
1023static u16 vfe_get_ub_size(u8 vfe_id)
1024{
1025	/* On VFE4.8 the ub-size is the same on both instances */
1026	return MSM_VFE_VFE0_UB_SIZE_RDI;
1027}
1028
1029static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)
1030{
1031	if (enable)
1032		writel_relaxed(2 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm),
1033			       vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD);
1034	else
1035		writel_relaxed(1 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm),
1036			       vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD);
1037
1038	/* The WM must be enabled before sending other commands */
1039	wmb();
1040}
1041
1042static void vfe_set_qos(struct vfe_device *vfe)
1043{
1044	u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG;
1045	u32 val3 = VFE_0_BUS_BDG_QOS_CFG_3_CFG;
1046	u32 val4 = VFE_0_BUS_BDG_QOS_CFG_4_CFG;
1047	u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG;
1048
1049	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0);
1050	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1);
1051	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2);
1052	writel_relaxed(val3, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3);
1053	writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4);
1054	writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5);
1055	writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6);
1056	writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);
1057}
1058
1059static void vfe_set_ds(struct vfe_device *vfe)
1060{
1061	u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG;
1062	u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG;
1063
1064	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0);
1065	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1);
1066	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2);
1067	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3);
1068	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4);
1069	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5);
1070	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6);
1071	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7);
1072	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8);
1073	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9);
1074	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10);
1075	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11);
1076	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12);
1077	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13);
1078	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14);
1079	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15);
1080	writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16);
1081}
1082
1083static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
1084{
1085	*value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
1086	*value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
1087
1088	writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
1089	writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
1090
1091	/* Enforce barrier between local & global IRQ clear */
1092	wmb();
1093	writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
1094}
1095
1096/*
1097 * vfe_pm_domain_off - Disable power domains specific to this VFE.
1098 * @vfe: VFE Device
1099 */
1100static void vfe_pm_domain_off(struct vfe_device *vfe)
1101{
1102	struct camss *camss = vfe->camss;
1103
1104	device_link_del(camss->genpd_link[vfe->id]);
1105}
1106
1107/*
1108 * vfe_pm_domain_on - Enable power domains specific to this VFE.
1109 * @vfe: VFE Device
1110 */
1111static int vfe_pm_domain_on(struct vfe_device *vfe)
1112{
1113	struct camss *camss = vfe->camss;
1114	enum vfe_line_id id = vfe->id;
1115
1116	camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], DL_FLAG_STATELESS |
1117						DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
1118
1119	if (!camss->genpd_link[id]) {
1120		dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", id);
1121		return -EINVAL;
1122	}
1123
1124	return 0;
1125}
1126
1127static void vfe_violation_read(struct vfe_device *vfe)
1128{
1129	u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
1130
1131	pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
1132}
1133
1134static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_8 = {
1135	.bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
1136	.bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
1137	.bus_enable_wr_if = vfe_bus_enable_wr_if,
1138	.bus_reload_wm = vfe_bus_reload_wm,
1139	.camif_wait_for_stop = vfe_camif_wait_for_stop,
1140	.enable_irq_common = vfe_enable_irq_common,
1141	.enable_irq_pix_line = vfe_enable_irq_pix_line,
1142	.enable_irq_wm_line = vfe_enable_irq_wm_line,
1143	.get_ub_size = vfe_get_ub_size,
1144	.halt_clear = vfe_halt_clear,
1145	.halt_request = vfe_halt_request,
1146	.set_camif_cfg = vfe_set_camif_cfg,
1147	.set_camif_cmd = vfe_set_camif_cmd,
1148	.set_cgc_override = vfe_set_cgc_override,
1149	.set_clamp_cfg = vfe_set_clamp_cfg,
1150	.set_crop_cfg = vfe_set_crop_cfg,
1151	.set_demux_cfg = vfe_set_demux_cfg,
1152	.set_ds = vfe_set_ds,
1153	.set_module_cfg = vfe_set_module_cfg,
1154	.set_qos = vfe_set_qos,
1155	.set_rdi_cid = vfe_set_rdi_cid,
1156	.set_realign_cfg = vfe_set_realign_cfg,
1157	.set_scale_cfg = vfe_set_scale_cfg,
1158	.set_xbar_cfg = vfe_set_xbar_cfg,
1159	.wm_enable = vfe_wm_enable,
1160	.wm_frame_based = vfe_wm_frame_based,
1161	.wm_get_ping_pong_status = vfe_wm_get_ping_pong_status,
1162	.wm_line_based = vfe_wm_line_based,
1163	.wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern,
1164	.wm_set_framedrop_period = vfe_wm_set_framedrop_period,
1165	.wm_set_ping_addr = vfe_wm_set_ping_addr,
1166	.wm_set_pong_addr = vfe_wm_set_pong_addr,
1167	.wm_set_subsample = vfe_wm_set_subsample,
1168	.wm_set_ub_cfg = vfe_wm_set_ub_cfg,
1169};
1170
1171static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
1172{
1173	vfe->isr_ops = vfe_isr_ops_gen1;
1174	vfe->ops_gen1 = &vfe_ops_gen1_4_8;
1175	vfe->video_ops = vfe_video_ops_gen1;
1176
1177	vfe->line_num = VFE_LINE_NUM_GEN1;
1178}
1179
1180const struct vfe_hw_ops vfe_ops_4_8 = {
1181	.global_reset = vfe_global_reset,
1182	.hw_version = vfe_hw_version,
1183	.isr_read = vfe_isr_read,
1184	.isr = vfe_isr,
1185	.pm_domain_off = vfe_pm_domain_off,
1186	.pm_domain_on = vfe_pm_domain_on,
1187	.reg_update_clear = vfe_reg_update_clear,
1188	.reg_update = vfe_reg_update,
1189	.subdev_init = vfe_subdev_init,
1190	.vfe_disable = vfe_gen1_disable,
1191	.vfe_enable = vfe_gen1_enable,
1192	.vfe_halt = vfe_gen1_halt,
1193	.violation_read = vfe_violation_read,
1194};
1195