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