1633b388fSRobert Foss // SPDX-License-Identifier: GPL-2.0
2633b388fSRobert Foss /*
3633b388fSRobert Foss  * camss-vfe-4-8.c
4633b388fSRobert Foss  *
5633b388fSRobert Foss  * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.8
6633b388fSRobert Foss  *
7633b388fSRobert Foss  * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
8633b388fSRobert Foss  * Copyright (C) 2015-2021 Linaro Ltd.
9633b388fSRobert Foss  */
10633b388fSRobert Foss 
112f6f8af6SRobert Foss #include <linux/device.h>
12633b388fSRobert Foss #include <linux/interrupt.h>
13633b388fSRobert Foss #include <linux/io.h>
14633b388fSRobert Foss #include <linux/iopoll.h>
15633b388fSRobert Foss 
16633b388fSRobert Foss #include "camss.h"
17633b388fSRobert Foss #include "camss-vfe.h"
18633b388fSRobert Foss #include "camss-vfe-gen1.h"
19633b388fSRobert Foss 
20633b388fSRobert Foss #define VFE_0_HW_VERSION		0x000
21633b388fSRobert Foss 
22633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD		0x018
23633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD_CORE	BIT(0)
24633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD_CAMIF	BIT(1)
25633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD_BUS	BIT(2)
26633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD_BUS_BDG	BIT(3)
27633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD_REGISTER	BIT(4)
28633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD_PM	BIT(5)
29633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD_BUS_MISR	BIT(6)
30633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD_TESTGEN	BIT(7)
31633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD_DSP	BIT(8)
32633b388fSRobert Foss #define VFE_0_GLOBAL_RESET_CMD_IDLE_CGC	BIT(9)
33633b388fSRobert Foss 
34633b388fSRobert Foss #define VFE_0_MODULE_LENS_EN		0x040
35633b388fSRobert Foss #define VFE_0_MODULE_LENS_EN_DEMUX		BIT(2)
36633b388fSRobert Foss #define VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE	BIT(3)
37633b388fSRobert Foss 
38633b388fSRobert Foss #define VFE_0_MODULE_ZOOM_EN		0x04c
39633b388fSRobert Foss #define VFE_0_MODULE_ZOOM_EN_SCALE_ENC		BIT(1)
40633b388fSRobert Foss #define VFE_0_MODULE_ZOOM_EN_CROP_ENC		BIT(2)
41633b388fSRobert Foss #define VFE_0_MODULE_ZOOM_EN_REALIGN_BUF	BIT(9)
42633b388fSRobert Foss 
43633b388fSRobert Foss #define VFE_0_CORE_CFG			0x050
44633b388fSRobert Foss #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR	0x4
45633b388fSRobert Foss #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB	0x5
46633b388fSRobert Foss #define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY	0x6
47633b388fSRobert Foss #define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY	0x7
48633b388fSRobert Foss #define VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN	BIT(4)
49633b388fSRobert Foss 
50633b388fSRobert Foss #define VFE_0_IRQ_CMD			0x058
51633b388fSRobert Foss #define VFE_0_IRQ_CMD_GLOBAL_CLEAR	BIT(0)
52633b388fSRobert Foss 
53633b388fSRobert Foss #define VFE_0_IRQ_MASK_0		0x05c
54633b388fSRobert Foss #define VFE_0_IRQ_MASK_0_CAMIF_SOF			BIT(0)
55633b388fSRobert Foss #define VFE_0_IRQ_MASK_0_CAMIF_EOF			BIT(1)
56633b388fSRobert Foss #define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)		BIT((n) + 5)
57633b388fSRobert Foss #define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n)		\
58633b388fSRobert Foss 	((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n))
59633b388fSRobert Foss #define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n)	BIT((n) + 8)
60633b388fSRobert Foss #define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n)	BIT((n) + 25)
61633b388fSRobert Foss #define VFE_0_IRQ_MASK_0_RESET_ACK			BIT(31)
62633b388fSRobert Foss #define VFE_0_IRQ_MASK_1		0x060
63633b388fSRobert Foss #define VFE_0_IRQ_MASK_1_CAMIF_ERROR			BIT(0)
64633b388fSRobert Foss #define VFE_0_IRQ_MASK_1_VIOLATION			BIT(7)
65633b388fSRobert Foss #define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK		BIT(8)
66633b388fSRobert Foss #define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n)	BIT((n) + 9)
67633b388fSRobert Foss #define VFE_0_IRQ_MASK_1_RDIn_SOF(n)			BIT((n) + 29)
68633b388fSRobert Foss 
69633b388fSRobert Foss #define VFE_0_IRQ_CLEAR_0		0x064
70633b388fSRobert Foss #define VFE_0_IRQ_CLEAR_1		0x068
71633b388fSRobert Foss 
72633b388fSRobert Foss #define VFE_0_IRQ_STATUS_0		0x06c
73633b388fSRobert Foss #define VFE_0_IRQ_STATUS_0_CAMIF_SOF			BIT(0)
74633b388fSRobert Foss #define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)		BIT((n) + 5)
75633b388fSRobert Foss #define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n)		\
76633b388fSRobert Foss 	((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n))
77633b388fSRobert Foss #define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n)	BIT((n) + 8)
78633b388fSRobert Foss #define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n)	BIT((n) + 25)
79633b388fSRobert Foss #define VFE_0_IRQ_STATUS_0_RESET_ACK			BIT(31)
80633b388fSRobert Foss #define VFE_0_IRQ_STATUS_1		0x070
81633b388fSRobert Foss #define VFE_0_IRQ_STATUS_1_VIOLATION			BIT(7)
82633b388fSRobert Foss #define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK		BIT(8)
83633b388fSRobert Foss #define VFE_0_IRQ_STATUS_1_RDIn_SOF(n)			BIT((n) + 29)
84633b388fSRobert Foss 
85633b388fSRobert Foss #define VFE_0_IRQ_COMPOSITE_MASK_0	0x074
86633b388fSRobert Foss #define VFE_0_VIOLATION_STATUS		0x07c
87633b388fSRobert Foss 
88633b388fSRobert Foss #define VFE_0_BUS_CMD			0x80
89633b388fSRobert Foss #define VFE_0_BUS_CMD_Mx_RLD_CMD(x)	BIT(x)
90633b388fSRobert Foss 
91633b388fSRobert Foss #define VFE_0_BUS_CFG			0x084
92633b388fSRobert Foss 
93633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x(x)		(0x90 + 0x4 * ((x) / 2))
94633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN			BIT(2)
95633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN			BIT(3)
96633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTRA		(0x1 << 4)
97633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER		(0x2 << 4)
98633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA	(0x3 << 4)
99633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT		8
100633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA		0x0
101633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0	0xc
102633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1	0xd
103633b388fSRobert Foss #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2	0xe
104633b388fSRobert Foss 
105633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n)		(0x0a0 + 0x2c * (n))
106633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT	0
107633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n)	(0x0a4 + 0x2c * (n))
108633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n)	(0x0ac + 0x2c * (n))
109633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n)		(0x0b4 + 0x2c * (n))
110633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT	1
111633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT	2
112633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK	(0x1f << 2)
113633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n)		(0x0b8 + 0x2c * (n))
114633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT	16
115633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n)	(0x0bc + 0x2c * (n))
116633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n)	(0x0c0 + 0x2c * (n))
117633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n)	\
118633b388fSRobert Foss 							(0x0c4 + 0x2c * (n))
119633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n)	\
120633b388fSRobert Foss 							(0x0c8 + 0x2c * (n))
121633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF	0xffffffff
122633b388fSRobert Foss 
123633b388fSRobert Foss #define VFE_0_BUS_PING_PONG_STATUS	0x338
124633b388fSRobert Foss 
125633b388fSRobert Foss #define VFE_0_BUS_BDG_CMD		0x400
126633b388fSRobert Foss #define VFE_0_BUS_BDG_CMD_HALT_REQ	1
127633b388fSRobert Foss 
128633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_0		0x404
129633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_0_CFG	0xaaa5aaa5
130633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_1		0x408
131633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_2		0x40c
132633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_3		0x410
133633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_3_CFG	0xaa55aaa5
134633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_4		0x414
135633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_4_CFG	0xaa55aa55
136633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_5		0x418
137633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_6		0x41c
138633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_7		0x420
139633b388fSRobert Foss #define VFE_0_BUS_BDG_QOS_CFG_7_CFG	0x0005aa55
140633b388fSRobert Foss 
141633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_0		0x424
142633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_0_CFG	0xcccc1111
143633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_1		0x428
144633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_2		0x42c
145633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_3		0x430
146633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_4		0x434
147633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_5		0x438
148633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_6		0x43c
149633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_7		0x440
150633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_8		0x444
151633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_9		0x448
152633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_10		0x44c
153633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_11		0x450
154633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_12		0x454
155633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_13		0x458
156633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_14		0x45c
157633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_15		0x460
158633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_16		0x464
159633b388fSRobert Foss #define VFE_0_BUS_BDG_DS_CFG_16_CFG	0x00000110
160633b388fSRobert Foss 
161633b388fSRobert Foss #define VFE_0_RDI_CFG_x(x)		(0x46c + (0x4 * (x)))
162633b388fSRobert Foss #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT	28
163633b388fSRobert Foss #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK	(0xf << 28)
164633b388fSRobert Foss #define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT	4
165633b388fSRobert Foss #define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK		(0xf << 4)
166633b388fSRobert Foss #define VFE_0_RDI_CFG_x_RDI_EN_BIT		BIT(2)
167633b388fSRobert Foss #define VFE_0_RDI_CFG_x_MIPI_EN_BITS		0x3
168633b388fSRobert Foss 
169633b388fSRobert Foss #define VFE_0_CAMIF_CMD				0x478
170633b388fSRobert Foss #define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY	0
171633b388fSRobert Foss #define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY	1
172633b388fSRobert Foss #define VFE_0_CAMIF_CMD_NO_CHANGE		3
173633b388fSRobert Foss #define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS	BIT(2)
174633b388fSRobert Foss #define VFE_0_CAMIF_CFG				0x47c
175633b388fSRobert Foss #define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN		BIT(6)
176633b388fSRobert Foss #define VFE_0_CAMIF_FRAME_CFG			0x484
177633b388fSRobert Foss #define VFE_0_CAMIF_WINDOW_WIDTH_CFG		0x488
178633b388fSRobert Foss #define VFE_0_CAMIF_WINDOW_HEIGHT_CFG		0x48c
179633b388fSRobert Foss #define VFE_0_CAMIF_SUBSAMPLE_CFG		0x490
180633b388fSRobert Foss #define VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN	0x498
181633b388fSRobert Foss #define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN	0x49c
182633b388fSRobert Foss #define VFE_0_CAMIF_STATUS			0x4a4
183633b388fSRobert Foss #define VFE_0_CAMIF_STATUS_HALT			BIT(31)
184633b388fSRobert Foss 
185633b388fSRobert Foss #define VFE_0_REG_UPDATE		0x4ac
186633b388fSRobert Foss #define VFE_0_REG_UPDATE_RDIn(n)		BIT(1 + (n))
187633b388fSRobert Foss #define VFE_0_REG_UPDATE_line_n(n)		\
188633b388fSRobert Foss 			((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n))
189633b388fSRobert Foss 
190633b388fSRobert Foss #define VFE_0_DEMUX_CFG				0x560
191633b388fSRobert Foss #define VFE_0_DEMUX_CFG_PERIOD			0x3
192633b388fSRobert Foss #define VFE_0_DEMUX_GAIN_0			0x564
193633b388fSRobert Foss #define VFE_0_DEMUX_GAIN_0_CH0_EVEN		(0x80 << 0)
194633b388fSRobert Foss #define VFE_0_DEMUX_GAIN_0_CH0_ODD		(0x80 << 16)
195633b388fSRobert Foss #define VFE_0_DEMUX_GAIN_1			0x568
196633b388fSRobert Foss #define VFE_0_DEMUX_GAIN_1_CH1			(0x80 << 0)
197633b388fSRobert Foss #define VFE_0_DEMUX_GAIN_1_CH2			(0x80 << 16)
198633b388fSRobert Foss #define VFE_0_DEMUX_EVEN_CFG			0x574
199633b388fSRobert Foss #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV	0x9cac
200633b388fSRobert Foss #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU	0xac9c
201633b388fSRobert Foss #define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY	0xc9ca
202633b388fSRobert Foss #define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY	0xcac9
203633b388fSRobert Foss #define VFE_0_DEMUX_ODD_CFG			0x578
204633b388fSRobert Foss #define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV	0x9cac
205633b388fSRobert Foss #define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU	0xac9c
206633b388fSRobert Foss #define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY	0xc9ca
207633b388fSRobert Foss #define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY	0xcac9
208633b388fSRobert Foss 
209633b388fSRobert Foss #define VFE_0_SCALE_ENC_Y_CFG			0x91c
210633b388fSRobert Foss #define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE		0x920
211633b388fSRobert Foss #define VFE_0_SCALE_ENC_Y_H_PHASE		0x924
212633b388fSRobert Foss #define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE		0x934
213633b388fSRobert Foss #define VFE_0_SCALE_ENC_Y_V_PHASE		0x938
214633b388fSRobert Foss #define VFE_0_SCALE_ENC_CBCR_CFG		0x948
215633b388fSRobert Foss #define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE	0x94c
216633b388fSRobert Foss #define VFE_0_SCALE_ENC_CBCR_H_PHASE		0x950
217633b388fSRobert Foss #define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE	0x960
218633b388fSRobert Foss #define VFE_0_SCALE_ENC_CBCR_V_PHASE		0x964
219633b388fSRobert Foss 
220633b388fSRobert Foss #define VFE_0_CROP_ENC_Y_WIDTH			0x974
221633b388fSRobert Foss #define VFE_0_CROP_ENC_Y_HEIGHT			0x978
222633b388fSRobert Foss #define VFE_0_CROP_ENC_CBCR_WIDTH		0x97c
223633b388fSRobert Foss #define VFE_0_CROP_ENC_CBCR_HEIGHT		0x980
224633b388fSRobert Foss 
225633b388fSRobert Foss #define VFE_0_CLAMP_ENC_MAX_CFG			0x984
226633b388fSRobert Foss #define VFE_0_CLAMP_ENC_MAX_CFG_CH0		(0xff << 0)
227633b388fSRobert Foss #define VFE_0_CLAMP_ENC_MAX_CFG_CH1		(0xff << 8)
228633b388fSRobert Foss #define VFE_0_CLAMP_ENC_MAX_CFG_CH2		(0xff << 16)
229633b388fSRobert Foss #define VFE_0_CLAMP_ENC_MIN_CFG			0x988
230633b388fSRobert Foss #define VFE_0_CLAMP_ENC_MIN_CFG_CH0		(0x0 << 0)
231633b388fSRobert Foss #define VFE_0_CLAMP_ENC_MIN_CFG_CH1		(0x0 << 8)
232633b388fSRobert Foss #define VFE_0_CLAMP_ENC_MIN_CFG_CH2		(0x0 << 16)
233633b388fSRobert Foss 
234633b388fSRobert Foss #define VFE_0_REALIGN_BUF_CFG			0xaac
235633b388fSRobert Foss #define VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL     BIT(2)
236633b388fSRobert Foss #define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL     BIT(3)
237633b388fSRobert Foss #define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE      BIT(4)
238633b388fSRobert Foss 
239633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_CMD		0xcec
240633b388fSRobert Foss #define VFE_0_BUS_IMAGE_MASTER_n_SHIFT(x)	(2 * (x))
241633b388fSRobert Foss 
242633b388fSRobert Foss #define CAMIF_TIMEOUT_SLEEP_US 1000
243633b388fSRobert Foss #define CAMIF_TIMEOUT_ALL_US 1000000
244633b388fSRobert Foss 
245633b388fSRobert Foss #define MSM_VFE_VFE0_UB_SIZE 2047
246633b388fSRobert Foss #define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3)
247633b388fSRobert Foss #define MSM_VFE_VFE1_UB_SIZE 1535
248633b388fSRobert Foss #define MSM_VFE_VFE1_UB_SIZE_RDI (MSM_VFE_VFE1_UB_SIZE / 3)
249633b388fSRobert Foss 
vfe_hw_version(struct vfe_device * vfe)250d2e86540SRobert Foss static u32 vfe_hw_version(struct vfe_device *vfe)
251633b388fSRobert Foss {
252633b388fSRobert Foss 	u32 hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION);
253633b388fSRobert Foss 
2545ad58667SRobert Foss 	dev_dbg(vfe->camss->dev, "VFE HW Version = 0x%08x\n", hw_version);
255d2e86540SRobert Foss 
256d2e86540SRobert Foss 	return hw_version;
257633b388fSRobert Foss }
258633b388fSRobert Foss 
vfe_reg_clr(struct vfe_device * vfe,u32 reg,u32 clr_bits)259633b388fSRobert Foss static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)
260633b388fSRobert Foss {
261633b388fSRobert Foss 	u32 bits = readl_relaxed(vfe->base + reg);
262633b388fSRobert Foss 
263633b388fSRobert Foss 	writel_relaxed(bits & ~clr_bits, vfe->base + reg);
264633b388fSRobert Foss }
265633b388fSRobert Foss 
vfe_reg_set(struct vfe_device * vfe,u32 reg,u32 set_bits)266633b388fSRobert Foss static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
267633b388fSRobert Foss {
268633b388fSRobert Foss 	u32 bits = readl_relaxed(vfe->base + reg);
269633b388fSRobert Foss 
270633b388fSRobert Foss 	writel_relaxed(bits | set_bits, vfe->base + reg);
271633b388fSRobert Foss }
272633b388fSRobert Foss 
vfe_global_reset(struct vfe_device * vfe)273633b388fSRobert Foss static void vfe_global_reset(struct vfe_device *vfe)
274633b388fSRobert Foss {
275633b388fSRobert Foss 	u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_IDLE_CGC	|
276633b388fSRobert Foss 			 VFE_0_GLOBAL_RESET_CMD_DSP		|
277633b388fSRobert Foss 			 VFE_0_GLOBAL_RESET_CMD_TESTGEN		|
278633b388fSRobert Foss 			 VFE_0_GLOBAL_RESET_CMD_BUS_MISR	|
279633b388fSRobert Foss 			 VFE_0_GLOBAL_RESET_CMD_PM		|
280633b388fSRobert Foss 			 VFE_0_GLOBAL_RESET_CMD_REGISTER	|
281633b388fSRobert Foss 			 VFE_0_GLOBAL_RESET_CMD_BUS_BDG		|
282633b388fSRobert Foss 			 VFE_0_GLOBAL_RESET_CMD_BUS		|
283633b388fSRobert Foss 			 VFE_0_GLOBAL_RESET_CMD_CAMIF		|
284633b388fSRobert Foss 			 VFE_0_GLOBAL_RESET_CMD_CORE;
285633b388fSRobert Foss 
286633b388fSRobert Foss 	writel_relaxed(BIT(31), vfe->base + VFE_0_IRQ_MASK_0);
287633b388fSRobert Foss 
288633b388fSRobert Foss 	/* Enforce barrier between IRQ mask setup and global reset */
289633b388fSRobert Foss 	wmb();
290633b388fSRobert Foss 	writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD);
291633b388fSRobert Foss }
292633b388fSRobert Foss 
vfe_halt_request(struct vfe_device * vfe)293633b388fSRobert Foss static void vfe_halt_request(struct vfe_device *vfe)
294633b388fSRobert Foss {
295633b388fSRobert Foss 	writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ,
296633b388fSRobert Foss 		       vfe->base + VFE_0_BUS_BDG_CMD);
297633b388fSRobert Foss }
298633b388fSRobert Foss 
vfe_halt_clear(struct vfe_device * vfe)299633b388fSRobert Foss static void vfe_halt_clear(struct vfe_device *vfe)
300633b388fSRobert Foss {
301633b388fSRobert Foss 	writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD);
302633b388fSRobert Foss }
303633b388fSRobert Foss 
vfe_wm_frame_based(struct vfe_device * vfe,u8 wm,u8 enable)304633b388fSRobert Foss static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable)
305633b388fSRobert Foss {
306633b388fSRobert Foss 	if (enable)
307633b388fSRobert Foss 		vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm),
308633b388fSRobert Foss 			    1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT);
309633b388fSRobert Foss 	else
310633b388fSRobert Foss 		vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm),
311633b388fSRobert Foss 			    1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT);
312633b388fSRobert Foss }
313633b388fSRobert Foss 
314633b388fSRobert Foss #define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N))
315633b388fSRobert Foss 
vfe_word_per_line_by_pixel(u32 format,u32 pixel_per_line)316633b388fSRobert Foss static int vfe_word_per_line_by_pixel(u32 format, u32 pixel_per_line)
317633b388fSRobert Foss {
318633b388fSRobert Foss 	int val = 0;
319633b388fSRobert Foss 
320633b388fSRobert Foss 	switch (format) {
321633b388fSRobert Foss 	case V4L2_PIX_FMT_NV12:
322633b388fSRobert Foss 	case V4L2_PIX_FMT_NV21:
323633b388fSRobert Foss 	case V4L2_PIX_FMT_NV16:
324633b388fSRobert Foss 	case V4L2_PIX_FMT_NV61:
325633b388fSRobert Foss 		val = CALC_WORD(pixel_per_line, 1, 8);
326633b388fSRobert Foss 		break;
327633b388fSRobert Foss 	case V4L2_PIX_FMT_YUYV:
328633b388fSRobert Foss 	case V4L2_PIX_FMT_YVYU:
329633b388fSRobert Foss 	case V4L2_PIX_FMT_UYVY:
330633b388fSRobert Foss 	case V4L2_PIX_FMT_VYUY:
331633b388fSRobert Foss 		val = CALC_WORD(pixel_per_line, 2, 8);
332633b388fSRobert Foss 		break;
333633b388fSRobert Foss 	}
334633b388fSRobert Foss 
335633b388fSRobert Foss 	return val;
336633b388fSRobert Foss }
337633b388fSRobert Foss 
vfe_word_per_line_by_bytes(u32 bytes_per_line)338633b388fSRobert Foss static int vfe_word_per_line_by_bytes(u32 bytes_per_line)
339633b388fSRobert Foss {
340633b388fSRobert Foss 	return CALC_WORD(bytes_per_line, 1, 8);
341633b388fSRobert Foss }
342633b388fSRobert Foss 
vfe_get_wm_sizes(struct v4l2_pix_format_mplane * pix,u8 plane,u16 * width,u16 * height,u16 * bytesperline)343633b388fSRobert Foss static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane,
344633b388fSRobert Foss 			     u16 *width, u16 *height, u16 *bytesperline)
345633b388fSRobert Foss {
346*749d8965STom Rix 	*width = pix->width;
347*749d8965STom Rix 	*height = pix->height;
348*749d8965STom Rix 
349633b388fSRobert Foss 	switch (pix->pixelformat) {
350633b388fSRobert Foss 	case V4L2_PIX_FMT_NV12:
351633b388fSRobert Foss 	case V4L2_PIX_FMT_NV21:
352633b388fSRobert Foss 		*bytesperline = pix->plane_fmt[0].bytesperline;
353633b388fSRobert Foss 		if (plane == 1)
354633b388fSRobert Foss 			*height /= 2;
355633b388fSRobert Foss 		break;
356633b388fSRobert Foss 	case V4L2_PIX_FMT_NV16:
357633b388fSRobert Foss 	case V4L2_PIX_FMT_NV61:
358633b388fSRobert Foss 		*bytesperline = pix->plane_fmt[0].bytesperline;
359633b388fSRobert Foss 		break;
360633b388fSRobert Foss 	case V4L2_PIX_FMT_YUYV:
361633b388fSRobert Foss 	case V4L2_PIX_FMT_YVYU:
362633b388fSRobert Foss 	case V4L2_PIX_FMT_VYUY:
363633b388fSRobert Foss 	case V4L2_PIX_FMT_UYVY:
364633b388fSRobert Foss 		*bytesperline = pix->plane_fmt[plane].bytesperline;
365633b388fSRobert Foss 		break;
366633b388fSRobert Foss 	}
367633b388fSRobert Foss }
368633b388fSRobert Foss 
vfe_wm_line_based(struct vfe_device * vfe,u32 wm,struct v4l2_pix_format_mplane * pix,u8 plane,u32 enable)369633b388fSRobert Foss static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm,
370633b388fSRobert Foss 			      struct v4l2_pix_format_mplane *pix,
371633b388fSRobert Foss 			      u8 plane, u32 enable)
372633b388fSRobert Foss {
373633b388fSRobert Foss 	u32 reg;
374633b388fSRobert Foss 
375633b388fSRobert Foss 	if (enable) {
376633b388fSRobert Foss 		u16 width = 0, height = 0, bytesperline = 0, wpl;
377633b388fSRobert Foss 
378633b388fSRobert Foss 		vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline);
379633b388fSRobert Foss 
380633b388fSRobert Foss 		wpl = vfe_word_per_line_by_pixel(pix->pixelformat, width);
381633b388fSRobert Foss 
382633b388fSRobert Foss 		reg = height - 1;
383633b388fSRobert Foss 		reg |= ((wpl + 3) / 4 - 1) << 16;
384633b388fSRobert Foss 
385633b388fSRobert Foss 		writel_relaxed(reg, vfe->base +
386633b388fSRobert Foss 			       VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
387633b388fSRobert Foss 
388633b388fSRobert Foss 		wpl = vfe_word_per_line_by_bytes(bytesperline);
389633b388fSRobert Foss 
390633b388fSRobert Foss 		reg = 0x3;
391633b388fSRobert Foss 		reg |= (height - 1) << 2;
392633b388fSRobert Foss 		reg |= ((wpl + 1) / 2) << 16;
393633b388fSRobert Foss 
394633b388fSRobert Foss 		writel_relaxed(reg, vfe->base +
395633b388fSRobert Foss 			       VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
396633b388fSRobert Foss 	} else {
397633b388fSRobert Foss 		writel_relaxed(0, vfe->base +
398633b388fSRobert Foss 			       VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
399633b388fSRobert Foss 		writel_relaxed(0, vfe->base +
400633b388fSRobert Foss 			       VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
401633b388fSRobert Foss 	}
402633b388fSRobert Foss }
403633b388fSRobert Foss 
vfe_wm_set_framedrop_period(struct vfe_device * vfe,u8 wm,u8 per)404633b388fSRobert Foss static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per)
405633b388fSRobert Foss {
406633b388fSRobert Foss 	u32 reg;
407633b388fSRobert Foss 
408633b388fSRobert Foss 	reg = readl_relaxed(vfe->base +
409633b388fSRobert Foss 			    VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
410633b388fSRobert Foss 
411633b388fSRobert Foss 	reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK);
412633b388fSRobert Foss 
413633b388fSRobert Foss 	reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT)
414633b388fSRobert Foss 		& VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK;
415633b388fSRobert Foss 
416633b388fSRobert Foss 	writel_relaxed(reg,
417633b388fSRobert Foss 		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
418633b388fSRobert Foss }
419633b388fSRobert Foss 
vfe_wm_set_framedrop_pattern(struct vfe_device * vfe,u8 wm,u32 pattern)420633b388fSRobert Foss static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm,
421633b388fSRobert Foss 					 u32 pattern)
422633b388fSRobert Foss {
423633b388fSRobert Foss 	writel_relaxed(pattern, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm));
424633b388fSRobert Foss }
425633b388fSRobert Foss 
vfe_wm_set_ub_cfg(struct vfe_device * vfe,u8 wm,u16 offset,u16 depth)426633b388fSRobert Foss static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm,
427633b388fSRobert Foss 			      u16 offset, u16 depth)
428633b388fSRobert Foss {
429633b388fSRobert Foss 	u32 reg;
430633b388fSRobert Foss 
431633b388fSRobert Foss 	reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) |
432633b388fSRobert Foss 	      depth;
433633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm));
434633b388fSRobert Foss }
435633b388fSRobert Foss 
vfe_bus_reload_wm(struct vfe_device * vfe,u8 wm)436633b388fSRobert Foss static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm)
437633b388fSRobert Foss {
438633b388fSRobert Foss 	/* Enforce barrier between any outstanding register write */
439633b388fSRobert Foss 	wmb();
440633b388fSRobert Foss 
441633b388fSRobert Foss 	writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD);
442633b388fSRobert Foss 
443633b388fSRobert Foss 	/* Use barrier to make sure bus reload is issued before anything else */
444633b388fSRobert Foss 	wmb();
445633b388fSRobert Foss }
446633b388fSRobert Foss 
vfe_wm_set_ping_addr(struct vfe_device * vfe,u8 wm,u32 addr)447633b388fSRobert Foss static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr)
448633b388fSRobert Foss {
449633b388fSRobert Foss 	writel_relaxed(addr,
450633b388fSRobert Foss 		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm));
451633b388fSRobert Foss }
452633b388fSRobert Foss 
vfe_wm_set_pong_addr(struct vfe_device * vfe,u8 wm,u32 addr)453633b388fSRobert Foss static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr)
454633b388fSRobert Foss {
455633b388fSRobert Foss 	writel_relaxed(addr,
456633b388fSRobert Foss 		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm));
457633b388fSRobert Foss }
458633b388fSRobert Foss 
vfe_wm_get_ping_pong_status(struct vfe_device * vfe,u8 wm)459633b388fSRobert Foss static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm)
460633b388fSRobert Foss {
461633b388fSRobert Foss 	u32 reg;
462633b388fSRobert Foss 
463633b388fSRobert Foss 	reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS);
464633b388fSRobert Foss 
465633b388fSRobert Foss 	return (reg >> wm) & 0x1;
466633b388fSRobert Foss }
467633b388fSRobert Foss 
vfe_bus_enable_wr_if(struct vfe_device * vfe,u8 enable)468633b388fSRobert Foss static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable)
469633b388fSRobert Foss {
470633b388fSRobert Foss 	if (enable)
471633b388fSRobert Foss 		writel_relaxed(0x101, vfe->base + VFE_0_BUS_CFG);
472633b388fSRobert Foss 	else
473633b388fSRobert Foss 		writel_relaxed(0, vfe->base + VFE_0_BUS_CFG);
474633b388fSRobert Foss }
475633b388fSRobert Foss 
vfe_bus_connect_wm_to_rdi(struct vfe_device * vfe,u8 wm,enum vfe_line_id id)476633b388fSRobert Foss static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm,
477633b388fSRobert Foss 				      enum vfe_line_id id)
478633b388fSRobert Foss {
479633b388fSRobert Foss 	u32 reg;
480633b388fSRobert Foss 
481633b388fSRobert Foss 	reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
482633b388fSRobert Foss 	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg);
483633b388fSRobert Foss 
484633b388fSRobert Foss 	reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
485633b388fSRobert Foss 	reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) &
486633b388fSRobert Foss 		VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK;
487633b388fSRobert Foss 	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg);
488633b388fSRobert Foss 
489633b388fSRobert Foss 	switch (id) {
490633b388fSRobert Foss 	case VFE_LINE_RDI0:
491633b388fSRobert Foss 	default:
492633b388fSRobert Foss 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
493633b388fSRobert Foss 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
494633b388fSRobert Foss 		break;
495633b388fSRobert Foss 	case VFE_LINE_RDI1:
496633b388fSRobert Foss 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
497633b388fSRobert Foss 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
498633b388fSRobert Foss 		break;
499633b388fSRobert Foss 	case VFE_LINE_RDI2:
500633b388fSRobert Foss 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
501633b388fSRobert Foss 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
502633b388fSRobert Foss 		break;
503633b388fSRobert Foss 	}
504633b388fSRobert Foss 
505633b388fSRobert Foss 	if (wm % 2 == 1)
506633b388fSRobert Foss 		reg <<= 16;
507633b388fSRobert Foss 
508633b388fSRobert Foss 	vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
509633b388fSRobert Foss }
510633b388fSRobert Foss 
vfe_wm_set_subsample(struct vfe_device * vfe,u8 wm)511633b388fSRobert Foss static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm)
512633b388fSRobert Foss {
513633b388fSRobert Foss 	writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF,
514633b388fSRobert Foss 		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm));
515633b388fSRobert Foss }
516633b388fSRobert Foss 
vfe_bus_disconnect_wm_from_rdi(struct vfe_device * vfe,u8 wm,enum vfe_line_id id)517633b388fSRobert Foss static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm,
518633b388fSRobert Foss 					   enum vfe_line_id id)
519633b388fSRobert Foss {
520633b388fSRobert Foss 	u32 reg;
521633b388fSRobert Foss 
522633b388fSRobert Foss 	reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
523633b388fSRobert Foss 	vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg);
524633b388fSRobert Foss 
525633b388fSRobert Foss 	switch (id) {
526633b388fSRobert Foss 	case VFE_LINE_RDI0:
527633b388fSRobert Foss 	default:
528633b388fSRobert Foss 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
529633b388fSRobert Foss 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
530633b388fSRobert Foss 		break;
531633b388fSRobert Foss 	case VFE_LINE_RDI1:
532633b388fSRobert Foss 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
533633b388fSRobert Foss 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
534633b388fSRobert Foss 		break;
535633b388fSRobert Foss 	case VFE_LINE_RDI2:
536633b388fSRobert Foss 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
537633b388fSRobert Foss 		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
538633b388fSRobert Foss 		break;
539633b388fSRobert Foss 	}
540633b388fSRobert Foss 
541633b388fSRobert Foss 	if (wm % 2 == 1)
542633b388fSRobert Foss 		reg <<= 16;
543633b388fSRobert Foss 
544633b388fSRobert Foss 	vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
545633b388fSRobert Foss }
546633b388fSRobert Foss 
vfe_set_xbar_cfg(struct vfe_device * vfe,struct vfe_output * output,u8 enable)547633b388fSRobert Foss static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output,
548633b388fSRobert Foss 			     u8 enable)
549633b388fSRobert Foss {
550633b388fSRobert Foss 	struct vfe_line *line = container_of(output, struct vfe_line, output);
551633b388fSRobert Foss 	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
552633b388fSRobert Foss 	u32 reg;
553633b388fSRobert Foss 
554633b388fSRobert Foss 	switch (p) {
555633b388fSRobert Foss 	case V4L2_PIX_FMT_NV12:
556633b388fSRobert Foss 	case V4L2_PIX_FMT_NV21:
557633b388fSRobert Foss 	case V4L2_PIX_FMT_NV16:
558633b388fSRobert Foss 	case V4L2_PIX_FMT_NV61:
559633b388fSRobert Foss 		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA <<
560633b388fSRobert Foss 			VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
561633b388fSRobert Foss 
562633b388fSRobert Foss 		if (output->wm_idx[0] % 2 == 1)
563633b388fSRobert Foss 			reg <<= 16;
564633b388fSRobert Foss 
565633b388fSRobert Foss 		if (enable)
566633b388fSRobert Foss 			vfe_reg_set(vfe,
567633b388fSRobert Foss 				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
568633b388fSRobert Foss 				    reg);
569633b388fSRobert Foss 		else
570633b388fSRobert Foss 			vfe_reg_clr(vfe,
571633b388fSRobert Foss 				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
572633b388fSRobert Foss 				    reg);
573633b388fSRobert Foss 
574633b388fSRobert Foss 		reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
575633b388fSRobert Foss 		if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16)
576633b388fSRobert Foss 			reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
577633b388fSRobert Foss 
578633b388fSRobert Foss 		if (output->wm_idx[1] % 2 == 1)
579633b388fSRobert Foss 			reg <<= 16;
580633b388fSRobert Foss 
581633b388fSRobert Foss 		if (enable)
582633b388fSRobert Foss 			vfe_reg_set(vfe,
583633b388fSRobert Foss 				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]),
584633b388fSRobert Foss 				    reg);
585633b388fSRobert Foss 		else
586633b388fSRobert Foss 			vfe_reg_clr(vfe,
587633b388fSRobert Foss 				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]),
588633b388fSRobert Foss 				    reg);
589633b388fSRobert Foss 		break;
590633b388fSRobert Foss 	case V4L2_PIX_FMT_YUYV:
591633b388fSRobert Foss 	case V4L2_PIX_FMT_YVYU:
592633b388fSRobert Foss 	case V4L2_PIX_FMT_VYUY:
593633b388fSRobert Foss 	case V4L2_PIX_FMT_UYVY:
594633b388fSRobert Foss 		reg = VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN;
595633b388fSRobert Foss 		reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
596633b388fSRobert Foss 
597633b388fSRobert Foss 		if (p == V4L2_PIX_FMT_YUYV || p == V4L2_PIX_FMT_YVYU)
598633b388fSRobert Foss 			reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
599633b388fSRobert Foss 
600633b388fSRobert Foss 		if (output->wm_idx[0] % 2 == 1)
601633b388fSRobert Foss 			reg <<= 16;
602633b388fSRobert Foss 
603633b388fSRobert Foss 		if (enable)
604633b388fSRobert Foss 			vfe_reg_set(vfe,
605633b388fSRobert Foss 				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
606633b388fSRobert Foss 				    reg);
607633b388fSRobert Foss 		else
608633b388fSRobert Foss 			vfe_reg_clr(vfe,
609633b388fSRobert Foss 				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
610633b388fSRobert Foss 				    reg);
611633b388fSRobert Foss 		break;
612633b388fSRobert Foss 	default:
613633b388fSRobert Foss 		break;
614633b388fSRobert Foss 	}
615633b388fSRobert Foss }
616633b388fSRobert Foss 
vfe_set_realign_cfg(struct vfe_device * vfe,struct vfe_line * line,u8 enable)617633b388fSRobert Foss static void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line,
618633b388fSRobert Foss 				u8 enable)
619633b388fSRobert Foss {
620633b388fSRobert Foss 	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
621633b388fSRobert Foss 	u32 val = VFE_0_MODULE_ZOOM_EN_REALIGN_BUF;
622633b388fSRobert Foss 
623633b388fSRobert Foss 	if (p != V4L2_PIX_FMT_YUYV && p != V4L2_PIX_FMT_YVYU &&
624633b388fSRobert Foss 	    p != V4L2_PIX_FMT_VYUY && p != V4L2_PIX_FMT_UYVY)
625633b388fSRobert Foss 		return;
626633b388fSRobert Foss 
627633b388fSRobert Foss 	if (enable) {
628633b388fSRobert Foss 		vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val);
629633b388fSRobert Foss 	} else {
630633b388fSRobert Foss 		vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val);
631633b388fSRobert Foss 		return;
632633b388fSRobert Foss 	}
633633b388fSRobert Foss 
634633b388fSRobert Foss 	val = VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE;
635633b388fSRobert Foss 
636633b388fSRobert Foss 	if (p == V4L2_PIX_FMT_UYVY || p == V4L2_PIX_FMT_YUYV)
637633b388fSRobert Foss 		val |= VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL;
638633b388fSRobert Foss 	else
639633b388fSRobert Foss 		val |= VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL;
640633b388fSRobert Foss 
641633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_REALIGN_BUF_CFG);
642633b388fSRobert Foss }
643633b388fSRobert Foss 
vfe_set_rdi_cid(struct vfe_device * vfe,enum vfe_line_id id,u8 cid)644633b388fSRobert Foss static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid)
645633b388fSRobert Foss {
646633b388fSRobert Foss 	vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id),
647633b388fSRobert Foss 		    VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK);
648633b388fSRobert Foss 
649633b388fSRobert Foss 	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id),
650633b388fSRobert Foss 		    cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT);
651633b388fSRobert Foss }
652633b388fSRobert Foss 
vfe_reg_update(struct vfe_device * vfe,enum vfe_line_id line_id)653633b388fSRobert Foss static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
654633b388fSRobert Foss {
655633b388fSRobert Foss 	vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id);
656633b388fSRobert Foss 
657633b388fSRobert Foss 	/* Enforce barrier between line update and commit */
658633b388fSRobert Foss 	wmb();
659633b388fSRobert Foss 
660633b388fSRobert Foss 	writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE);
661633b388fSRobert Foss 
662633b388fSRobert Foss 	/* Make sure register update is issued before further reg writes */
663633b388fSRobert Foss 	wmb();
664633b388fSRobert Foss }
665633b388fSRobert Foss 
vfe_reg_update_clear(struct vfe_device * vfe,enum vfe_line_id line_id)666633b388fSRobert Foss static inline void vfe_reg_update_clear(struct vfe_device *vfe,
667633b388fSRobert Foss 					enum vfe_line_id line_id)
668633b388fSRobert Foss {
669633b388fSRobert Foss 	vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id);
670633b388fSRobert Foss }
671633b388fSRobert Foss 
vfe_enable_irq_wm_line(struct vfe_device * vfe,u8 wm,enum vfe_line_id line_id,u8 enable)672633b388fSRobert Foss static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm,
673633b388fSRobert Foss 				   enum vfe_line_id line_id, u8 enable)
674633b388fSRobert Foss {
675633b388fSRobert Foss 	u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) |
676633b388fSRobert Foss 		      VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
677633b388fSRobert Foss 	u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) |
678633b388fSRobert Foss 		      VFE_0_IRQ_MASK_1_RDIn_SOF(line_id);
679633b388fSRobert Foss 
680633b388fSRobert Foss 	if (enable) {
681633b388fSRobert Foss 		vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
682633b388fSRobert Foss 		vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
683633b388fSRobert Foss 	} else {
684633b388fSRobert Foss 		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
685633b388fSRobert Foss 		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
686633b388fSRobert Foss 	}
687633b388fSRobert Foss }
688633b388fSRobert Foss 
vfe_enable_irq_pix_line(struct vfe_device * vfe,u8 comp,enum vfe_line_id line_id,u8 enable)689633b388fSRobert Foss static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp,
690633b388fSRobert Foss 				    enum vfe_line_id line_id, u8 enable)
691633b388fSRobert Foss {
692633b388fSRobert Foss 	struct vfe_output *output = &vfe->line[line_id].output;
693633b388fSRobert Foss 	unsigned int i;
694633b388fSRobert Foss 	u32 irq_en0;
695633b388fSRobert Foss 	u32 irq_en1;
696633b388fSRobert Foss 	u32 comp_mask = 0;
697633b388fSRobert Foss 
698633b388fSRobert Foss 	irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF;
699633b388fSRobert Foss 	irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF;
700633b388fSRobert Foss 	irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp);
701633b388fSRobert Foss 	irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
702633b388fSRobert Foss 	irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR;
703633b388fSRobert Foss 	for (i = 0; i < output->wm_num; i++) {
704633b388fSRobert Foss 		irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(output->wm_idx[i]);
705633b388fSRobert Foss 		comp_mask |= (1 << output->wm_idx[i]) << comp * 8;
706633b388fSRobert Foss 	}
707633b388fSRobert Foss 
708633b388fSRobert Foss 	if (enable) {
709633b388fSRobert Foss 		vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
710633b388fSRobert Foss 		vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
711633b388fSRobert Foss 		vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
712633b388fSRobert Foss 	} else {
713633b388fSRobert Foss 		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
714633b388fSRobert Foss 		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
715633b388fSRobert Foss 		vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
716633b388fSRobert Foss 	}
717633b388fSRobert Foss }
718633b388fSRobert Foss 
vfe_enable_irq_common(struct vfe_device * vfe)719633b388fSRobert Foss static void vfe_enable_irq_common(struct vfe_device *vfe)
720633b388fSRobert Foss {
721633b388fSRobert Foss 	u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK;
722633b388fSRobert Foss 	u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION |
723633b388fSRobert Foss 		      VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK;
724633b388fSRobert Foss 
725633b388fSRobert Foss 	vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
726633b388fSRobert Foss 	vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
727633b388fSRobert Foss }
728633b388fSRobert Foss 
vfe_set_demux_cfg(struct vfe_device * vfe,struct vfe_line * line)729633b388fSRobert Foss static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)
730633b388fSRobert Foss {
731633b388fSRobert Foss 	u32 val, even_cfg, odd_cfg;
732633b388fSRobert Foss 
733633b388fSRobert Foss 	writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG);
734633b388fSRobert Foss 
735633b388fSRobert Foss 	val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD;
736633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0);
737633b388fSRobert Foss 
738633b388fSRobert Foss 	val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2;
739633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);
740633b388fSRobert Foss 
741633b388fSRobert Foss 	switch (line->fmt[MSM_VFE_PAD_SINK].code) {
742633b388fSRobert Foss 	case MEDIA_BUS_FMT_YUYV8_2X8:
743633b388fSRobert Foss 		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;
744633b388fSRobert Foss 		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;
745633b388fSRobert Foss 		break;
746633b388fSRobert Foss 	case MEDIA_BUS_FMT_YVYU8_2X8:
747633b388fSRobert Foss 		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;
748633b388fSRobert Foss 		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;
749633b388fSRobert Foss 		break;
750633b388fSRobert Foss 	case MEDIA_BUS_FMT_UYVY8_2X8:
751633b388fSRobert Foss 	default:
752633b388fSRobert Foss 		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;
753633b388fSRobert Foss 		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;
754633b388fSRobert Foss 		break;
755633b388fSRobert Foss 	case MEDIA_BUS_FMT_VYUY8_2X8:
756633b388fSRobert Foss 		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;
757633b388fSRobert Foss 		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;
758633b388fSRobert Foss 		break;
759633b388fSRobert Foss 	}
760633b388fSRobert Foss 
761633b388fSRobert Foss 	writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG);
762633b388fSRobert Foss 	writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG);
763633b388fSRobert Foss }
764633b388fSRobert Foss 
vfe_set_scale_cfg(struct vfe_device * vfe,struct vfe_line * line)765633b388fSRobert Foss static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line)
766633b388fSRobert Foss {
767633b388fSRobert Foss 	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
768633b388fSRobert Foss 	u32 reg;
769633b388fSRobert Foss 	u16 input, output;
770633b388fSRobert Foss 	u8 interp_reso;
771633b388fSRobert Foss 	u32 phase_mult;
772633b388fSRobert Foss 
773633b388fSRobert Foss 	writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG);
774633b388fSRobert Foss 
775633b388fSRobert Foss 	input = line->fmt[MSM_VFE_PAD_SINK].width - 1;
776633b388fSRobert Foss 	output = line->compose.width - 1;
777633b388fSRobert Foss 	reg = (output << 16) | input;
778633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE);
779633b388fSRobert Foss 
780633b388fSRobert Foss 	interp_reso = vfe_calc_interp_reso(input, output);
781633b388fSRobert Foss 	phase_mult = input * (1 << (14 + interp_reso)) / output;
782633b388fSRobert Foss 	reg = (interp_reso << 28) | phase_mult;
783633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE);
784633b388fSRobert Foss 
785633b388fSRobert Foss 	input = line->fmt[MSM_VFE_PAD_SINK].height - 1;
786633b388fSRobert Foss 	output = line->compose.height - 1;
787633b388fSRobert Foss 	reg = (output << 16) | input;
788633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE);
789633b388fSRobert Foss 
790633b388fSRobert Foss 	interp_reso = vfe_calc_interp_reso(input, output);
791633b388fSRobert Foss 	phase_mult = input * (1 << (14 + interp_reso)) / output;
792633b388fSRobert Foss 	reg = (interp_reso << 28) | phase_mult;
793633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE);
794633b388fSRobert Foss 
795633b388fSRobert Foss 	writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG);
796633b388fSRobert Foss 
797633b388fSRobert Foss 	input = line->fmt[MSM_VFE_PAD_SINK].width - 1;
798633b388fSRobert Foss 	output = line->compose.width / 2 - 1;
799633b388fSRobert Foss 	reg = (output << 16) | input;
800633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE);
801633b388fSRobert Foss 
802633b388fSRobert Foss 	interp_reso = vfe_calc_interp_reso(input, output);
803633b388fSRobert Foss 	phase_mult = input * (1 << (14 + interp_reso)) / output;
804633b388fSRobert Foss 	reg = (interp_reso << 28) | phase_mult;
805633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE);
806633b388fSRobert Foss 
807633b388fSRobert Foss 	input = line->fmt[MSM_VFE_PAD_SINK].height - 1;
808633b388fSRobert Foss 	output = line->compose.height - 1;
809633b388fSRobert Foss 	if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21)
810633b388fSRobert Foss 		output = line->compose.height / 2 - 1;
811633b388fSRobert Foss 	reg = (output << 16) | input;
812633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE);
813633b388fSRobert Foss 
814633b388fSRobert Foss 	interp_reso = vfe_calc_interp_reso(input, output);
815633b388fSRobert Foss 	phase_mult = input * (1 << (14 + interp_reso)) / output;
816633b388fSRobert Foss 	reg = (interp_reso << 28) | phase_mult;
817633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE);
818633b388fSRobert Foss }
819633b388fSRobert Foss 
vfe_set_crop_cfg(struct vfe_device * vfe,struct vfe_line * line)820633b388fSRobert Foss static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line)
821633b388fSRobert Foss {
822633b388fSRobert Foss 	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
823633b388fSRobert Foss 	u32 reg;
824633b388fSRobert Foss 	u16 first, last;
825633b388fSRobert Foss 
826633b388fSRobert Foss 	first = line->crop.left;
827633b388fSRobert Foss 	last = line->crop.left + line->crop.width - 1;
828633b388fSRobert Foss 	reg = (first << 16) | last;
829633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH);
830633b388fSRobert Foss 
831633b388fSRobert Foss 	first = line->crop.top;
832633b388fSRobert Foss 	last = line->crop.top + line->crop.height - 1;
833633b388fSRobert Foss 	reg = (first << 16) | last;
834633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT);
835633b388fSRobert Foss 
836633b388fSRobert Foss 	first = line->crop.left / 2;
837633b388fSRobert Foss 	last = line->crop.left / 2 + line->crop.width / 2 - 1;
838633b388fSRobert Foss 	reg = (first << 16) | last;
839633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH);
840633b388fSRobert Foss 
841633b388fSRobert Foss 	first = line->crop.top;
842633b388fSRobert Foss 	last = line->crop.top + line->crop.height - 1;
843633b388fSRobert Foss 	if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) {
844633b388fSRobert Foss 		first = line->crop.top / 2;
845633b388fSRobert Foss 		last = line->crop.top / 2 + line->crop.height / 2 - 1;
846633b388fSRobert Foss 	}
847633b388fSRobert Foss 	reg = (first << 16) | last;
848633b388fSRobert Foss 	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT);
849633b388fSRobert Foss }
850633b388fSRobert Foss 
vfe_set_clamp_cfg(struct vfe_device * vfe)851633b388fSRobert Foss static void vfe_set_clamp_cfg(struct vfe_device *vfe)
852633b388fSRobert Foss {
853633b388fSRobert Foss 	u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 |
854633b388fSRobert Foss 		VFE_0_CLAMP_ENC_MAX_CFG_CH1 |
855633b388fSRobert Foss 		VFE_0_CLAMP_ENC_MAX_CFG_CH2;
856633b388fSRobert Foss 
857633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG);
858633b388fSRobert Foss 
859633b388fSRobert Foss 	val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 |
860633b388fSRobert Foss 		VFE_0_CLAMP_ENC_MIN_CFG_CH1 |
861633b388fSRobert Foss 		VFE_0_CLAMP_ENC_MIN_CFG_CH2;
862633b388fSRobert Foss 
863633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG);
864633b388fSRobert Foss }
865633b388fSRobert Foss 
vfe_set_cgc_override(struct vfe_device * vfe,u8 wm,u8 enable)866633b388fSRobert Foss static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable)
867633b388fSRobert Foss {
868633b388fSRobert Foss 	/* empty */
869633b388fSRobert Foss }
870633b388fSRobert Foss 
vfe_set_camif_cfg(struct vfe_device * vfe,struct vfe_line * line)871633b388fSRobert Foss static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)
872633b388fSRobert Foss {
873633b388fSRobert Foss 	u32 val;
874633b388fSRobert Foss 
875633b388fSRobert Foss 	switch (line->fmt[MSM_VFE_PAD_SINK].code) {
876633b388fSRobert Foss 	case MEDIA_BUS_FMT_YUYV8_2X8:
877633b388fSRobert Foss 		val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;
878633b388fSRobert Foss 		break;
879633b388fSRobert Foss 	case MEDIA_BUS_FMT_YVYU8_2X8:
880633b388fSRobert Foss 		val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;
881633b388fSRobert Foss 		break;
882633b388fSRobert Foss 	case MEDIA_BUS_FMT_UYVY8_2X8:
883633b388fSRobert Foss 	default:
884633b388fSRobert Foss 		val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;
885633b388fSRobert Foss 		break;
886633b388fSRobert Foss 	case MEDIA_BUS_FMT_VYUY8_2X8:
887633b388fSRobert Foss 		val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;
888633b388fSRobert Foss 		break;
889633b388fSRobert Foss 	}
890633b388fSRobert Foss 
891633b388fSRobert Foss 	val |= VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN;
892633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_CORE_CFG);
893633b388fSRobert Foss 
894633b388fSRobert Foss 	val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
895633b388fSRobert Foss 	val |= (line->fmt[MSM_VFE_PAD_SINK].height - 1) << 16;
896633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG);
897633b388fSRobert Foss 
898633b388fSRobert Foss 	val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
899633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG);
900633b388fSRobert Foss 
901633b388fSRobert Foss 	val = line->fmt[MSM_VFE_PAD_SINK].height - 1;
902633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG);
903633b388fSRobert Foss 
904633b388fSRobert Foss 	val = 0xffffffff;
905633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG);
906633b388fSRobert Foss 
907633b388fSRobert Foss 	val = 0xffffffff;
908633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN);
909633b388fSRobert Foss 
910633b388fSRobert Foss 	val = 0xffffffff;
911633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN);
912633b388fSRobert Foss 
913633b388fSRobert Foss 	val = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
914633b388fSRobert Foss 	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val);
915633b388fSRobert Foss 
916633b388fSRobert Foss 	val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN;
917633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG);
918633b388fSRobert Foss }
919633b388fSRobert Foss 
vfe_set_camif_cmd(struct vfe_device * vfe,u8 enable)920633b388fSRobert Foss static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable)
921633b388fSRobert Foss {
922633b388fSRobert Foss 	u32 cmd;
923633b388fSRobert Foss 
924633b388fSRobert Foss 	cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE;
925633b388fSRobert Foss 	writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
926633b388fSRobert Foss 
927633b388fSRobert Foss 	/* Make sure camif command is issued written before it is changed again */
928633b388fSRobert Foss 	wmb();
929633b388fSRobert Foss 
930633b388fSRobert Foss 	if (enable)
931633b388fSRobert Foss 		cmd = VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY;
932633b388fSRobert Foss 	else
933633b388fSRobert Foss 		cmd = VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY;
934633b388fSRobert Foss 
935633b388fSRobert Foss 	writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
936633b388fSRobert Foss }
937633b388fSRobert Foss 
vfe_set_module_cfg(struct vfe_device * vfe,u8 enable)938633b388fSRobert Foss static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable)
939633b388fSRobert Foss {
940633b388fSRobert Foss 	u32 val_lens = VFE_0_MODULE_LENS_EN_DEMUX |
941633b388fSRobert Foss 		       VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE;
942633b388fSRobert Foss 	u32 val_zoom = VFE_0_MODULE_ZOOM_EN_SCALE_ENC |
943633b388fSRobert Foss 		       VFE_0_MODULE_ZOOM_EN_CROP_ENC;
944633b388fSRobert Foss 
945633b388fSRobert Foss 	if (enable) {
946633b388fSRobert Foss 		vfe_reg_set(vfe, VFE_0_MODULE_LENS_EN, val_lens);
947633b388fSRobert Foss 		vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom);
948633b388fSRobert Foss 	} else {
949633b388fSRobert Foss 		vfe_reg_clr(vfe, VFE_0_MODULE_LENS_EN, val_lens);
950633b388fSRobert Foss 		vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom);
951633b388fSRobert Foss 	}
952633b388fSRobert Foss }
953633b388fSRobert Foss 
vfe_camif_wait_for_stop(struct vfe_device * vfe,struct device * dev)954633b388fSRobert Foss static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)
955633b388fSRobert Foss {
956633b388fSRobert Foss 	u32 val;
957633b388fSRobert Foss 	int ret;
958633b388fSRobert Foss 
959633b388fSRobert Foss 	ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS,
960633b388fSRobert Foss 				 val,
961633b388fSRobert Foss 				 (val & VFE_0_CAMIF_STATUS_HALT),
962633b388fSRobert Foss 				 CAMIF_TIMEOUT_SLEEP_US,
963633b388fSRobert Foss 				 CAMIF_TIMEOUT_ALL_US);
964633b388fSRobert Foss 	if (ret < 0)
965633b388fSRobert Foss 		dev_err(dev, "%s: camif stop timeout\n", __func__);
966633b388fSRobert Foss 
967633b388fSRobert Foss 	return ret;
968633b388fSRobert Foss }
969633b388fSRobert Foss 
970633b388fSRobert Foss /*
971633b388fSRobert Foss  * vfe_isr - VFE module interrupt handler
972633b388fSRobert Foss  * @irq: Interrupt line
973633b388fSRobert Foss  * @dev: VFE device
974633b388fSRobert Foss  *
975633b388fSRobert Foss  * Return IRQ_HANDLED on success
976633b388fSRobert Foss  */
vfe_isr(int irq,void * dev)977633b388fSRobert Foss static irqreturn_t vfe_isr(int irq, void *dev)
978633b388fSRobert Foss {
979633b388fSRobert Foss 	struct vfe_device *vfe = dev;
980633b388fSRobert Foss 	u32 value0, value1;
981633b388fSRobert Foss 	int i, j;
982633b388fSRobert Foss 
983633b388fSRobert Foss 	vfe->ops->isr_read(vfe, &value0, &value1);
984633b388fSRobert Foss 
985633b388fSRobert Foss 	dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
986633b388fSRobert Foss 		value0, value1);
987633b388fSRobert Foss 
988633b388fSRobert Foss 	if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
989633b388fSRobert Foss 		vfe->isr_ops.reset_ack(vfe);
990633b388fSRobert Foss 
991633b388fSRobert Foss 	if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
992633b388fSRobert Foss 		vfe->ops->violation_read(vfe);
993633b388fSRobert Foss 
994633b388fSRobert Foss 	if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
995633b388fSRobert Foss 		vfe->isr_ops.halt_ack(vfe);
996633b388fSRobert Foss 
997633b388fSRobert Foss 	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
998633b388fSRobert Foss 		if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
999633b388fSRobert Foss 			vfe->isr_ops.reg_update(vfe, i);
1000633b388fSRobert Foss 
1001633b388fSRobert Foss 	if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
1002633b388fSRobert Foss 		vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
1003633b388fSRobert Foss 
1004633b388fSRobert Foss 	for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
1005633b388fSRobert Foss 		if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
1006633b388fSRobert Foss 			vfe->isr_ops.sof(vfe, i);
1007633b388fSRobert Foss 
1008633b388fSRobert Foss 	for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
1009633b388fSRobert Foss 		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
1010633b388fSRobert Foss 			vfe->isr_ops.comp_done(vfe, i);
1011633b388fSRobert Foss 			for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
1012633b388fSRobert Foss 				if (vfe->wm_output_map[j] == VFE_LINE_PIX)
1013633b388fSRobert Foss 					value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
1014633b388fSRobert Foss 		}
1015633b388fSRobert Foss 
1016633b388fSRobert Foss 	for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
1017633b388fSRobert Foss 		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
1018633b388fSRobert Foss 			vfe->isr_ops.wm_done(vfe, i);
1019633b388fSRobert Foss 
1020633b388fSRobert Foss 	return IRQ_HANDLED;
1021633b388fSRobert Foss }
1022633b388fSRobert Foss 
vfe_get_ub_size(u8 vfe_id)1023633b388fSRobert Foss static u16 vfe_get_ub_size(u8 vfe_id)
1024633b388fSRobert Foss {
1025633b388fSRobert Foss 	/* On VFE4.8 the ub-size is the same on both instances */
1026633b388fSRobert Foss 	return MSM_VFE_VFE0_UB_SIZE_RDI;
1027633b388fSRobert Foss }
1028633b388fSRobert Foss 
vfe_wm_enable(struct vfe_device * vfe,u8 wm,u8 enable)1029633b388fSRobert Foss static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)
1030633b388fSRobert Foss {
1031633b388fSRobert Foss 	if (enable)
1032633b388fSRobert Foss 		writel_relaxed(2 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm),
1033633b388fSRobert Foss 			       vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD);
1034633b388fSRobert Foss 	else
1035633b388fSRobert Foss 		writel_relaxed(1 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm),
1036633b388fSRobert Foss 			       vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD);
1037633b388fSRobert Foss 
1038633b388fSRobert Foss 	/* The WM must be enabled before sending other commands */
1039633b388fSRobert Foss 	wmb();
1040633b388fSRobert Foss }
1041633b388fSRobert Foss 
vfe_set_qos(struct vfe_device * vfe)1042633b388fSRobert Foss static void vfe_set_qos(struct vfe_device *vfe)
1043633b388fSRobert Foss {
1044633b388fSRobert Foss 	u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG;
1045633b388fSRobert Foss 	u32 val3 = VFE_0_BUS_BDG_QOS_CFG_3_CFG;
1046633b388fSRobert Foss 	u32 val4 = VFE_0_BUS_BDG_QOS_CFG_4_CFG;
1047633b388fSRobert Foss 	u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG;
1048633b388fSRobert Foss 
1049633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0);
1050633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1);
1051633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2);
1052633b388fSRobert Foss 	writel_relaxed(val3, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3);
1053633b388fSRobert Foss 	writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4);
1054633b388fSRobert Foss 	writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5);
1055633b388fSRobert Foss 	writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6);
1056633b388fSRobert Foss 	writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);
1057633b388fSRobert Foss }
1058633b388fSRobert Foss 
vfe_set_ds(struct vfe_device * vfe)1059633b388fSRobert Foss static void vfe_set_ds(struct vfe_device *vfe)
1060633b388fSRobert Foss {
1061633b388fSRobert Foss 	u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG;
1062633b388fSRobert Foss 	u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG;
1063633b388fSRobert Foss 
1064633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0);
1065633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1);
1066633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2);
1067633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3);
1068633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4);
1069633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5);
1070633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6);
1071633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7);
1072633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8);
1073633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9);
1074633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10);
1075633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11);
1076633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12);
1077633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13);
1078633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14);
1079633b388fSRobert Foss 	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15);
1080633b388fSRobert Foss 	writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16);
1081633b388fSRobert Foss }
1082633b388fSRobert Foss 
vfe_isr_read(struct vfe_device * vfe,u32 * value0,u32 * value1)1083633b388fSRobert Foss static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
1084633b388fSRobert Foss {
1085633b388fSRobert Foss 	*value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
1086633b388fSRobert Foss 	*value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
1087633b388fSRobert Foss 
1088633b388fSRobert Foss 	writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
1089633b388fSRobert Foss 	writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
1090633b388fSRobert Foss 
1091633b388fSRobert Foss 	/* Enforce barrier between local & global IRQ clear */
1092633b388fSRobert Foss 	wmb();
1093633b388fSRobert Foss 	writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
1094633b388fSRobert Foss }
1095633b388fSRobert Foss 
10962f6f8af6SRobert Foss /*
10972f6f8af6SRobert Foss  * vfe_pm_domain_off - Disable power domains specific to this VFE.
10982f6f8af6SRobert Foss  * @vfe: VFE Device
10992f6f8af6SRobert Foss  */
vfe_pm_domain_off(struct vfe_device * vfe)11002f6f8af6SRobert Foss static void vfe_pm_domain_off(struct vfe_device *vfe)
11012f6f8af6SRobert Foss {
11022f6f8af6SRobert Foss 	struct camss *camss = vfe->camss;
11032f6f8af6SRobert Foss 
11042f6f8af6SRobert Foss 	device_link_del(camss->genpd_link[vfe->id]);
11052f6f8af6SRobert Foss }
11062f6f8af6SRobert Foss 
11072f6f8af6SRobert Foss /*
11082f6f8af6SRobert Foss  * vfe_pm_domain_on - Enable power domains specific to this VFE.
11092f6f8af6SRobert Foss  * @vfe: VFE Device
11102f6f8af6SRobert Foss  */
vfe_pm_domain_on(struct vfe_device * vfe)11112f6f8af6SRobert Foss static int vfe_pm_domain_on(struct vfe_device *vfe)
11122f6f8af6SRobert Foss {
11132f6f8af6SRobert Foss 	struct camss *camss = vfe->camss;
11142f6f8af6SRobert Foss 	enum vfe_line_id id = vfe->id;
11152f6f8af6SRobert Foss 
11162f6f8af6SRobert Foss 	camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], DL_FLAG_STATELESS |
11172f6f8af6SRobert Foss 						DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
11182f6f8af6SRobert Foss 
11192f6f8af6SRobert Foss 	if (!camss->genpd_link[id]) {
11202f6f8af6SRobert Foss 		dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", id);
11212f6f8af6SRobert Foss 		return -EINVAL;
11222f6f8af6SRobert Foss 	}
11232f6f8af6SRobert Foss 
11242f6f8af6SRobert Foss 	return 0;
11252f6f8af6SRobert Foss }
11262f6f8af6SRobert Foss 
vfe_violation_read(struct vfe_device * vfe)1127633b388fSRobert Foss static void vfe_violation_read(struct vfe_device *vfe)
1128633b388fSRobert Foss {
1129633b388fSRobert Foss 	u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
1130633b388fSRobert Foss 
1131633b388fSRobert Foss 	pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
1132633b388fSRobert Foss }
1133633b388fSRobert Foss 
1134633b388fSRobert Foss static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_8 = {
1135633b388fSRobert Foss 	.bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
1136633b388fSRobert Foss 	.bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
1137633b388fSRobert Foss 	.bus_enable_wr_if = vfe_bus_enable_wr_if,
1138633b388fSRobert Foss 	.bus_reload_wm = vfe_bus_reload_wm,
1139633b388fSRobert Foss 	.camif_wait_for_stop = vfe_camif_wait_for_stop,
1140633b388fSRobert Foss 	.enable_irq_common = vfe_enable_irq_common,
1141633b388fSRobert Foss 	.enable_irq_pix_line = vfe_enable_irq_pix_line,
1142633b388fSRobert Foss 	.enable_irq_wm_line = vfe_enable_irq_wm_line,
1143633b388fSRobert Foss 	.get_ub_size = vfe_get_ub_size,
1144633b388fSRobert Foss 	.halt_clear = vfe_halt_clear,
1145633b388fSRobert Foss 	.halt_request = vfe_halt_request,
1146633b388fSRobert Foss 	.set_camif_cfg = vfe_set_camif_cfg,
1147633b388fSRobert Foss 	.set_camif_cmd = vfe_set_camif_cmd,
1148633b388fSRobert Foss 	.set_cgc_override = vfe_set_cgc_override,
1149633b388fSRobert Foss 	.set_clamp_cfg = vfe_set_clamp_cfg,
1150633b388fSRobert Foss 	.set_crop_cfg = vfe_set_crop_cfg,
1151633b388fSRobert Foss 	.set_demux_cfg = vfe_set_demux_cfg,
1152633b388fSRobert Foss 	.set_ds = vfe_set_ds,
1153633b388fSRobert Foss 	.set_module_cfg = vfe_set_module_cfg,
1154633b388fSRobert Foss 	.set_qos = vfe_set_qos,
1155633b388fSRobert Foss 	.set_rdi_cid = vfe_set_rdi_cid,
1156633b388fSRobert Foss 	.set_realign_cfg = vfe_set_realign_cfg,
1157633b388fSRobert Foss 	.set_scale_cfg = vfe_set_scale_cfg,
1158633b388fSRobert Foss 	.set_xbar_cfg = vfe_set_xbar_cfg,
1159633b388fSRobert Foss 	.wm_enable = vfe_wm_enable,
1160633b388fSRobert Foss 	.wm_frame_based = vfe_wm_frame_based,
1161633b388fSRobert Foss 	.wm_get_ping_pong_status = vfe_wm_get_ping_pong_status,
1162633b388fSRobert Foss 	.wm_line_based = vfe_wm_line_based,
1163633b388fSRobert Foss 	.wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern,
1164633b388fSRobert Foss 	.wm_set_framedrop_period = vfe_wm_set_framedrop_period,
1165633b388fSRobert Foss 	.wm_set_ping_addr = vfe_wm_set_ping_addr,
1166633b388fSRobert Foss 	.wm_set_pong_addr = vfe_wm_set_pong_addr,
1167633b388fSRobert Foss 	.wm_set_subsample = vfe_wm_set_subsample,
1168633b388fSRobert Foss 	.wm_set_ub_cfg = vfe_wm_set_ub_cfg,
1169633b388fSRobert Foss };
1170633b388fSRobert Foss 
vfe_subdev_init(struct device * dev,struct vfe_device * vfe)1171633b388fSRobert Foss static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
1172633b388fSRobert Foss {
1173633b388fSRobert Foss 	vfe->isr_ops = vfe_isr_ops_gen1;
1174633b388fSRobert Foss 	vfe->ops_gen1 = &vfe_ops_gen1_4_8;
1175633b388fSRobert Foss 	vfe->video_ops = vfe_video_ops_gen1;
1176633b388fSRobert Foss 
1177633b388fSRobert Foss 	vfe->line_num = VFE_LINE_NUM_GEN1;
1178633b388fSRobert Foss }
1179633b388fSRobert Foss 
1180633b388fSRobert Foss const struct vfe_hw_ops vfe_ops_4_8 = {
1181633b388fSRobert Foss 	.global_reset = vfe_global_reset,
1182d2e86540SRobert Foss 	.hw_version = vfe_hw_version,
1183633b388fSRobert Foss 	.isr_read = vfe_isr_read,
1184633b388fSRobert Foss 	.isr = vfe_isr,
11852f6f8af6SRobert Foss 	.pm_domain_off = vfe_pm_domain_off,
11862f6f8af6SRobert Foss 	.pm_domain_on = vfe_pm_domain_on,
1187633b388fSRobert Foss 	.reg_update_clear = vfe_reg_update_clear,
1188633b388fSRobert Foss 	.reg_update = vfe_reg_update,
1189633b388fSRobert Foss 	.subdev_init = vfe_subdev_init,
1190633b388fSRobert Foss 	.vfe_disable = vfe_gen1_disable,
1191633b388fSRobert Foss 	.vfe_enable = vfe_gen1_enable,
1192633b388fSRobert Foss 	.vfe_halt = vfe_gen1_halt,
1193633b388fSRobert Foss 	.violation_read = vfe_violation_read,
1194633b388fSRobert Foss };
1195