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