1
2
3
4
5
6
7
8
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
257static 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
264static 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
274static 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
281static 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
288static 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
304 wmb();
305 writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD);
306}
307
308static 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
314static void vfe_halt_clear(struct vfe_device *vfe)
315{
316 writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD);
317}
318
319static 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
329static 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
341static 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
363static int vfe_word_per_line_by_bytes(u32 bytes_per_line)
364{
365 return CALC_WORD(bytes_per_line, 1, 8);
366}
367
368static 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
398static 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
433static 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
449static 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
456static 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
466static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm)
467{
468
469 wmb();
470
471 writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD);
472
473
474 wmb();
475}
476
477static 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
483static 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
489static 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
498static 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
506static 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
541static 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
548static 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
578static 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
648static 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
675static 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
684static 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
689 wmb();
690 writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE);
691
692
693 wmb();
694}
695
696static 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
702static 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
719static 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
750static 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
760static 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
796static 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
851static 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
882static 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
897static 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
912static 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
936static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable)
937{
938
939}
940
941static 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
990static 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
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
1008static 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
1024static 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
1044
1045
1046
1047
1048
1049static 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
1095static 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
1104 wmb();
1105 writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
1106}
1107
1108
1109
1110
1111
1112static 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
1126
1127
1128static 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
1144static 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
1151static 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
1188static 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
1197const 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