Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / drivers / media / platform / qcom / camss-8x16 / camss-vfe.c
blob55232a9129503e3dda670a3821d0a0f6390a6f2c
1 /*
2 * camss-vfe.c
4 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module
6 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
7 * Copyright (C) 2015-2017 Linaro Ltd.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 and
11 * only version 2 as published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 #include <linux/clk.h>
19 #include <linux/completion.h>
20 #include <linux/interrupt.h>
21 #include <linux/iommu.h>
22 #include <linux/iopoll.h>
23 #include <linux/mutex.h>
24 #include <linux/of.h>
25 #include <linux/platform_device.h>
26 #include <linux/spinlock_types.h>
27 #include <linux/spinlock.h>
28 #include <media/media-entity.h>
29 #include <media/v4l2-device.h>
30 #include <media/v4l2-subdev.h>
32 #include "camss-vfe.h"
33 #include "camss.h"
35 #define MSM_VFE_NAME "msm_vfe"
37 #define vfe_line_array(ptr_line) \
38 ((const struct vfe_line (*)[]) &(ptr_line[-(ptr_line->id)]))
40 #define to_vfe(ptr_line) \
41 container_of(vfe_line_array(ptr_line), struct vfe_device, ptr_line)
43 #define VFE_0_HW_VERSION 0x000
45 #define VFE_0_GLOBAL_RESET_CMD 0x00c
46 #define VFE_0_GLOBAL_RESET_CMD_CORE (1 << 0)
47 #define VFE_0_GLOBAL_RESET_CMD_CAMIF (1 << 1)
48 #define VFE_0_GLOBAL_RESET_CMD_BUS (1 << 2)
49 #define VFE_0_GLOBAL_RESET_CMD_BUS_BDG (1 << 3)
50 #define VFE_0_GLOBAL_RESET_CMD_REGISTER (1 << 4)
51 #define VFE_0_GLOBAL_RESET_CMD_TIMER (1 << 5)
52 #define VFE_0_GLOBAL_RESET_CMD_PM (1 << 6)
53 #define VFE_0_GLOBAL_RESET_CMD_BUS_MISR (1 << 7)
54 #define VFE_0_GLOBAL_RESET_CMD_TESTGEN (1 << 8)
56 #define VFE_0_MODULE_CFG 0x018
57 #define VFE_0_MODULE_CFG_DEMUX (1 << 2)
58 #define VFE_0_MODULE_CFG_CHROMA_UPSAMPLE (1 << 3)
59 #define VFE_0_MODULE_CFG_SCALE_ENC (1 << 23)
60 #define VFE_0_MODULE_CFG_CROP_ENC (1 << 27)
62 #define VFE_0_CORE_CFG 0x01c
63 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR 0x4
64 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB 0x5
65 #define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY 0x6
66 #define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY 0x7
68 #define VFE_0_IRQ_CMD 0x024
69 #define VFE_0_IRQ_CMD_GLOBAL_CLEAR (1 << 0)
71 #define VFE_0_IRQ_MASK_0 0x028
72 #define VFE_0_IRQ_MASK_0_CAMIF_SOF (1 << 0)
73 #define VFE_0_IRQ_MASK_0_CAMIF_EOF (1 << 1)
74 #define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n) (1 << ((n) + 5))
75 #define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n) \
76 ((n) == VFE_LINE_PIX ? (1 << 4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n))
77 #define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n) (1 << ((n) + 8))
78 #define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n) (1 << ((n) + 25))
79 #define VFE_0_IRQ_MASK_0_RESET_ACK (1 << 31)
80 #define VFE_0_IRQ_MASK_1 0x02c
81 #define VFE_0_IRQ_MASK_1_CAMIF_ERROR (1 << 0)
82 #define VFE_0_IRQ_MASK_1_VIOLATION (1 << 7)
83 #define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK (1 << 8)
84 #define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) (1 << ((n) + 9))
85 #define VFE_0_IRQ_MASK_1_RDIn_SOF(n) (1 << ((n) + 29))
87 #define VFE_0_IRQ_CLEAR_0 0x030
88 #define VFE_0_IRQ_CLEAR_1 0x034
90 #define VFE_0_IRQ_STATUS_0 0x038
91 #define VFE_0_IRQ_STATUS_0_CAMIF_SOF (1 << 0)
92 #define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n) (1 << ((n) + 5))
93 #define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n) \
94 ((n) == VFE_LINE_PIX ? (1 << 4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n))
95 #define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n) (1 << ((n) + 8))
96 #define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n) (1 << ((n) + 25))
97 #define VFE_0_IRQ_STATUS_0_RESET_ACK (1 << 31)
98 #define VFE_0_IRQ_STATUS_1 0x03c
99 #define VFE_0_IRQ_STATUS_1_VIOLATION (1 << 7)
100 #define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK (1 << 8)
101 #define VFE_0_IRQ_STATUS_1_RDIn_SOF(n) (1 << ((n) + 29))
103 #define VFE_0_IRQ_COMPOSITE_MASK_0 0x40
104 #define VFE_0_VIOLATION_STATUS 0x48
106 #define VFE_0_BUS_CMD 0x4c
107 #define VFE_0_BUS_CMD_Mx_RLD_CMD(x) (1 << (x))
109 #define VFE_0_BUS_CFG 0x050
111 #define VFE_0_BUS_XBAR_CFG_x(x) (0x58 + 0x4 * ((x) / 2))
112 #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN (1 << 1)
113 #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA (0x3 << 4)
114 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT 8
115 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA 0
116 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 5
117 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 6
118 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 7
120 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n) (0x06c + 0x24 * (n))
121 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT 0
122 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT 1
123 #define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n) (0x070 + 0x24 * (n))
124 #define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n) (0x074 + 0x24 * (n))
125 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n) (0x078 + 0x24 * (n))
126 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT 2
127 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK (0x1F << 2)
129 #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n) (0x07c + 0x24 * (n))
130 #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT 16
131 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n) (0x080 + 0x24 * (n))
132 #define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n) (0x084 + 0x24 * (n))
133 #define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n) \
134 (0x088 + 0x24 * (n))
135 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n) \
136 (0x08c + 0x24 * (n))
137 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF 0xffffffff
139 #define VFE_0_BUS_PING_PONG_STATUS 0x268
141 #define VFE_0_BUS_BDG_CMD 0x2c0
142 #define VFE_0_BUS_BDG_CMD_HALT_REQ 1
144 #define VFE_0_BUS_BDG_QOS_CFG_0 0x2c4
145 #define VFE_0_BUS_BDG_QOS_CFG_0_CFG 0xaaa5aaa5
146 #define VFE_0_BUS_BDG_QOS_CFG_1 0x2c8
147 #define VFE_0_BUS_BDG_QOS_CFG_2 0x2cc
148 #define VFE_0_BUS_BDG_QOS_CFG_3 0x2d0
149 #define VFE_0_BUS_BDG_QOS_CFG_4 0x2d4
150 #define VFE_0_BUS_BDG_QOS_CFG_5 0x2d8
151 #define VFE_0_BUS_BDG_QOS_CFG_6 0x2dc
152 #define VFE_0_BUS_BDG_QOS_CFG_7 0x2e0
153 #define VFE_0_BUS_BDG_QOS_CFG_7_CFG 0x0001aaa5
155 #define VFE_0_RDI_CFG_x(x) (0x2e8 + (0x4 * (x)))
156 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT 28
157 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK (0xf << 28)
158 #define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT 4
159 #define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK (0xf << 4)
160 #define VFE_0_RDI_CFG_x_RDI_EN_BIT (1 << 2)
161 #define VFE_0_RDI_CFG_x_MIPI_EN_BITS 0x3
162 #define VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(r) (1 << (16 + (r)))
164 #define VFE_0_CAMIF_CMD 0x2f4
165 #define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY 0
166 #define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY 1
167 #define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS (1 << 2)
168 #define VFE_0_CAMIF_CFG 0x2f8
169 #define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN (1 << 6)
170 #define VFE_0_CAMIF_FRAME_CFG 0x300
171 #define VFE_0_CAMIF_WINDOW_WIDTH_CFG 0x304
172 #define VFE_0_CAMIF_WINDOW_HEIGHT_CFG 0x308
173 #define VFE_0_CAMIF_SUBSAMPLE_CFG_0 0x30c
174 #define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN 0x314
175 #define VFE_0_CAMIF_STATUS 0x31c
176 #define VFE_0_CAMIF_STATUS_HALT (1 << 31)
178 #define VFE_0_REG_UPDATE 0x378
179 #define VFE_0_REG_UPDATE_RDIn(n) (1 << (1 + (n)))
180 #define VFE_0_REG_UPDATE_line_n(n) \
181 ((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n))
183 #define VFE_0_DEMUX_CFG 0x424
184 #define VFE_0_DEMUX_CFG_PERIOD 0x3
185 #define VFE_0_DEMUX_GAIN_0 0x428
186 #define VFE_0_DEMUX_GAIN_0_CH0_EVEN (0x80 << 0)
187 #define VFE_0_DEMUX_GAIN_0_CH0_ODD (0x80 << 16)
188 #define VFE_0_DEMUX_GAIN_1 0x42c
189 #define VFE_0_DEMUX_GAIN_1_CH1 (0x80 << 0)
190 #define VFE_0_DEMUX_GAIN_1_CH2 (0x80 << 16)
191 #define VFE_0_DEMUX_EVEN_CFG 0x438
192 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV 0x9cac
193 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU 0xac9c
194 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY 0xc9ca
195 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY 0xcac9
196 #define VFE_0_DEMUX_ODD_CFG 0x43c
197 #define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV 0x9cac
198 #define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU 0xac9c
199 #define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY 0xc9ca
200 #define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY 0xcac9
202 #define VFE_0_SCALE_ENC_Y_CFG 0x75c
203 #define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE 0x760
204 #define VFE_0_SCALE_ENC_Y_H_PHASE 0x764
205 #define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE 0x76c
206 #define VFE_0_SCALE_ENC_Y_V_PHASE 0x770
207 #define VFE_0_SCALE_ENC_CBCR_CFG 0x778
208 #define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE 0x77c
209 #define VFE_0_SCALE_ENC_CBCR_H_PHASE 0x780
210 #define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE 0x790
211 #define VFE_0_SCALE_ENC_CBCR_V_PHASE 0x794
213 #define VFE_0_CROP_ENC_Y_WIDTH 0x854
214 #define VFE_0_CROP_ENC_Y_HEIGHT 0x858
215 #define VFE_0_CROP_ENC_CBCR_WIDTH 0x85c
216 #define VFE_0_CROP_ENC_CBCR_HEIGHT 0x860
218 #define VFE_0_CLAMP_ENC_MAX_CFG 0x874
219 #define VFE_0_CLAMP_ENC_MAX_CFG_CH0 (0xff << 0)
220 #define VFE_0_CLAMP_ENC_MAX_CFG_CH1 (0xff << 8)
221 #define VFE_0_CLAMP_ENC_MAX_CFG_CH2 (0xff << 16)
222 #define VFE_0_CLAMP_ENC_MIN_CFG 0x878
223 #define VFE_0_CLAMP_ENC_MIN_CFG_CH0 (0x0 << 0)
224 #define VFE_0_CLAMP_ENC_MIN_CFG_CH1 (0x0 << 8)
225 #define VFE_0_CLAMP_ENC_MIN_CFG_CH2 (0x0 << 16)
227 #define VFE_0_CGC_OVERRIDE_1 0x974
228 #define VFE_0_CGC_OVERRIDE_1_IMAGE_Mx_CGC_OVERRIDE(x) (1 << (x))
230 /* VFE reset timeout */
231 #define VFE_RESET_TIMEOUT_MS 50
232 /* VFE halt timeout */
233 #define VFE_HALT_TIMEOUT_MS 100
234 /* Max number of frame drop updates per frame */
235 #define VFE_FRAME_DROP_UPDATES 5
236 /* Frame drop value. NOTE: VAL + UPDATES should not exceed 31 */
237 #define VFE_FRAME_DROP_VAL 20
239 #define VFE_NEXT_SOF_MS 500
241 #define CAMIF_TIMEOUT_SLEEP_US 1000
242 #define CAMIF_TIMEOUT_ALL_US 1000000
244 #define SCALER_RATIO_MAX 16
246 static const struct {
247 u32 code;
248 u8 bpp;
249 } vfe_formats[] = {
251 MEDIA_BUS_FMT_UYVY8_2X8,
255 MEDIA_BUS_FMT_VYUY8_2X8,
259 MEDIA_BUS_FMT_YUYV8_2X8,
263 MEDIA_BUS_FMT_YVYU8_2X8,
267 MEDIA_BUS_FMT_SBGGR8_1X8,
271 MEDIA_BUS_FMT_SGBRG8_1X8,
275 MEDIA_BUS_FMT_SGRBG8_1X8,
279 MEDIA_BUS_FMT_SRGGB8_1X8,
283 MEDIA_BUS_FMT_SBGGR10_1X10,
287 MEDIA_BUS_FMT_SGBRG10_1X10,
291 MEDIA_BUS_FMT_SGRBG10_1X10,
295 MEDIA_BUS_FMT_SRGGB10_1X10,
299 MEDIA_BUS_FMT_SBGGR12_1X12,
303 MEDIA_BUS_FMT_SGBRG12_1X12,
307 MEDIA_BUS_FMT_SGRBG12_1X12,
311 MEDIA_BUS_FMT_SRGGB12_1X12,
317 * vfe_get_bpp - map media bus format to bits per pixel
318 * @code: media bus format code
320 * Return number of bits per pixel
322 static u8 vfe_get_bpp(u32 code)
324 unsigned int i;
326 for (i = 0; i < ARRAY_SIZE(vfe_formats); i++)
327 if (code == vfe_formats[i].code)
328 return vfe_formats[i].bpp;
330 WARN(1, "Unknown format\n");
332 return vfe_formats[0].bpp;
335 static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)
337 u32 bits = readl_relaxed(vfe->base + reg);
339 writel_relaxed(bits & ~clr_bits, vfe->base + reg);
342 static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
344 u32 bits = readl_relaxed(vfe->base + reg);
346 writel_relaxed(bits | set_bits, vfe->base + reg);
349 static void vfe_global_reset(struct vfe_device *vfe)
351 u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_TESTGEN |
352 VFE_0_GLOBAL_RESET_CMD_BUS_MISR |
353 VFE_0_GLOBAL_RESET_CMD_PM |
354 VFE_0_GLOBAL_RESET_CMD_TIMER |
355 VFE_0_GLOBAL_RESET_CMD_REGISTER |
356 VFE_0_GLOBAL_RESET_CMD_BUS_BDG |
357 VFE_0_GLOBAL_RESET_CMD_BUS |
358 VFE_0_GLOBAL_RESET_CMD_CAMIF |
359 VFE_0_GLOBAL_RESET_CMD_CORE;
361 writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD);
364 static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)
366 if (enable)
367 vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
368 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT);
369 else
370 vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
371 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT);
374 static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable)
376 if (enable)
377 vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
378 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT);
379 else
380 vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
381 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT);
384 #define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N))
386 static int vfe_word_per_line(uint32_t format, uint32_t pixel_per_line)
388 int val = 0;
390 switch (format) {
391 case V4L2_PIX_FMT_NV12:
392 case V4L2_PIX_FMT_NV21:
393 case V4L2_PIX_FMT_NV16:
394 case V4L2_PIX_FMT_NV61:
395 val = CALC_WORD(pixel_per_line, 1, 8);
396 break;
397 case V4L2_PIX_FMT_YUYV:
398 case V4L2_PIX_FMT_YVYU:
399 case V4L2_PIX_FMT_UYVY:
400 case V4L2_PIX_FMT_VYUY:
401 val = CALC_WORD(pixel_per_line, 2, 8);
402 break;
405 return val;
408 static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane,
409 u16 *width, u16 *height, u16 *bytesperline)
411 switch (pix->pixelformat) {
412 case V4L2_PIX_FMT_NV12:
413 case V4L2_PIX_FMT_NV21:
414 *width = pix->width;
415 *height = pix->height;
416 *bytesperline = pix->plane_fmt[0].bytesperline;
417 if (plane == 1)
418 *height /= 2;
419 break;
420 case V4L2_PIX_FMT_NV16:
421 case V4L2_PIX_FMT_NV61:
422 *width = pix->width;
423 *height = pix->height;
424 *bytesperline = pix->plane_fmt[0].bytesperline;
425 break;
429 static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm,
430 struct v4l2_pix_format_mplane *pix,
431 u8 plane, u32 enable)
433 u32 reg;
435 if (enable) {
436 u16 width = 0, height = 0, bytesperline = 0, wpl;
438 vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline);
440 wpl = vfe_word_per_line(pix->pixelformat, width);
442 reg = height - 1;
443 reg |= ((wpl + 1) / 2 - 1) << 16;
445 writel_relaxed(reg, vfe->base +
446 VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
448 wpl = vfe_word_per_line(pix->pixelformat, bytesperline);
450 reg = 0x3;
451 reg |= (height - 1) << 4;
452 reg |= wpl << 16;
454 writel_relaxed(reg, vfe->base +
455 VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
456 } else {
457 writel_relaxed(0, vfe->base +
458 VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
459 writel_relaxed(0, vfe->base +
460 VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
464 static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per)
466 u32 reg;
468 reg = readl_relaxed(vfe->base +
469 VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
471 reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK);
473 reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT)
474 & VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK;
476 writel_relaxed(reg,
477 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
480 static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm,
481 u32 pattern)
483 writel_relaxed(pattern,
484 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm));
487 static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm, u16 offset,
488 u16 depth)
490 u32 reg;
492 reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) |
493 depth;
494 writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm));
497 static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm)
499 wmb();
500 writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD);
501 wmb();
504 static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr)
506 writel_relaxed(addr,
507 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm));
510 static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr)
512 writel_relaxed(addr,
513 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm));
516 static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm)
518 u32 reg;
520 reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS);
522 return (reg >> wm) & 0x1;
525 static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable)
527 if (enable)
528 writel_relaxed(0x10000009, vfe->base + VFE_0_BUS_CFG);
529 else
530 writel_relaxed(0, vfe->base + VFE_0_BUS_CFG);
533 static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm,
534 enum vfe_line_id id)
536 u32 reg;
538 reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
539 reg |= VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(id);
540 vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg);
542 reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
543 reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) &
544 VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK;
545 vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg);
547 switch (id) {
548 case VFE_LINE_RDI0:
549 default:
550 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
551 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
552 break;
553 case VFE_LINE_RDI1:
554 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
555 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
556 break;
557 case VFE_LINE_RDI2:
558 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
559 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
560 break;
563 if (wm % 2 == 1)
564 reg <<= 16;
566 vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
569 static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm)
571 writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF,
572 vfe->base +
573 VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm));
576 static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm,
577 enum vfe_line_id id)
579 u32 reg;
581 reg = VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(id);
582 vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(0), reg);
584 reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
585 vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg);
587 switch (id) {
588 case VFE_LINE_RDI0:
589 default:
590 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
591 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
592 break;
593 case VFE_LINE_RDI1:
594 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
595 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
596 break;
597 case VFE_LINE_RDI2:
598 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
599 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
600 break;
603 if (wm % 2 == 1)
604 reg <<= 16;
606 vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
609 static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output,
610 u8 enable)
612 struct vfe_line *line = container_of(output, struct vfe_line, output);
613 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
614 u32 reg;
615 unsigned int i;
617 for (i = 0; i < output->wm_num; i++) {
618 if (i == 0) {
619 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA <<
620 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
621 } else if (i == 1) {
622 reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
623 if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16)
624 reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
625 } else {
626 /* On current devices output->wm_num is always <= 2 */
627 break;
630 if (output->wm_idx[i] % 2 == 1)
631 reg <<= 16;
633 if (enable)
634 vfe_reg_set(vfe,
635 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[i]),
636 reg);
637 else
638 vfe_reg_clr(vfe,
639 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[i]),
640 reg);
644 static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid)
646 vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id),
647 VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK);
649 vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id),
650 cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT);
653 static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
655 vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id);
656 wmb();
657 writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE);
658 wmb();
661 static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm,
662 enum vfe_line_id line_id, u8 enable)
664 u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) |
665 VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
666 u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) |
667 VFE_0_IRQ_MASK_1_RDIn_SOF(line_id);
669 if (enable) {
670 vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
671 vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
672 } else {
673 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
674 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
678 static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp,
679 enum vfe_line_id line_id, u8 enable)
681 struct vfe_output *output = &vfe->line[line_id].output;
682 unsigned int i;
683 u32 irq_en0;
684 u32 irq_en1;
685 u32 comp_mask = 0;
687 irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF;
688 irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF;
689 irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp);
690 irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
691 irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR;
692 for (i = 0; i < output->wm_num; i++) {
693 irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(
694 output->wm_idx[i]);
695 comp_mask |= (1 << output->wm_idx[i]) << comp * 8;
698 if (enable) {
699 vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
700 vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
701 vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
702 } else {
703 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
704 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
705 vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
709 static void vfe_enable_irq_common(struct vfe_device *vfe)
711 u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK;
712 u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION |
713 VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK;
715 vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
716 vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
719 static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)
721 u32 val, even_cfg, odd_cfg;
723 writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG);
725 val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD;
726 writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0);
728 val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2;
729 writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);
731 switch (line->fmt[MSM_VFE_PAD_SINK].code) {
732 case MEDIA_BUS_FMT_YUYV8_2X8:
733 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;
734 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;
735 break;
736 case MEDIA_BUS_FMT_YVYU8_2X8:
737 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;
738 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;
739 break;
740 case MEDIA_BUS_FMT_UYVY8_2X8:
741 default:
742 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;
743 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;
744 break;
745 case MEDIA_BUS_FMT_VYUY8_2X8:
746 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;
747 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;
748 break;
751 writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG);
752 writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG);
755 static inline u8 vfe_calc_interp_reso(u16 input, u16 output)
757 if (input / output >= 16)
758 return 0;
760 if (input / output >= 8)
761 return 1;
763 if (input / output >= 4)
764 return 2;
766 return 3;
769 static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line)
771 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
772 u32 reg;
773 u16 input, output;
774 u8 interp_reso;
775 u32 phase_mult;
777 writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG);
779 input = line->fmt[MSM_VFE_PAD_SINK].width;
780 output = line->compose.width;
781 reg = (output << 16) | input;
782 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE);
784 interp_reso = vfe_calc_interp_reso(input, output);
785 phase_mult = input * (1 << (13 + interp_reso)) / output;
786 reg = (interp_reso << 20) | phase_mult;
787 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE);
789 input = line->fmt[MSM_VFE_PAD_SINK].height;
790 output = line->compose.height;
791 reg = (output << 16) | input;
792 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE);
794 interp_reso = vfe_calc_interp_reso(input, output);
795 phase_mult = input * (1 << (13 + interp_reso)) / output;
796 reg = (interp_reso << 20) | phase_mult;
797 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE);
799 writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG);
801 input = line->fmt[MSM_VFE_PAD_SINK].width;
802 output = line->compose.width / 2;
803 reg = (output << 16) | input;
804 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE);
806 interp_reso = vfe_calc_interp_reso(input, output);
807 phase_mult = input * (1 << (13 + interp_reso)) / output;
808 reg = (interp_reso << 20) | phase_mult;
809 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE);
811 input = line->fmt[MSM_VFE_PAD_SINK].height;
812 output = line->compose.height;
813 if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21)
814 output = line->compose.height / 2;
815 reg = (output << 16) | input;
816 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE);
818 interp_reso = vfe_calc_interp_reso(input, output);
819 phase_mult = input * (1 << (13 + interp_reso)) / output;
820 reg = (interp_reso << 20) | phase_mult;
821 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE);
824 static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line)
826 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
827 u32 reg;
828 u16 first, last;
830 first = line->crop.left;
831 last = line->crop.left + line->crop.width - 1;
832 reg = (first << 16) | last;
833 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH);
835 first = line->crop.top;
836 last = line->crop.top + line->crop.height - 1;
837 reg = (first << 16) | last;
838 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT);
840 first = line->crop.left / 2;
841 last = line->crop.left / 2 + line->crop.width / 2 - 1;
842 reg = (first << 16) | last;
843 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH);
845 first = line->crop.top;
846 last = line->crop.top + line->crop.height - 1;
847 if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) {
848 first = line->crop.top / 2;
849 last = line->crop.top / 2 + line->crop.height / 2 - 1;
851 reg = (first << 16) | last;
852 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT);
855 static void vfe_set_clamp_cfg(struct vfe_device *vfe)
857 u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 |
858 VFE_0_CLAMP_ENC_MAX_CFG_CH1 |
859 VFE_0_CLAMP_ENC_MAX_CFG_CH2;
861 writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG);
863 val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 |
864 VFE_0_CLAMP_ENC_MIN_CFG_CH1 |
865 VFE_0_CLAMP_ENC_MIN_CFG_CH2;
867 writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG);
871 * vfe_reset - Trigger reset on VFE module and wait to complete
872 * @vfe: VFE device
874 * Return 0 on success or a negative error code otherwise
876 static int vfe_reset(struct vfe_device *vfe)
878 unsigned long time;
880 reinit_completion(&vfe->reset_complete);
882 vfe_global_reset(vfe);
884 time = wait_for_completion_timeout(&vfe->reset_complete,
885 msecs_to_jiffies(VFE_RESET_TIMEOUT_MS));
886 if (!time) {
887 dev_err(to_device(vfe), "VFE reset timeout\n");
888 return -EIO;
891 return 0;
895 * vfe_halt - Trigger halt on VFE module and wait to complete
896 * @vfe: VFE device
898 * Return 0 on success or a negative error code otherwise
900 static int vfe_halt(struct vfe_device *vfe)
902 unsigned long time;
904 reinit_completion(&vfe->halt_complete);
906 writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ,
907 vfe->base + VFE_0_BUS_BDG_CMD);
909 time = wait_for_completion_timeout(&vfe->halt_complete,
910 msecs_to_jiffies(VFE_HALT_TIMEOUT_MS));
911 if (!time) {
912 dev_err(to_device(vfe), "VFE halt timeout\n");
913 return -EIO;
916 return 0;
919 static void vfe_init_outputs(struct vfe_device *vfe)
921 int i;
923 for (i = 0; i < ARRAY_SIZE(vfe->line); i++) {
924 struct vfe_output *output = &vfe->line[i].output;
926 output->state = VFE_OUTPUT_OFF;
927 output->buf[0] = NULL;
928 output->buf[1] = NULL;
929 INIT_LIST_HEAD(&output->pending_bufs);
931 output->wm_num = 1;
932 if (vfe->line[i].id == VFE_LINE_PIX)
933 output->wm_num = 2;
937 static void vfe_reset_output_maps(struct vfe_device *vfe)
939 int i;
941 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
942 vfe->wm_output_map[i] = VFE_LINE_NONE;
945 static void vfe_set_qos(struct vfe_device *vfe)
947 u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG;
948 u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG;
950 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0);
951 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1);
952 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2);
953 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3);
954 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4);
955 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5);
956 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6);
957 writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);
960 static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable)
962 u32 val = VFE_0_CGC_OVERRIDE_1_IMAGE_Mx_CGC_OVERRIDE(wm);
964 if (enable)
965 vfe_reg_set(vfe, VFE_0_CGC_OVERRIDE_1, val);
966 else
967 vfe_reg_clr(vfe, VFE_0_CGC_OVERRIDE_1, val);
969 wmb();
972 static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable)
974 u32 val = VFE_0_MODULE_CFG_DEMUX |
975 VFE_0_MODULE_CFG_CHROMA_UPSAMPLE |
976 VFE_0_MODULE_CFG_SCALE_ENC |
977 VFE_0_MODULE_CFG_CROP_ENC;
979 if (enable)
980 writel_relaxed(val, vfe->base + VFE_0_MODULE_CFG);
981 else
982 writel_relaxed(0x0, vfe->base + VFE_0_MODULE_CFG);
985 static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)
987 u32 val;
989 switch (line->fmt[MSM_VFE_PAD_SINK].code) {
990 case MEDIA_BUS_FMT_YUYV8_2X8:
991 val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;
992 break;
993 case MEDIA_BUS_FMT_YVYU8_2X8:
994 val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;
995 break;
996 case MEDIA_BUS_FMT_UYVY8_2X8:
997 default:
998 val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;
999 break;
1000 case MEDIA_BUS_FMT_VYUY8_2X8:
1001 val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;
1002 break;
1005 writel_relaxed(val, vfe->base + VFE_0_CORE_CFG);
1007 val = line->fmt[MSM_VFE_PAD_SINK].width * 2;
1008 val |= line->fmt[MSM_VFE_PAD_SINK].height << 16;
1009 writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG);
1011 val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
1012 writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG);
1014 val = line->fmt[MSM_VFE_PAD_SINK].height - 1;
1015 writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG);
1017 val = 0xffffffff;
1018 writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG_0);
1020 val = 0xffffffff;
1021 writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN);
1023 val = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
1024 vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val);
1026 val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN;
1027 writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG);
1030 static void vfe_set_camif_cmd(struct vfe_device *vfe, u32 cmd)
1032 writel_relaxed(VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS,
1033 vfe->base + VFE_0_CAMIF_CMD);
1035 writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
1038 static int vfe_camif_wait_for_stop(struct vfe_device *vfe)
1040 u32 val;
1041 int ret;
1043 ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS,
1044 val,
1045 (val & VFE_0_CAMIF_STATUS_HALT),
1046 CAMIF_TIMEOUT_SLEEP_US,
1047 CAMIF_TIMEOUT_ALL_US);
1048 if (ret < 0)
1049 dev_err(to_device(vfe), "%s: camif stop timeout\n", __func__);
1051 return ret;
1054 static void vfe_output_init_addrs(struct vfe_device *vfe,
1055 struct vfe_output *output, u8 sync)
1057 u32 ping_addr;
1058 u32 pong_addr;
1059 unsigned int i;
1061 output->active_buf = 0;
1063 for (i = 0; i < output->wm_num; i++) {
1064 if (output->buf[0])
1065 ping_addr = output->buf[0]->addr[i];
1066 else
1067 ping_addr = 0;
1069 if (output->buf[1])
1070 pong_addr = output->buf[1]->addr[i];
1071 else
1072 pong_addr = ping_addr;
1074 vfe_wm_set_ping_addr(vfe, output->wm_idx[i], ping_addr);
1075 vfe_wm_set_pong_addr(vfe, output->wm_idx[i], pong_addr);
1076 if (sync)
1077 vfe_bus_reload_wm(vfe, output->wm_idx[i]);
1081 static void vfe_output_update_ping_addr(struct vfe_device *vfe,
1082 struct vfe_output *output, u8 sync)
1084 u32 addr;
1085 unsigned int i;
1087 for (i = 0; i < output->wm_num; i++) {
1088 if (output->buf[0])
1089 addr = output->buf[0]->addr[i];
1090 else
1091 addr = 0;
1093 vfe_wm_set_ping_addr(vfe, output->wm_idx[i], addr);
1094 if (sync)
1095 vfe_bus_reload_wm(vfe, output->wm_idx[i]);
1099 static void vfe_output_update_pong_addr(struct vfe_device *vfe,
1100 struct vfe_output *output, u8 sync)
1102 u32 addr;
1103 unsigned int i;
1105 for (i = 0; i < output->wm_num; i++) {
1106 if (output->buf[1])
1107 addr = output->buf[1]->addr[i];
1108 else
1109 addr = 0;
1111 vfe_wm_set_pong_addr(vfe, output->wm_idx[i], addr);
1112 if (sync)
1113 vfe_bus_reload_wm(vfe, output->wm_idx[i]);
1118 static int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id)
1120 int ret = -EBUSY;
1121 int i;
1123 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) {
1124 if (vfe->wm_output_map[i] == VFE_LINE_NONE) {
1125 vfe->wm_output_map[i] = line_id;
1126 ret = i;
1127 break;
1131 return ret;
1134 static int vfe_release_wm(struct vfe_device *vfe, u8 wm)
1136 if (wm >= ARRAY_SIZE(vfe->wm_output_map))
1137 return -EINVAL;
1139 vfe->wm_output_map[wm] = VFE_LINE_NONE;
1141 return 0;
1144 static void vfe_output_frame_drop(struct vfe_device *vfe,
1145 struct vfe_output *output,
1146 u32 drop_pattern)
1148 u8 drop_period;
1149 unsigned int i;
1151 /* We need to toggle update period to be valid on next frame */
1152 output->drop_update_idx++;
1153 output->drop_update_idx %= VFE_FRAME_DROP_UPDATES;
1154 drop_period = VFE_FRAME_DROP_VAL + output->drop_update_idx;
1156 for (i = 0; i < output->wm_num; i++) {
1157 vfe_wm_set_framedrop_period(vfe, output->wm_idx[i],
1158 drop_period);
1159 vfe_wm_set_framedrop_pattern(vfe, output->wm_idx[i],
1160 drop_pattern);
1162 vfe_reg_update(vfe, container_of(output, struct vfe_line, output)->id);
1165 static struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output)
1167 struct camss_buffer *buffer = NULL;
1169 if (!list_empty(&output->pending_bufs)) {
1170 buffer = list_first_entry(&output->pending_bufs,
1171 struct camss_buffer,
1172 queue);
1173 list_del(&buffer->queue);
1176 return buffer;
1180 * vfe_buf_add_pending - Add output buffer to list of pending
1181 * @output: VFE output
1182 * @buffer: Video buffer
1184 static void vfe_buf_add_pending(struct vfe_output *output,
1185 struct camss_buffer *buffer)
1187 INIT_LIST_HEAD(&buffer->queue);
1188 list_add_tail(&buffer->queue, &output->pending_bufs);
1192 * vfe_buf_flush_pending - Flush all pending buffers.
1193 * @output: VFE output
1194 * @state: vb2 buffer state
1196 static void vfe_buf_flush_pending(struct vfe_output *output,
1197 enum vb2_buffer_state state)
1199 struct camss_buffer *buf;
1200 struct camss_buffer *t;
1202 list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) {
1203 vb2_buffer_done(&buf->vb.vb2_buf, state);
1204 list_del(&buf->queue);
1208 static void vfe_buf_update_wm_on_next(struct vfe_device *vfe,
1209 struct vfe_output *output)
1211 switch (output->state) {
1212 case VFE_OUTPUT_CONTINUOUS:
1213 vfe_output_frame_drop(vfe, output, 3);
1214 break;
1215 case VFE_OUTPUT_SINGLE:
1216 default:
1217 dev_err_ratelimited(to_device(vfe),
1218 "Next buf in wrong state! %d\n",
1219 output->state);
1220 break;
1224 static void vfe_buf_update_wm_on_last(struct vfe_device *vfe,
1225 struct vfe_output *output)
1227 switch (output->state) {
1228 case VFE_OUTPUT_CONTINUOUS:
1229 output->state = VFE_OUTPUT_SINGLE;
1230 vfe_output_frame_drop(vfe, output, 1);
1231 break;
1232 case VFE_OUTPUT_SINGLE:
1233 output->state = VFE_OUTPUT_STOPPING;
1234 vfe_output_frame_drop(vfe, output, 0);
1235 break;
1236 default:
1237 dev_err_ratelimited(to_device(vfe),
1238 "Last buff in wrong state! %d\n",
1239 output->state);
1240 break;
1244 static void vfe_buf_update_wm_on_new(struct vfe_device *vfe,
1245 struct vfe_output *output,
1246 struct camss_buffer *new_buf)
1248 int inactive_idx;
1250 switch (output->state) {
1251 case VFE_OUTPUT_SINGLE:
1252 inactive_idx = !output->active_buf;
1254 if (!output->buf[inactive_idx]) {
1255 output->buf[inactive_idx] = new_buf;
1257 if (inactive_idx)
1258 vfe_output_update_pong_addr(vfe, output, 0);
1259 else
1260 vfe_output_update_ping_addr(vfe, output, 0);
1262 vfe_output_frame_drop(vfe, output, 3);
1263 output->state = VFE_OUTPUT_CONTINUOUS;
1264 } else {
1265 vfe_buf_add_pending(output, new_buf);
1266 dev_err_ratelimited(to_device(vfe),
1267 "Inactive buffer is busy\n");
1269 break;
1271 case VFE_OUTPUT_IDLE:
1272 if (!output->buf[0]) {
1273 output->buf[0] = new_buf;
1275 vfe_output_init_addrs(vfe, output, 1);
1277 vfe_output_frame_drop(vfe, output, 1);
1278 output->state = VFE_OUTPUT_SINGLE;
1279 } else {
1280 vfe_buf_add_pending(output, new_buf);
1281 dev_err_ratelimited(to_device(vfe),
1282 "Output idle with buffer set!\n");
1284 break;
1286 case VFE_OUTPUT_CONTINUOUS:
1287 default:
1288 vfe_buf_add_pending(output, new_buf);
1289 break;
1293 static int vfe_get_output(struct vfe_line *line)
1295 struct vfe_device *vfe = to_vfe(line);
1296 struct vfe_output *output;
1297 unsigned long flags;
1298 int i;
1299 int wm_idx;
1301 spin_lock_irqsave(&vfe->output_lock, flags);
1303 output = &line->output;
1304 if (output->state != VFE_OUTPUT_OFF) {
1305 dev_err(to_device(vfe), "Output is running\n");
1306 goto error;
1308 output->state = VFE_OUTPUT_RESERVED;
1310 output->active_buf = 0;
1312 for (i = 0; i < output->wm_num; i++) {
1313 wm_idx = vfe_reserve_wm(vfe, line->id);
1314 if (wm_idx < 0) {
1315 dev_err(to_device(vfe), "Can not reserve wm\n");
1316 goto error_get_wm;
1318 output->wm_idx[i] = wm_idx;
1321 output->drop_update_idx = 0;
1323 spin_unlock_irqrestore(&vfe->output_lock, flags);
1325 return 0;
1327 error_get_wm:
1328 for (i--; i >= 0; i--)
1329 vfe_release_wm(vfe, output->wm_idx[i]);
1330 output->state = VFE_OUTPUT_OFF;
1331 error:
1332 spin_unlock_irqrestore(&vfe->output_lock, flags);
1334 return -EINVAL;
1337 static int vfe_put_output(struct vfe_line *line)
1339 struct vfe_device *vfe = to_vfe(line);
1340 struct vfe_output *output = &line->output;
1341 unsigned long flags;
1342 unsigned int i;
1344 spin_lock_irqsave(&vfe->output_lock, flags);
1346 for (i = 0; i < output->wm_num; i++)
1347 vfe_release_wm(vfe, output->wm_idx[i]);
1349 output->state = VFE_OUTPUT_OFF;
1351 spin_unlock_irqrestore(&vfe->output_lock, flags);
1352 return 0;
1355 static int vfe_enable_output(struct vfe_line *line)
1357 struct vfe_device *vfe = to_vfe(line);
1358 struct vfe_output *output = &line->output;
1359 unsigned long flags;
1360 unsigned int i;
1361 u16 ub_size;
1363 switch (vfe->id) {
1364 case 0:
1365 ub_size = MSM_VFE_VFE0_UB_SIZE_RDI;
1366 break;
1367 case 1:
1368 ub_size = MSM_VFE_VFE1_UB_SIZE_RDI;
1369 break;
1370 default:
1371 return -EINVAL;
1374 spin_lock_irqsave(&vfe->output_lock, flags);
1376 vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line->id);
1378 if (output->state != VFE_OUTPUT_RESERVED) {
1379 dev_err(to_device(vfe), "Output is not in reserved state %d\n",
1380 output->state);
1381 spin_unlock_irqrestore(&vfe->output_lock, flags);
1382 return -EINVAL;
1384 output->state = VFE_OUTPUT_IDLE;
1386 output->buf[0] = vfe_buf_get_pending(output);
1387 output->buf[1] = vfe_buf_get_pending(output);
1389 if (!output->buf[0] && output->buf[1]) {
1390 output->buf[0] = output->buf[1];
1391 output->buf[1] = NULL;
1394 if (output->buf[0])
1395 output->state = VFE_OUTPUT_SINGLE;
1397 if (output->buf[1])
1398 output->state = VFE_OUTPUT_CONTINUOUS;
1400 switch (output->state) {
1401 case VFE_OUTPUT_SINGLE:
1402 vfe_output_frame_drop(vfe, output, 1);
1403 break;
1404 case VFE_OUTPUT_CONTINUOUS:
1405 vfe_output_frame_drop(vfe, output, 3);
1406 break;
1407 default:
1408 vfe_output_frame_drop(vfe, output, 0);
1409 break;
1412 output->sequence = 0;
1413 output->wait_sof = 0;
1414 output->wait_reg_update = 0;
1415 reinit_completion(&output->sof);
1416 reinit_completion(&output->reg_update);
1418 vfe_output_init_addrs(vfe, output, 0);
1420 if (line->id != VFE_LINE_PIX) {
1421 vfe_set_cgc_override(vfe, output->wm_idx[0], 1);
1422 vfe_enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 1);
1423 vfe_bus_connect_wm_to_rdi(vfe, output->wm_idx[0], line->id);
1424 vfe_wm_set_subsample(vfe, output->wm_idx[0]);
1425 vfe_set_rdi_cid(vfe, line->id, 0);
1426 vfe_wm_set_ub_cfg(vfe, output->wm_idx[0],
1427 (ub_size + 1) * output->wm_idx[0], ub_size);
1428 vfe_wm_frame_based(vfe, output->wm_idx[0], 1);
1429 vfe_wm_enable(vfe, output->wm_idx[0], 1);
1430 vfe_bus_reload_wm(vfe, output->wm_idx[0]);
1431 } else {
1432 ub_size /= output->wm_num;
1433 for (i = 0; i < output->wm_num; i++) {
1434 vfe_set_cgc_override(vfe, output->wm_idx[i], 1);
1435 vfe_wm_set_subsample(vfe, output->wm_idx[i]);
1436 vfe_wm_set_ub_cfg(vfe, output->wm_idx[i],
1437 (ub_size + 1) * output->wm_idx[i],
1438 ub_size);
1439 vfe_wm_line_based(vfe, output->wm_idx[i],
1440 &line->video_out.active_fmt.fmt.pix_mp,
1441 i, 1);
1442 vfe_wm_enable(vfe, output->wm_idx[i], 1);
1443 vfe_bus_reload_wm(vfe, output->wm_idx[i]);
1445 vfe_enable_irq_pix_line(vfe, 0, line->id, 1);
1446 vfe_set_module_cfg(vfe, 1);
1447 vfe_set_camif_cfg(vfe, line);
1448 vfe_set_xbar_cfg(vfe, output, 1);
1449 vfe_set_demux_cfg(vfe, line);
1450 vfe_set_scale_cfg(vfe, line);
1451 vfe_set_crop_cfg(vfe, line);
1452 vfe_set_clamp_cfg(vfe);
1453 vfe_set_camif_cmd(vfe, VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY);
1456 vfe_reg_update(vfe, line->id);
1458 spin_unlock_irqrestore(&vfe->output_lock, flags);
1460 return 0;
1463 static int vfe_disable_output(struct vfe_line *line)
1465 struct vfe_device *vfe = to_vfe(line);
1466 struct vfe_output *output = &line->output;
1467 unsigned long flags;
1468 unsigned long time;
1469 unsigned int i;
1471 spin_lock_irqsave(&vfe->output_lock, flags);
1473 output->wait_sof = 1;
1474 spin_unlock_irqrestore(&vfe->output_lock, flags);
1476 time = wait_for_completion_timeout(&output->sof,
1477 msecs_to_jiffies(VFE_NEXT_SOF_MS));
1478 if (!time)
1479 dev_err(to_device(vfe), "VFE sof timeout\n");
1481 spin_lock_irqsave(&vfe->output_lock, flags);
1482 for (i = 0; i < output->wm_num; i++)
1483 vfe_wm_enable(vfe, output->wm_idx[i], 0);
1485 vfe_reg_update(vfe, line->id);
1486 output->wait_reg_update = 1;
1487 spin_unlock_irqrestore(&vfe->output_lock, flags);
1489 time = wait_for_completion_timeout(&output->reg_update,
1490 msecs_to_jiffies(VFE_NEXT_SOF_MS));
1491 if (!time)
1492 dev_err(to_device(vfe), "VFE reg update timeout\n");
1494 spin_lock_irqsave(&vfe->output_lock, flags);
1496 if (line->id != VFE_LINE_PIX) {
1497 vfe_wm_frame_based(vfe, output->wm_idx[0], 0);
1498 vfe_bus_disconnect_wm_from_rdi(vfe, output->wm_idx[0], line->id);
1499 vfe_enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 0);
1500 vfe_set_cgc_override(vfe, output->wm_idx[0], 0);
1501 spin_unlock_irqrestore(&vfe->output_lock, flags);
1502 } else {
1503 for (i = 0; i < output->wm_num; i++) {
1504 vfe_wm_line_based(vfe, output->wm_idx[i], NULL, i, 0);
1505 vfe_set_cgc_override(vfe, output->wm_idx[i], 0);
1508 vfe_enable_irq_pix_line(vfe, 0, line->id, 0);
1509 vfe_set_module_cfg(vfe, 0);
1510 vfe_set_xbar_cfg(vfe, output, 0);
1512 vfe_set_camif_cmd(vfe, VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY);
1513 spin_unlock_irqrestore(&vfe->output_lock, flags);
1515 vfe_camif_wait_for_stop(vfe);
1518 return 0;
1522 * vfe_enable - Enable streaming on VFE line
1523 * @line: VFE line
1525 * Return 0 on success or a negative error code otherwise
1527 static int vfe_enable(struct vfe_line *line)
1529 struct vfe_device *vfe = to_vfe(line);
1530 int ret;
1532 mutex_lock(&vfe->stream_lock);
1534 if (!vfe->stream_count) {
1535 vfe_enable_irq_common(vfe);
1537 vfe_bus_enable_wr_if(vfe, 1);
1539 vfe_set_qos(vfe);
1542 vfe->stream_count++;
1544 mutex_unlock(&vfe->stream_lock);
1546 ret = vfe_get_output(line);
1547 if (ret < 0)
1548 goto error_get_output;
1550 ret = vfe_enable_output(line);
1551 if (ret < 0)
1552 goto error_enable_output;
1554 vfe->was_streaming = 1;
1556 return 0;
1559 error_enable_output:
1560 vfe_put_output(line);
1562 error_get_output:
1563 mutex_lock(&vfe->stream_lock);
1565 if (vfe->stream_count == 1)
1566 vfe_bus_enable_wr_if(vfe, 0);
1568 vfe->stream_count--;
1570 mutex_unlock(&vfe->stream_lock);
1572 return ret;
1576 * vfe_disable - Disable streaming on VFE line
1577 * @line: VFE line
1579 * Return 0 on success or a negative error code otherwise
1581 static int vfe_disable(struct vfe_line *line)
1583 struct vfe_device *vfe = to_vfe(line);
1585 vfe_disable_output(line);
1587 vfe_put_output(line);
1589 mutex_lock(&vfe->stream_lock);
1591 if (vfe->stream_count == 1)
1592 vfe_bus_enable_wr_if(vfe, 0);
1594 vfe->stream_count--;
1596 mutex_unlock(&vfe->stream_lock);
1598 return 0;
1602 * vfe_isr_sof - Process start of frame interrupt
1603 * @vfe: VFE Device
1604 * @line_id: VFE line
1606 static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id)
1608 struct vfe_output *output;
1609 unsigned long flags;
1611 spin_lock_irqsave(&vfe->output_lock, flags);
1612 output = &vfe->line[line_id].output;
1613 if (output->wait_sof) {
1614 output->wait_sof = 0;
1615 complete(&output->sof);
1617 spin_unlock_irqrestore(&vfe->output_lock, flags);
1621 * vfe_isr_reg_update - Process reg update interrupt
1622 * @vfe: VFE Device
1623 * @line_id: VFE line
1625 static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
1627 struct vfe_output *output;
1628 unsigned long flags;
1630 spin_lock_irqsave(&vfe->output_lock, flags);
1631 vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id);
1633 output = &vfe->line[line_id].output;
1635 if (output->wait_reg_update) {
1636 output->wait_reg_update = 0;
1637 complete(&output->reg_update);
1638 spin_unlock_irqrestore(&vfe->output_lock, flags);
1639 return;
1642 if (output->state == VFE_OUTPUT_STOPPING) {
1643 /* Release last buffer when hw is idle */
1644 if (output->last_buffer) {
1645 vb2_buffer_done(&output->last_buffer->vb.vb2_buf,
1646 VB2_BUF_STATE_DONE);
1647 output->last_buffer = NULL;
1649 output->state = VFE_OUTPUT_IDLE;
1651 /* Buffers received in stopping state are queued in */
1652 /* dma pending queue, start next capture here */
1654 output->buf[0] = vfe_buf_get_pending(output);
1655 output->buf[1] = vfe_buf_get_pending(output);
1657 if (!output->buf[0] && output->buf[1]) {
1658 output->buf[0] = output->buf[1];
1659 output->buf[1] = NULL;
1662 if (output->buf[0])
1663 output->state = VFE_OUTPUT_SINGLE;
1665 if (output->buf[1])
1666 output->state = VFE_OUTPUT_CONTINUOUS;
1668 switch (output->state) {
1669 case VFE_OUTPUT_SINGLE:
1670 vfe_output_frame_drop(vfe, output, 2);
1671 break;
1672 case VFE_OUTPUT_CONTINUOUS:
1673 vfe_output_frame_drop(vfe, output, 3);
1674 break;
1675 default:
1676 vfe_output_frame_drop(vfe, output, 0);
1677 break;
1680 vfe_output_init_addrs(vfe, output, 1);
1683 spin_unlock_irqrestore(&vfe->output_lock, flags);
1687 * vfe_isr_wm_done - Process write master done interrupt
1688 * @vfe: VFE Device
1689 * @wm: Write master id
1691 static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
1693 struct camss_buffer *ready_buf;
1694 struct vfe_output *output;
1695 dma_addr_t *new_addr;
1696 unsigned long flags;
1697 u32 active_index;
1698 u64 ts = ktime_get_ns();
1699 unsigned int i;
1701 active_index = vfe_wm_get_ping_pong_status(vfe, wm);
1703 spin_lock_irqsave(&vfe->output_lock, flags);
1705 if (vfe->wm_output_map[wm] == VFE_LINE_NONE) {
1706 dev_err_ratelimited(to_device(vfe),
1707 "Received wm done for unmapped index\n");
1708 goto out_unlock;
1710 output = &vfe->line[vfe->wm_output_map[wm]].output;
1712 if (output->active_buf == active_index) {
1713 dev_err_ratelimited(to_device(vfe),
1714 "Active buffer mismatch!\n");
1715 goto out_unlock;
1717 output->active_buf = active_index;
1719 ready_buf = output->buf[!active_index];
1720 if (!ready_buf) {
1721 dev_err_ratelimited(to_device(vfe),
1722 "Missing ready buf %d %d!\n",
1723 !active_index, output->state);
1724 goto out_unlock;
1727 ready_buf->vb.vb2_buf.timestamp = ts;
1728 ready_buf->vb.sequence = output->sequence++;
1730 /* Get next buffer */
1731 output->buf[!active_index] = vfe_buf_get_pending(output);
1732 if (!output->buf[!active_index]) {
1733 /* No next buffer - set same address */
1734 new_addr = ready_buf->addr;
1735 vfe_buf_update_wm_on_last(vfe, output);
1736 } else {
1737 new_addr = output->buf[!active_index]->addr;
1738 vfe_buf_update_wm_on_next(vfe, output);
1741 if (active_index)
1742 for (i = 0; i < output->wm_num; i++)
1743 vfe_wm_set_ping_addr(vfe, output->wm_idx[i],
1744 new_addr[i]);
1745 else
1746 for (i = 0; i < output->wm_num; i++)
1747 vfe_wm_set_pong_addr(vfe, output->wm_idx[i],
1748 new_addr[i]);
1750 spin_unlock_irqrestore(&vfe->output_lock, flags);
1752 if (output->state == VFE_OUTPUT_STOPPING)
1753 output->last_buffer = ready_buf;
1754 else
1755 vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
1757 return;
1759 out_unlock:
1760 spin_unlock_irqrestore(&vfe->output_lock, flags);
1764 * vfe_isr_wm_done - Process composite image done interrupt
1765 * @vfe: VFE Device
1766 * @comp: Composite image id
1768 static void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp)
1770 unsigned int i;
1772 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
1773 if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
1774 vfe_isr_wm_done(vfe, i);
1775 break;
1780 * vfe_isr - ISPIF module interrupt handler
1781 * @irq: Interrupt line
1782 * @dev: VFE device
1784 * Return IRQ_HANDLED on success
1786 static irqreturn_t vfe_isr(int irq, void *dev)
1788 struct vfe_device *vfe = dev;
1789 u32 value0, value1;
1790 u32 violation;
1791 int i, j;
1793 value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
1794 value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
1796 writel_relaxed(value0, vfe->base + VFE_0_IRQ_CLEAR_0);
1797 writel_relaxed(value1, vfe->base + VFE_0_IRQ_CLEAR_1);
1799 wmb();
1800 writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
1802 if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
1803 complete(&vfe->reset_complete);
1805 if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION) {
1806 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
1807 dev_err_ratelimited(to_device(vfe),
1808 "VFE: violation = 0x%08x\n", violation);
1811 if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK) {
1812 complete(&vfe->halt_complete);
1813 writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD);
1816 for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++)
1817 if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
1818 vfe_isr_reg_update(vfe, i);
1820 if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
1821 vfe_isr_sof(vfe, VFE_LINE_PIX);
1823 for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
1824 if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
1825 vfe_isr_sof(vfe, i);
1827 for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
1828 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
1829 vfe_isr_comp_done(vfe, i);
1830 for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
1831 if (vfe->wm_output_map[j] == VFE_LINE_PIX)
1832 value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
1835 for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
1836 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
1837 vfe_isr_wm_done(vfe, i);
1839 return IRQ_HANDLED;
1843 * vfe_set_clock_rates - Calculate and set clock rates on VFE module
1844 * @vfe: VFE device
1846 * Return 0 on success or a negative error code otherwise
1848 static int vfe_set_clock_rates(struct vfe_device *vfe)
1850 struct device *dev = to_device(vfe);
1851 u32 pixel_clock[MSM_VFE_LINE_NUM];
1852 int i, j;
1853 int ret;
1855 for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) {
1856 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
1857 &pixel_clock[i]);
1858 if (ret)
1859 pixel_clock[i] = 0;
1862 for (i = 0; i < vfe->nclocks; i++) {
1863 struct camss_clock *clock = &vfe->clock[i];
1865 if (!strcmp(clock->name, "camss_vfe_vfe")) {
1866 u64 min_rate = 0;
1867 long rate;
1869 for (j = VFE_LINE_RDI0; j <= VFE_LINE_PIX; j++) {
1870 u32 tmp;
1871 u8 bpp;
1873 if (j == VFE_LINE_PIX) {
1874 tmp = pixel_clock[j];
1875 } else {
1876 bpp = vfe_get_bpp(vfe->line[j].
1877 fmt[MSM_VFE_PAD_SINK].code);
1878 tmp = pixel_clock[j] * bpp / 64;
1881 if (min_rate < tmp)
1882 min_rate = tmp;
1885 camss_add_clock_margin(&min_rate);
1887 for (j = 0; j < clock->nfreqs; j++)
1888 if (min_rate < clock->freq[j])
1889 break;
1891 if (j == clock->nfreqs) {
1892 dev_err(dev,
1893 "Pixel clock is too high for VFE");
1894 return -EINVAL;
1897 /* if sensor pixel clock is not available */
1898 /* set highest possible VFE clock rate */
1899 if (min_rate == 0)
1900 j = clock->nfreqs - 1;
1902 rate = clk_round_rate(clock->clk, clock->freq[j]);
1903 if (rate < 0) {
1904 dev_err(dev, "clk round rate failed: %ld\n",
1905 rate);
1906 return -EINVAL;
1909 ret = clk_set_rate(clock->clk, rate);
1910 if (ret < 0) {
1911 dev_err(dev, "clk set rate failed: %d\n", ret);
1912 return ret;
1917 return 0;
1921 * vfe_check_clock_rates - Check current clock rates on VFE module
1922 * @vfe: VFE device
1924 * Return 0 if current clock rates are suitable for a new pipeline
1925 * or a negative error code otherwise
1927 static int vfe_check_clock_rates(struct vfe_device *vfe)
1929 u32 pixel_clock[MSM_VFE_LINE_NUM];
1930 int i, j;
1931 int ret;
1933 for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) {
1934 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
1935 &pixel_clock[i]);
1936 if (ret)
1937 pixel_clock[i] = 0;
1940 for (i = 0; i < vfe->nclocks; i++) {
1941 struct camss_clock *clock = &vfe->clock[i];
1943 if (!strcmp(clock->name, "camss_vfe_vfe")) {
1944 u64 min_rate = 0;
1945 unsigned long rate;
1947 for (j = VFE_LINE_RDI0; j <= VFE_LINE_PIX; j++) {
1948 u32 tmp;
1949 u8 bpp;
1951 if (j == VFE_LINE_PIX) {
1952 tmp = pixel_clock[j];
1953 } else {
1954 bpp = vfe_get_bpp(vfe->line[j].
1955 fmt[MSM_VFE_PAD_SINK].code);
1956 tmp = pixel_clock[j] * bpp / 64;
1959 if (min_rate < tmp)
1960 min_rate = tmp;
1963 camss_add_clock_margin(&min_rate);
1965 rate = clk_get_rate(clock->clk);
1966 if (rate < min_rate)
1967 return -EBUSY;
1971 return 0;
1975 * vfe_get - Power up and reset VFE module
1976 * @vfe: VFE Device
1978 * Return 0 on success or a negative error code otherwise
1980 static int vfe_get(struct vfe_device *vfe)
1982 int ret;
1984 mutex_lock(&vfe->power_lock);
1986 if (vfe->power_count == 0) {
1987 ret = vfe_set_clock_rates(vfe);
1988 if (ret < 0)
1989 goto error_clocks;
1991 ret = camss_enable_clocks(vfe->nclocks, vfe->clock,
1992 to_device(vfe));
1993 if (ret < 0)
1994 goto error_clocks;
1996 ret = vfe_reset(vfe);
1997 if (ret < 0)
1998 goto error_reset;
2000 vfe_reset_output_maps(vfe);
2002 vfe_init_outputs(vfe);
2003 } else {
2004 ret = vfe_check_clock_rates(vfe);
2005 if (ret < 0)
2006 goto error_clocks;
2008 vfe->power_count++;
2010 mutex_unlock(&vfe->power_lock);
2012 return 0;
2014 error_reset:
2015 camss_disable_clocks(vfe->nclocks, vfe->clock);
2017 error_clocks:
2018 mutex_unlock(&vfe->power_lock);
2020 return ret;
2024 * vfe_put - Power down VFE module
2025 * @vfe: VFE Device
2027 static void vfe_put(struct vfe_device *vfe)
2029 mutex_lock(&vfe->power_lock);
2031 if (vfe->power_count == 0) {
2032 dev_err(to_device(vfe), "vfe power off on power_count == 0\n");
2033 goto exit;
2034 } else if (vfe->power_count == 1) {
2035 if (vfe->was_streaming) {
2036 vfe->was_streaming = 0;
2037 vfe_halt(vfe);
2039 camss_disable_clocks(vfe->nclocks, vfe->clock);
2042 vfe->power_count--;
2044 exit:
2045 mutex_unlock(&vfe->power_lock);
2049 * vfe_video_pad_to_line - Get pointer to VFE line by media pad
2050 * @pad: Media pad
2052 * Return pointer to vfe line structure
2054 static struct vfe_line *vfe_video_pad_to_line(struct media_pad *pad)
2056 struct media_pad *vfe_pad;
2057 struct v4l2_subdev *subdev;
2059 vfe_pad = media_entity_remote_pad(pad);
2060 if (vfe_pad == NULL)
2061 return NULL;
2063 subdev = media_entity_to_v4l2_subdev(vfe_pad->entity);
2065 return container_of(subdev, struct vfe_line, subdev);
2069 * vfe_queue_buffer - Add empty buffer
2070 * @vid: Video device structure
2071 * @buf: Buffer to be enqueued
2073 * Add an empty buffer - depending on the current number of buffers it will be
2074 * put in pending buffer queue or directly given to the hardware to be filled.
2076 * Return 0 on success or a negative error code otherwise
2078 static int vfe_queue_buffer(struct camss_video *vid,
2079 struct camss_buffer *buf)
2081 struct vfe_device *vfe = &vid->camss->vfe;
2082 struct vfe_line *line;
2083 struct vfe_output *output;
2084 unsigned long flags;
2086 line = vfe_video_pad_to_line(&vid->pad);
2087 if (!line) {
2088 dev_err(to_device(vfe), "Can not queue buffer\n");
2089 return -1;
2091 output = &line->output;
2093 spin_lock_irqsave(&vfe->output_lock, flags);
2095 vfe_buf_update_wm_on_new(vfe, output, buf);
2097 spin_unlock_irqrestore(&vfe->output_lock, flags);
2099 return 0;
2103 * vfe_flush_buffers - Return all vb2 buffers
2104 * @vid: Video device structure
2105 * @state: vb2 buffer state of the returned buffers
2107 * Return all buffers to vb2. This includes queued pending buffers (still
2108 * unused) and any buffers given to the hardware but again still not used.
2110 * Return 0 on success or a negative error code otherwise
2112 static int vfe_flush_buffers(struct camss_video *vid,
2113 enum vb2_buffer_state state)
2115 struct vfe_device *vfe = &vid->camss->vfe;
2116 struct vfe_line *line;
2117 struct vfe_output *output;
2118 unsigned long flags;
2120 line = vfe_video_pad_to_line(&vid->pad);
2121 if (!line) {
2122 dev_err(to_device(vfe), "Can not flush buffers\n");
2123 return -1;
2125 output = &line->output;
2127 spin_lock_irqsave(&vfe->output_lock, flags);
2129 vfe_buf_flush_pending(output, state);
2131 if (output->buf[0])
2132 vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state);
2134 if (output->buf[1])
2135 vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state);
2137 if (output->last_buffer) {
2138 vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state);
2139 output->last_buffer = NULL;
2142 spin_unlock_irqrestore(&vfe->output_lock, flags);
2144 return 0;
2148 * vfe_set_power - Power on/off VFE module
2149 * @sd: VFE V4L2 subdevice
2150 * @on: Requested power state
2152 * Return 0 on success or a negative error code otherwise
2154 static int vfe_set_power(struct v4l2_subdev *sd, int on)
2156 struct vfe_line *line = v4l2_get_subdevdata(sd);
2157 struct vfe_device *vfe = to_vfe(line);
2158 int ret;
2160 if (on) {
2161 u32 hw_version;
2163 ret = vfe_get(vfe);
2164 if (ret < 0)
2165 return ret;
2167 hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION);
2168 dev_dbg(to_device(vfe),
2169 "VFE HW Version = 0x%08x\n", hw_version);
2170 } else {
2171 vfe_put(vfe);
2174 return 0;
2178 * vfe_set_stream - Enable/disable streaming on VFE module
2179 * @sd: VFE V4L2 subdevice
2180 * @enable: Requested streaming state
2182 * Main configuration of VFE module is triggered here.
2184 * Return 0 on success or a negative error code otherwise
2186 static int vfe_set_stream(struct v4l2_subdev *sd, int enable)
2188 struct vfe_line *line = v4l2_get_subdevdata(sd);
2189 struct vfe_device *vfe = to_vfe(line);
2190 int ret;
2192 if (enable) {
2193 ret = vfe_enable(line);
2194 if (ret < 0)
2195 dev_err(to_device(vfe),
2196 "Failed to enable vfe outputs\n");
2197 } else {
2198 ret = vfe_disable(line);
2199 if (ret < 0)
2200 dev_err(to_device(vfe),
2201 "Failed to disable vfe outputs\n");
2204 return ret;
2208 * __vfe_get_format - Get pointer to format structure
2209 * @line: VFE line
2210 * @cfg: V4L2 subdev pad configuration
2211 * @pad: pad from which format is requested
2212 * @which: TRY or ACTIVE format
2214 * Return pointer to TRY or ACTIVE format structure
2216 static struct v4l2_mbus_framefmt *
2217 __vfe_get_format(struct vfe_line *line,
2218 struct v4l2_subdev_pad_config *cfg,
2219 unsigned int pad,
2220 enum v4l2_subdev_format_whence which)
2222 if (which == V4L2_SUBDEV_FORMAT_TRY)
2223 return v4l2_subdev_get_try_format(&line->subdev, cfg, pad);
2225 return &line->fmt[pad];
2229 * __vfe_get_compose - Get pointer to compose selection structure
2230 * @line: VFE line
2231 * @cfg: V4L2 subdev pad configuration
2232 * @which: TRY or ACTIVE format
2234 * Return pointer to TRY or ACTIVE compose rectangle structure
2236 static struct v4l2_rect *
2237 __vfe_get_compose(struct vfe_line *line,
2238 struct v4l2_subdev_pad_config *cfg,
2239 enum v4l2_subdev_format_whence which)
2241 if (which == V4L2_SUBDEV_FORMAT_TRY)
2242 return v4l2_subdev_get_try_compose(&line->subdev, cfg,
2243 MSM_VFE_PAD_SINK);
2245 return &line->compose;
2249 * __vfe_get_crop - Get pointer to crop selection structure
2250 * @line: VFE line
2251 * @cfg: V4L2 subdev pad configuration
2252 * @which: TRY or ACTIVE format
2254 * Return pointer to TRY or ACTIVE crop rectangle structure
2256 static struct v4l2_rect *
2257 __vfe_get_crop(struct vfe_line *line,
2258 struct v4l2_subdev_pad_config *cfg,
2259 enum v4l2_subdev_format_whence which)
2261 if (which == V4L2_SUBDEV_FORMAT_TRY)
2262 return v4l2_subdev_get_try_crop(&line->subdev, cfg,
2263 MSM_VFE_PAD_SRC);
2265 return &line->crop;
2269 * vfe_try_format - Handle try format by pad subdev method
2270 * @line: VFE line
2271 * @cfg: V4L2 subdev pad configuration
2272 * @pad: pad on which format is requested
2273 * @fmt: pointer to v4l2 format structure
2274 * @which: wanted subdev format
2276 static void vfe_try_format(struct vfe_line *line,
2277 struct v4l2_subdev_pad_config *cfg,
2278 unsigned int pad,
2279 struct v4l2_mbus_framefmt *fmt,
2280 enum v4l2_subdev_format_whence which)
2282 unsigned int i;
2283 u32 code;
2285 switch (pad) {
2286 case MSM_VFE_PAD_SINK:
2287 /* Set format on sink pad */
2289 for (i = 0; i < ARRAY_SIZE(vfe_formats); i++)
2290 if (fmt->code == vfe_formats[i].code)
2291 break;
2293 /* If not found, use UYVY as default */
2294 if (i >= ARRAY_SIZE(vfe_formats))
2295 fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
2297 fmt->width = clamp_t(u32, fmt->width, 1, 8191);
2298 fmt->height = clamp_t(u32, fmt->height, 1, 8191);
2300 fmt->field = V4L2_FIELD_NONE;
2301 fmt->colorspace = V4L2_COLORSPACE_SRGB;
2303 break;
2305 case MSM_VFE_PAD_SRC:
2306 /* Set and return a format same as sink pad */
2308 code = fmt->code;
2310 *fmt = *__vfe_get_format(line, cfg, MSM_VFE_PAD_SINK,
2311 which);
2313 if (line->id == VFE_LINE_PIX) {
2314 struct v4l2_rect *rect;
2316 rect = __vfe_get_crop(line, cfg, which);
2318 fmt->width = rect->width;
2319 fmt->height = rect->height;
2321 switch (fmt->code) {
2322 case MEDIA_BUS_FMT_YUYV8_2X8:
2323 if (code == MEDIA_BUS_FMT_YUYV8_1_5X8)
2324 fmt->code = MEDIA_BUS_FMT_YUYV8_1_5X8;
2325 else
2326 fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
2327 break;
2328 case MEDIA_BUS_FMT_YVYU8_2X8:
2329 if (code == MEDIA_BUS_FMT_YVYU8_1_5X8)
2330 fmt->code = MEDIA_BUS_FMT_YVYU8_1_5X8;
2331 else
2332 fmt->code = MEDIA_BUS_FMT_YVYU8_2X8;
2333 break;
2334 case MEDIA_BUS_FMT_UYVY8_2X8:
2335 default:
2336 if (code == MEDIA_BUS_FMT_UYVY8_1_5X8)
2337 fmt->code = MEDIA_BUS_FMT_UYVY8_1_5X8;
2338 else
2339 fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
2340 break;
2341 case MEDIA_BUS_FMT_VYUY8_2X8:
2342 if (code == MEDIA_BUS_FMT_VYUY8_1_5X8)
2343 fmt->code = MEDIA_BUS_FMT_VYUY8_1_5X8;
2344 else
2345 fmt->code = MEDIA_BUS_FMT_VYUY8_2X8;
2346 break;
2350 break;
2353 fmt->colorspace = V4L2_COLORSPACE_SRGB;
2357 * vfe_try_compose - Handle try compose selection by pad subdev method
2358 * @line: VFE line
2359 * @cfg: V4L2 subdev pad configuration
2360 * @rect: pointer to v4l2 rect structure
2361 * @which: wanted subdev format
2363 static void vfe_try_compose(struct vfe_line *line,
2364 struct v4l2_subdev_pad_config *cfg,
2365 struct v4l2_rect *rect,
2366 enum v4l2_subdev_format_whence which)
2368 struct v4l2_mbus_framefmt *fmt;
2370 fmt = __vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, which);
2372 if (rect->width > fmt->width)
2373 rect->width = fmt->width;
2375 if (rect->height > fmt->height)
2376 rect->height = fmt->height;
2378 if (fmt->width > rect->width * SCALER_RATIO_MAX)
2379 rect->width = (fmt->width + SCALER_RATIO_MAX - 1) /
2380 SCALER_RATIO_MAX;
2382 rect->width &= ~0x1;
2384 if (fmt->height > rect->height * SCALER_RATIO_MAX)
2385 rect->height = (fmt->height + SCALER_RATIO_MAX - 1) /
2386 SCALER_RATIO_MAX;
2388 if (rect->width < 16)
2389 rect->width = 16;
2391 if (rect->height < 4)
2392 rect->height = 4;
2396 * vfe_try_crop - Handle try crop selection by pad subdev method
2397 * @line: VFE line
2398 * @cfg: V4L2 subdev pad configuration
2399 * @rect: pointer to v4l2 rect structure
2400 * @which: wanted subdev format
2402 static void vfe_try_crop(struct vfe_line *line,
2403 struct v4l2_subdev_pad_config *cfg,
2404 struct v4l2_rect *rect,
2405 enum v4l2_subdev_format_whence which)
2407 struct v4l2_rect *compose;
2409 compose = __vfe_get_compose(line, cfg, which);
2411 if (rect->width > compose->width)
2412 rect->width = compose->width;
2414 if (rect->width + rect->left > compose->width)
2415 rect->left = compose->width - rect->width;
2417 if (rect->height > compose->height)
2418 rect->height = compose->height;
2420 if (rect->height + rect->top > compose->height)
2421 rect->top = compose->height - rect->height;
2423 /* wm in line based mode writes multiple of 16 horizontally */
2424 rect->left += (rect->width & 0xf) >> 1;
2425 rect->width &= ~0xf;
2427 if (rect->width < 16) {
2428 rect->left = 0;
2429 rect->width = 16;
2432 if (rect->height < 4) {
2433 rect->top = 0;
2434 rect->height = 4;
2439 * vfe_enum_mbus_code - Handle pixel format enumeration
2440 * @sd: VFE V4L2 subdevice
2441 * @cfg: V4L2 subdev pad configuration
2442 * @code: pointer to v4l2_subdev_mbus_code_enum structure
2444 * return -EINVAL or zero on success
2446 static int vfe_enum_mbus_code(struct v4l2_subdev *sd,
2447 struct v4l2_subdev_pad_config *cfg,
2448 struct v4l2_subdev_mbus_code_enum *code)
2450 struct vfe_line *line = v4l2_get_subdevdata(sd);
2451 struct v4l2_mbus_framefmt *format;
2453 if (code->pad == MSM_VFE_PAD_SINK) {
2454 if (code->index >= ARRAY_SIZE(vfe_formats))
2455 return -EINVAL;
2457 code->code = vfe_formats[code->index].code;
2458 } else {
2459 if (code->index > 0)
2460 return -EINVAL;
2462 format = __vfe_get_format(line, cfg, MSM_VFE_PAD_SINK,
2463 code->which);
2465 code->code = format->code;
2468 return 0;
2472 * vfe_enum_frame_size - Handle frame size enumeration
2473 * @sd: VFE V4L2 subdevice
2474 * @cfg: V4L2 subdev pad configuration
2475 * @fse: pointer to v4l2_subdev_frame_size_enum structure
2477 * Return -EINVAL or zero on success
2479 static int vfe_enum_frame_size(struct v4l2_subdev *sd,
2480 struct v4l2_subdev_pad_config *cfg,
2481 struct v4l2_subdev_frame_size_enum *fse)
2483 struct vfe_line *line = v4l2_get_subdevdata(sd);
2484 struct v4l2_mbus_framefmt format;
2486 if (fse->index != 0)
2487 return -EINVAL;
2489 format.code = fse->code;
2490 format.width = 1;
2491 format.height = 1;
2492 vfe_try_format(line, cfg, fse->pad, &format, fse->which);
2493 fse->min_width = format.width;
2494 fse->min_height = format.height;
2496 if (format.code != fse->code)
2497 return -EINVAL;
2499 format.code = fse->code;
2500 format.width = -1;
2501 format.height = -1;
2502 vfe_try_format(line, cfg, fse->pad, &format, fse->which);
2503 fse->max_width = format.width;
2504 fse->max_height = format.height;
2506 return 0;
2510 * vfe_get_format - Handle get format by pads subdev method
2511 * @sd: VFE V4L2 subdevice
2512 * @cfg: V4L2 subdev pad configuration
2513 * @fmt: pointer to v4l2 subdev format structure
2515 * Return -EINVAL or zero on success
2517 static int vfe_get_format(struct v4l2_subdev *sd,
2518 struct v4l2_subdev_pad_config *cfg,
2519 struct v4l2_subdev_format *fmt)
2521 struct vfe_line *line = v4l2_get_subdevdata(sd);
2522 struct v4l2_mbus_framefmt *format;
2524 format = __vfe_get_format(line, cfg, fmt->pad, fmt->which);
2525 if (format == NULL)
2526 return -EINVAL;
2528 fmt->format = *format;
2530 return 0;
2533 static int vfe_set_selection(struct v4l2_subdev *sd,
2534 struct v4l2_subdev_pad_config *cfg,
2535 struct v4l2_subdev_selection *sel);
2538 * vfe_set_format - Handle set format by pads subdev method
2539 * @sd: VFE V4L2 subdevice
2540 * @cfg: V4L2 subdev pad configuration
2541 * @fmt: pointer to v4l2 subdev format structure
2543 * Return -EINVAL or zero on success
2545 static int vfe_set_format(struct v4l2_subdev *sd,
2546 struct v4l2_subdev_pad_config *cfg,
2547 struct v4l2_subdev_format *fmt)
2549 struct vfe_line *line = v4l2_get_subdevdata(sd);
2550 struct v4l2_mbus_framefmt *format;
2552 format = __vfe_get_format(line, cfg, fmt->pad, fmt->which);
2553 if (format == NULL)
2554 return -EINVAL;
2556 vfe_try_format(line, cfg, fmt->pad, &fmt->format, fmt->which);
2557 *format = fmt->format;
2559 if (fmt->pad == MSM_VFE_PAD_SINK) {
2560 struct v4l2_subdev_selection sel = { 0 };
2561 int ret;
2563 /* Propagate the format from sink to source */
2564 format = __vfe_get_format(line, cfg, MSM_VFE_PAD_SRC,
2565 fmt->which);
2567 *format = fmt->format;
2568 vfe_try_format(line, cfg, MSM_VFE_PAD_SRC, format,
2569 fmt->which);
2571 if (line->id != VFE_LINE_PIX)
2572 return 0;
2574 /* Reset sink pad compose selection */
2575 sel.which = fmt->which;
2576 sel.pad = MSM_VFE_PAD_SINK;
2577 sel.target = V4L2_SEL_TGT_COMPOSE;
2578 sel.r.width = fmt->format.width;
2579 sel.r.height = fmt->format.height;
2580 ret = vfe_set_selection(sd, cfg, &sel);
2581 if (ret < 0)
2582 return ret;
2585 return 0;
2589 * vfe_get_selection - Handle get selection by pads subdev method
2590 * @sd: VFE V4L2 subdevice
2591 * @cfg: V4L2 subdev pad configuration
2592 * @sel: pointer to v4l2 subdev selection structure
2594 * Return -EINVAL or zero on success
2596 static int vfe_get_selection(struct v4l2_subdev *sd,
2597 struct v4l2_subdev_pad_config *cfg,
2598 struct v4l2_subdev_selection *sel)
2600 struct vfe_line *line = v4l2_get_subdevdata(sd);
2601 struct v4l2_subdev_format fmt = { 0 };
2602 struct v4l2_rect *rect;
2603 int ret;
2605 if (line->id != VFE_LINE_PIX)
2606 return -EINVAL;
2608 if (sel->pad == MSM_VFE_PAD_SINK)
2609 switch (sel->target) {
2610 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
2611 fmt.pad = sel->pad;
2612 fmt.which = sel->which;
2613 ret = vfe_get_format(sd, cfg, &fmt);
2614 if (ret < 0)
2615 return ret;
2617 sel->r.left = 0;
2618 sel->r.top = 0;
2619 sel->r.width = fmt.format.width;
2620 sel->r.height = fmt.format.height;
2621 break;
2622 case V4L2_SEL_TGT_COMPOSE:
2623 rect = __vfe_get_compose(line, cfg, sel->which);
2624 if (rect == NULL)
2625 return -EINVAL;
2627 sel->r = *rect;
2628 break;
2629 default:
2630 return -EINVAL;
2632 else if (sel->pad == MSM_VFE_PAD_SRC)
2633 switch (sel->target) {
2634 case V4L2_SEL_TGT_CROP_BOUNDS:
2635 rect = __vfe_get_compose(line, cfg, sel->which);
2636 if (rect == NULL)
2637 return -EINVAL;
2639 sel->r.left = rect->left;
2640 sel->r.top = rect->top;
2641 sel->r.width = rect->width;
2642 sel->r.height = rect->height;
2643 break;
2644 case V4L2_SEL_TGT_CROP:
2645 rect = __vfe_get_crop(line, cfg, sel->which);
2646 if (rect == NULL)
2647 return -EINVAL;
2649 sel->r = *rect;
2650 break;
2651 default:
2652 return -EINVAL;
2655 return 0;
2659 * vfe_set_selection - Handle set selection by pads subdev method
2660 * @sd: VFE V4L2 subdevice
2661 * @cfg: V4L2 subdev pad configuration
2662 * @sel: pointer to v4l2 subdev selection structure
2664 * Return -EINVAL or zero on success
2666 static int vfe_set_selection(struct v4l2_subdev *sd,
2667 struct v4l2_subdev_pad_config *cfg,
2668 struct v4l2_subdev_selection *sel)
2670 struct vfe_line *line = v4l2_get_subdevdata(sd);
2671 struct v4l2_rect *rect;
2672 int ret;
2674 if (line->id != VFE_LINE_PIX)
2675 return -EINVAL;
2677 if (sel->target == V4L2_SEL_TGT_COMPOSE &&
2678 sel->pad == MSM_VFE_PAD_SINK) {
2679 struct v4l2_subdev_selection crop = { 0 };
2681 rect = __vfe_get_compose(line, cfg, sel->which);
2682 if (rect == NULL)
2683 return -EINVAL;
2685 vfe_try_compose(line, cfg, &sel->r, sel->which);
2686 *rect = sel->r;
2688 /* Reset source crop selection */
2689 crop.which = sel->which;
2690 crop.pad = MSM_VFE_PAD_SRC;
2691 crop.target = V4L2_SEL_TGT_CROP;
2692 crop.r = *rect;
2693 ret = vfe_set_selection(sd, cfg, &crop);
2694 } else if (sel->target == V4L2_SEL_TGT_CROP &&
2695 sel->pad == MSM_VFE_PAD_SRC) {
2696 struct v4l2_subdev_format fmt = { 0 };
2698 rect = __vfe_get_crop(line, cfg, sel->which);
2699 if (rect == NULL)
2700 return -EINVAL;
2702 vfe_try_crop(line, cfg, &sel->r, sel->which);
2703 *rect = sel->r;
2705 /* Reset source pad format width and height */
2706 fmt.which = sel->which;
2707 fmt.pad = MSM_VFE_PAD_SRC;
2708 ret = vfe_get_format(sd, cfg, &fmt);
2709 if (ret < 0)
2710 return ret;
2712 fmt.format.width = rect->width;
2713 fmt.format.height = rect->height;
2714 ret = vfe_set_format(sd, cfg, &fmt);
2715 } else {
2716 ret = -EINVAL;
2719 return ret;
2723 * vfe_init_formats - Initialize formats on all pads
2724 * @sd: VFE V4L2 subdevice
2725 * @fh: V4L2 subdev file handle
2727 * Initialize all pad formats with default values.
2729 * Return 0 on success or a negative error code otherwise
2731 static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2733 struct v4l2_subdev_format format = {
2734 .pad = MSM_VFE_PAD_SINK,
2735 .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
2736 V4L2_SUBDEV_FORMAT_ACTIVE,
2737 .format = {
2738 .code = MEDIA_BUS_FMT_UYVY8_2X8,
2739 .width = 1920,
2740 .height = 1080
2744 return vfe_set_format(sd, fh ? fh->pad : NULL, &format);
2748 * msm_vfe_subdev_init - Initialize VFE device structure and resources
2749 * @vfe: VFE device
2750 * @res: VFE module resources table
2752 * Return 0 on success or a negative error code otherwise
2754 int msm_vfe_subdev_init(struct vfe_device *vfe, const struct resources *res)
2756 struct device *dev = to_device(vfe);
2757 struct platform_device *pdev = to_platform_device(dev);
2758 struct resource *r;
2759 struct camss *camss = to_camss(vfe);
2760 int i, j;
2761 int ret;
2763 /* Memory */
2765 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]);
2766 vfe->base = devm_ioremap_resource(dev, r);
2767 if (IS_ERR(vfe->base)) {
2768 dev_err(dev, "could not map memory\n");
2769 return PTR_ERR(vfe->base);
2772 /* Interrupt */
2774 r = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
2775 res->interrupt[0]);
2776 if (!r) {
2777 dev_err(dev, "missing IRQ\n");
2778 return -EINVAL;
2781 vfe->irq = r->start;
2782 snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d",
2783 dev_name(dev), MSM_VFE_NAME, vfe->id);
2784 ret = devm_request_irq(dev, vfe->irq, vfe_isr,
2785 IRQF_TRIGGER_RISING, vfe->irq_name, vfe);
2786 if (ret < 0) {
2787 dev_err(dev, "request_irq failed: %d\n", ret);
2788 return ret;
2791 /* Clocks */
2793 vfe->nclocks = 0;
2794 while (res->clock[vfe->nclocks])
2795 vfe->nclocks++;
2797 vfe->clock = devm_kzalloc(dev, vfe->nclocks * sizeof(*vfe->clock),
2798 GFP_KERNEL);
2799 if (!vfe->clock)
2800 return -ENOMEM;
2802 for (i = 0; i < vfe->nclocks; i++) {
2803 struct camss_clock *clock = &vfe->clock[i];
2805 clock->clk = devm_clk_get(dev, res->clock[i]);
2806 if (IS_ERR(clock->clk))
2807 return PTR_ERR(clock->clk);
2809 clock->name = res->clock[i];
2811 clock->nfreqs = 0;
2812 while (res->clock_rate[i][clock->nfreqs])
2813 clock->nfreqs++;
2815 if (!clock->nfreqs) {
2816 clock->freq = NULL;
2817 continue;
2820 clock->freq = devm_kzalloc(dev, clock->nfreqs *
2821 sizeof(*clock->freq), GFP_KERNEL);
2822 if (!clock->freq)
2823 return -ENOMEM;
2825 for (j = 0; j < clock->nfreqs; j++)
2826 clock->freq[j] = res->clock_rate[i][j];
2829 mutex_init(&vfe->power_lock);
2830 vfe->power_count = 0;
2832 mutex_init(&vfe->stream_lock);
2833 vfe->stream_count = 0;
2835 spin_lock_init(&vfe->output_lock);
2837 vfe->id = 0;
2838 vfe->reg_update = 0;
2840 for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) {
2841 vfe->line[i].video_out.type =
2842 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2843 vfe->line[i].video_out.camss = camss;
2844 vfe->line[i].id = i;
2845 init_completion(&vfe->line[i].output.sof);
2846 init_completion(&vfe->line[i].output.reg_update);
2849 init_completion(&vfe->reset_complete);
2850 init_completion(&vfe->halt_complete);
2852 return 0;
2856 * msm_vfe_get_vfe_id - Get VFE HW module id
2857 * @entity: Pointer to VFE media entity structure
2858 * @id: Return CSID HW module id here
2860 void msm_vfe_get_vfe_id(struct media_entity *entity, u8 *id)
2862 struct v4l2_subdev *sd;
2863 struct vfe_line *line;
2864 struct vfe_device *vfe;
2866 sd = media_entity_to_v4l2_subdev(entity);
2867 line = v4l2_get_subdevdata(sd);
2868 vfe = to_vfe(line);
2870 *id = vfe->id;
2874 * msm_vfe_get_vfe_line_id - Get VFE line id by media entity
2875 * @entity: Pointer to VFE media entity structure
2876 * @id: Return VFE line id here
2878 void msm_vfe_get_vfe_line_id(struct media_entity *entity, enum vfe_line_id *id)
2880 struct v4l2_subdev *sd;
2881 struct vfe_line *line;
2883 sd = media_entity_to_v4l2_subdev(entity);
2884 line = v4l2_get_subdevdata(sd);
2886 *id = line->id;
2890 * vfe_link_setup - Setup VFE connections
2891 * @entity: Pointer to media entity structure
2892 * @local: Pointer to local pad
2893 * @remote: Pointer to remote pad
2894 * @flags: Link flags
2896 * Return 0 on success
2898 static int vfe_link_setup(struct media_entity *entity,
2899 const struct media_pad *local,
2900 const struct media_pad *remote, u32 flags)
2902 if (flags & MEDIA_LNK_FL_ENABLED)
2903 if (media_entity_remote_pad(local))
2904 return -EBUSY;
2906 return 0;
2909 static const struct v4l2_subdev_core_ops vfe_core_ops = {
2910 .s_power = vfe_set_power,
2913 static const struct v4l2_subdev_video_ops vfe_video_ops = {
2914 .s_stream = vfe_set_stream,
2917 static const struct v4l2_subdev_pad_ops vfe_pad_ops = {
2918 .enum_mbus_code = vfe_enum_mbus_code,
2919 .enum_frame_size = vfe_enum_frame_size,
2920 .get_fmt = vfe_get_format,
2921 .set_fmt = vfe_set_format,
2922 .get_selection = vfe_get_selection,
2923 .set_selection = vfe_set_selection,
2926 static const struct v4l2_subdev_ops vfe_v4l2_ops = {
2927 .core = &vfe_core_ops,
2928 .video = &vfe_video_ops,
2929 .pad = &vfe_pad_ops,
2932 static const struct v4l2_subdev_internal_ops vfe_v4l2_internal_ops = {
2933 .open = vfe_init_formats,
2936 static const struct media_entity_operations vfe_media_ops = {
2937 .link_setup = vfe_link_setup,
2938 .link_validate = v4l2_subdev_link_validate,
2941 static const struct camss_video_ops camss_vfe_video_ops = {
2942 .queue_buffer = vfe_queue_buffer,
2943 .flush_buffers = vfe_flush_buffers,
2946 void msm_vfe_stop_streaming(struct vfe_device *vfe)
2948 int i;
2950 for (i = 0; i < ARRAY_SIZE(vfe->line); i++)
2951 msm_video_stop_streaming(&vfe->line[i].video_out);
2955 * msm_vfe_register_entities - Register subdev node for VFE module
2956 * @vfe: VFE device
2957 * @v4l2_dev: V4L2 device
2959 * Initialize and register a subdev node for the VFE module. Then
2960 * call msm_video_register() to register the video device node which
2961 * will be connected to this subdev node. Then actually create the
2962 * media link between them.
2964 * Return 0 on success or a negative error code otherwise
2966 int msm_vfe_register_entities(struct vfe_device *vfe,
2967 struct v4l2_device *v4l2_dev)
2969 struct device *dev = to_device(vfe);
2970 struct v4l2_subdev *sd;
2971 struct media_pad *pads;
2972 struct camss_video *video_out;
2973 int ret;
2974 int i;
2976 for (i = 0; i < ARRAY_SIZE(vfe->line); i++) {
2977 char name[32];
2979 sd = &vfe->line[i].subdev;
2980 pads = vfe->line[i].pads;
2981 video_out = &vfe->line[i].video_out;
2983 v4l2_subdev_init(sd, &vfe_v4l2_ops);
2984 sd->internal_ops = &vfe_v4l2_internal_ops;
2985 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2986 if (i == VFE_LINE_PIX)
2987 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s",
2988 MSM_VFE_NAME, vfe->id, "pix");
2989 else
2990 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d",
2991 MSM_VFE_NAME, vfe->id, "rdi", i);
2993 v4l2_set_subdevdata(sd, &vfe->line[i]);
2995 ret = vfe_init_formats(sd, NULL);
2996 if (ret < 0) {
2997 dev_err(dev, "Failed to init format: %d\n", ret);
2998 goto error_init;
3001 pads[MSM_VFE_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
3002 pads[MSM_VFE_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
3004 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
3005 sd->entity.ops = &vfe_media_ops;
3006 ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM,
3007 pads);
3008 if (ret < 0) {
3009 dev_err(dev, "Failed to init media entity: %d\n", ret);
3010 goto error_init;
3013 ret = v4l2_device_register_subdev(v4l2_dev, sd);
3014 if (ret < 0) {
3015 dev_err(dev, "Failed to register subdev: %d\n", ret);
3016 goto error_reg_subdev;
3019 video_out->ops = &camss_vfe_video_ops;
3020 video_out->bpl_alignment = 8;
3021 video_out->line_based = 0;
3022 if (i == VFE_LINE_PIX) {
3023 video_out->bpl_alignment = 16;
3024 video_out->line_based = 1;
3026 snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d",
3027 MSM_VFE_NAME, vfe->id, "video", i);
3028 ret = msm_video_register(video_out, v4l2_dev, name,
3029 i == VFE_LINE_PIX ? 1 : 0);
3030 if (ret < 0) {
3031 dev_err(dev, "Failed to register video node: %d\n",
3032 ret);
3033 goto error_reg_video;
3036 ret = media_create_pad_link(
3037 &sd->entity, MSM_VFE_PAD_SRC,
3038 &video_out->vdev.entity, 0,
3039 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
3040 if (ret < 0) {
3041 dev_err(dev, "Failed to link %s->%s entities: %d\n",
3042 sd->entity.name, video_out->vdev.entity.name,
3043 ret);
3044 goto error_link;
3048 return 0;
3050 error_link:
3051 msm_video_unregister(video_out);
3053 error_reg_video:
3054 v4l2_device_unregister_subdev(sd);
3056 error_reg_subdev:
3057 media_entity_cleanup(&sd->entity);
3059 error_init:
3060 for (i--; i >= 0; i--) {
3061 sd = &vfe->line[i].subdev;
3062 video_out = &vfe->line[i].video_out;
3064 msm_video_unregister(video_out);
3065 v4l2_device_unregister_subdev(sd);
3066 media_entity_cleanup(&sd->entity);
3069 return ret;
3073 * msm_vfe_unregister_entities - Unregister VFE module subdev node
3074 * @vfe: VFE device
3076 void msm_vfe_unregister_entities(struct vfe_device *vfe)
3078 int i;
3080 mutex_destroy(&vfe->power_lock);
3081 mutex_destroy(&vfe->stream_lock);
3083 for (i = 0; i < ARRAY_SIZE(vfe->line); i++) {
3084 struct v4l2_subdev *sd = &vfe->line[i].subdev;
3085 struct camss_video *video_out = &vfe->line[i].video_out;
3087 msm_video_unregister(video_out);
3088 v4l2_device_unregister_subdev(sd);
3089 media_entity_cleanup(&sd->entity);