GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / media / platform / qcom / camss / camss-vfe-4-1.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * camss-vfe-4-1.c
4  *
5  * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.1
6  *
7  * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
8  * Copyright (C) 2015-2018 Linaro Ltd.
9  */
10
11 #include <linux/interrupt.h>
12 #include <linux/io.h>
13 #include <linux/iopoll.h>
14
15 #include "camss-vfe.h"
16
17 #define VFE_0_HW_VERSION                0x000
18
19 #define VFE_0_GLOBAL_RESET_CMD          0x00c
20 #define VFE_0_GLOBAL_RESET_CMD_CORE     BIT(0)
21 #define VFE_0_GLOBAL_RESET_CMD_CAMIF    BIT(1)
22 #define VFE_0_GLOBAL_RESET_CMD_BUS      BIT(2)
23 #define VFE_0_GLOBAL_RESET_CMD_BUS_BDG  BIT(3)
24 #define VFE_0_GLOBAL_RESET_CMD_REGISTER BIT(4)
25 #define VFE_0_GLOBAL_RESET_CMD_TIMER    BIT(5)
26 #define VFE_0_GLOBAL_RESET_CMD_PM       BIT(6)
27 #define VFE_0_GLOBAL_RESET_CMD_BUS_MISR BIT(7)
28 #define VFE_0_GLOBAL_RESET_CMD_TESTGEN  BIT(8)
29
30 #define VFE_0_MODULE_CFG                0x018
31 #define VFE_0_MODULE_CFG_DEMUX                  BIT(2)
32 #define VFE_0_MODULE_CFG_CHROMA_UPSAMPLE        BIT(3)
33 #define VFE_0_MODULE_CFG_SCALE_ENC              BIT(23)
34 #define VFE_0_MODULE_CFG_CROP_ENC               BIT(27)
35
36 #define VFE_0_CORE_CFG                  0x01c
37 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR     0x4
38 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB     0x5
39 #define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY     0x6
40 #define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY     0x7
41
42 #define VFE_0_IRQ_CMD                   0x024
43 #define VFE_0_IRQ_CMD_GLOBAL_CLEAR      BIT(0)
44
45 #define VFE_0_IRQ_MASK_0                0x028
46 #define VFE_0_IRQ_MASK_0_CAMIF_SOF                      BIT(0)
47 #define VFE_0_IRQ_MASK_0_CAMIF_EOF                      BIT(1)
48 #define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)             BIT((n) + 5)
49 #define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n)           \
50         ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n))
51 #define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n)    BIT((n) + 8)
52 #define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n)      BIT((n) + 25)
53 #define VFE_0_IRQ_MASK_0_RESET_ACK                      BIT(31)
54 #define VFE_0_IRQ_MASK_1                0x02c
55 #define VFE_0_IRQ_MASK_1_CAMIF_ERROR                    BIT(0)
56 #define VFE_0_IRQ_MASK_1_VIOLATION                      BIT(7)
57 #define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK               BIT(8)
58 #define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) BIT((n) + 9)
59 #define VFE_0_IRQ_MASK_1_RDIn_SOF(n)                    BIT((n) + 29)
60
61 #define VFE_0_IRQ_CLEAR_0               0x030
62 #define VFE_0_IRQ_CLEAR_1               0x034
63
64 #define VFE_0_IRQ_STATUS_0              0x038
65 #define VFE_0_IRQ_STATUS_0_CAMIF_SOF                    BIT(0)
66 #define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)           BIT((n) + 5)
67 #define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n)         \
68         ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n))
69 #define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n)  BIT((n) + 8)
70 #define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n)    BIT((n) + 25)
71 #define VFE_0_IRQ_STATUS_0_RESET_ACK                    BIT(31)
72 #define VFE_0_IRQ_STATUS_1              0x03c
73 #define VFE_0_IRQ_STATUS_1_VIOLATION                    BIT(7)
74 #define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK             BIT(8)
75 #define VFE_0_IRQ_STATUS_1_RDIn_SOF(n)                  BIT((n) + 29)
76
77 #define VFE_0_IRQ_COMPOSITE_MASK_0      0x40
78 #define VFE_0_VIOLATION_STATUS          0x48
79
80 #define VFE_0_BUS_CMD                   0x4c
81 #define VFE_0_BUS_CMD_Mx_RLD_CMD(x)     BIT(x)
82
83 #define VFE_0_BUS_CFG                   0x050
84
85 #define VFE_0_BUS_XBAR_CFG_x(x)         (0x58 + 0x4 * ((x) / 2))
86 #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN                   BIT(1)
87 #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA     (0x3 << 4)
88 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT          8
89 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA           0
90 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0       5
91 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1       6
92 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2       7
93
94 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n)              (0x06c + 0x24 * (n))
95 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT   0
96 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT 1
97 #define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n)        (0x070 + 0x24 * (n))
98 #define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n)        (0x074 + 0x24 * (n))
99 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n)         (0x078 + 0x24 * (n))
100 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT 2
101 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK  (0x1f << 2)
102
103 #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n)           (0x07c + 0x24 * (n))
104 #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT 16
105 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n)       (0x080 + 0x24 * (n))
106 #define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n)       (0x084 + 0x24 * (n))
107 #define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n)        \
108                                                         (0x088 + 0x24 * (n))
109 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n)    \
110                                                         (0x08c + 0x24 * (n))
111 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF   0xffffffff
112
113 #define VFE_0_BUS_PING_PONG_STATUS      0x268
114
115 #define VFE_0_BUS_BDG_CMD               0x2c0
116 #define VFE_0_BUS_BDG_CMD_HALT_REQ      1
117
118 #define VFE_0_BUS_BDG_QOS_CFG_0         0x2c4
119 #define VFE_0_BUS_BDG_QOS_CFG_0_CFG     0xaaa5aaa5
120 #define VFE_0_BUS_BDG_QOS_CFG_1         0x2c8
121 #define VFE_0_BUS_BDG_QOS_CFG_2         0x2cc
122 #define VFE_0_BUS_BDG_QOS_CFG_3         0x2d0
123 #define VFE_0_BUS_BDG_QOS_CFG_4         0x2d4
124 #define VFE_0_BUS_BDG_QOS_CFG_5         0x2d8
125 #define VFE_0_BUS_BDG_QOS_CFG_6         0x2dc
126 #define VFE_0_BUS_BDG_QOS_CFG_7         0x2e0
127 #define VFE_0_BUS_BDG_QOS_CFG_7_CFG     0x0001aaa5
128
129 #define VFE_0_RDI_CFG_x(x)              (0x2e8 + (0x4 * (x)))
130 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT    28
131 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK     (0xf << 28)
132 #define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT        4
133 #define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK         (0xf << 4)
134 #define VFE_0_RDI_CFG_x_RDI_EN_BIT              BIT(2)
135 #define VFE_0_RDI_CFG_x_MIPI_EN_BITS            0x3
136 #define VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(r)        BIT(16 + (r))
137
138 #define VFE_0_CAMIF_CMD                         0x2f4
139 #define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY  0
140 #define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY   1
141 #define VFE_0_CAMIF_CMD_NO_CHANGE               3
142 #define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS      BIT(2)
143 #define VFE_0_CAMIF_CFG                         0x2f8
144 #define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN           BIT(6)
145 #define VFE_0_CAMIF_FRAME_CFG                   0x300
146 #define VFE_0_CAMIF_WINDOW_WIDTH_CFG            0x304
147 #define VFE_0_CAMIF_WINDOW_HEIGHT_CFG           0x308
148 #define VFE_0_CAMIF_SUBSAMPLE_CFG_0             0x30c
149 #define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN       0x314
150 #define VFE_0_CAMIF_STATUS                      0x31c
151 #define VFE_0_CAMIF_STATUS_HALT                 BIT(31)
152
153 #define VFE_0_REG_UPDATE                        0x378
154 #define VFE_0_REG_UPDATE_RDIn(n)                BIT(1 + (n))
155 #define VFE_0_REG_UPDATE_line_n(n)              \
156                         ((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n))
157
158 #define VFE_0_DEMUX_CFG                         0x424
159 #define VFE_0_DEMUX_CFG_PERIOD                  0x3
160 #define VFE_0_DEMUX_GAIN_0                      0x428
161 #define VFE_0_DEMUX_GAIN_0_CH0_EVEN             (0x80 << 0)
162 #define VFE_0_DEMUX_GAIN_0_CH0_ODD              (0x80 << 16)
163 #define VFE_0_DEMUX_GAIN_1                      0x42c
164 #define VFE_0_DEMUX_GAIN_1_CH1                  (0x80 << 0)
165 #define VFE_0_DEMUX_GAIN_1_CH2                  (0x80 << 16)
166 #define VFE_0_DEMUX_EVEN_CFG                    0x438
167 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV       0x9cac
168 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU       0xac9c
169 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY       0xc9ca
170 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY       0xcac9
171 #define VFE_0_DEMUX_ODD_CFG                     0x43c
172 #define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV        0x9cac
173 #define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU        0xac9c
174 #define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY        0xc9ca
175 #define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY        0xcac9
176
177 #define VFE_0_SCALE_ENC_Y_CFG                   0x75c
178 #define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE          0x760
179 #define VFE_0_SCALE_ENC_Y_H_PHASE               0x764
180 #define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE          0x76c
181 #define VFE_0_SCALE_ENC_Y_V_PHASE               0x770
182 #define VFE_0_SCALE_ENC_CBCR_CFG                0x778
183 #define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE       0x77c
184 #define VFE_0_SCALE_ENC_CBCR_H_PHASE            0x780
185 #define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE       0x790
186 #define VFE_0_SCALE_ENC_CBCR_V_PHASE            0x794
187
188 #define VFE_0_CROP_ENC_Y_WIDTH                  0x854
189 #define VFE_0_CROP_ENC_Y_HEIGHT                 0x858
190 #define VFE_0_CROP_ENC_CBCR_WIDTH               0x85c
191 #define VFE_0_CROP_ENC_CBCR_HEIGHT              0x860
192
193 #define VFE_0_CLAMP_ENC_MAX_CFG                 0x874
194 #define VFE_0_CLAMP_ENC_MAX_CFG_CH0             (0xff << 0)
195 #define VFE_0_CLAMP_ENC_MAX_CFG_CH1             (0xff << 8)
196 #define VFE_0_CLAMP_ENC_MAX_CFG_CH2             (0xff << 16)
197 #define VFE_0_CLAMP_ENC_MIN_CFG                 0x878
198 #define VFE_0_CLAMP_ENC_MIN_CFG_CH0             (0x0 << 0)
199 #define VFE_0_CLAMP_ENC_MIN_CFG_CH1             (0x0 << 8)
200 #define VFE_0_CLAMP_ENC_MIN_CFG_CH2             (0x0 << 16)
201
202 #define VFE_0_CGC_OVERRIDE_1                    0x974
203 #define VFE_0_CGC_OVERRIDE_1_IMAGE_Mx_CGC_OVERRIDE(x)   BIT(x)
204
205 #define CAMIF_TIMEOUT_SLEEP_US 1000
206 #define CAMIF_TIMEOUT_ALL_US 1000000
207
208 #define MSM_VFE_VFE0_UB_SIZE 1023
209 #define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3)
210
211 static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev)
212 {
213         u32 hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION);
214
215         dev_dbg(dev, "VFE HW Version = 0x%08x\n", hw_version);
216 }
217
218 static u16 vfe_get_ub_size(u8 vfe_id)
219 {
220         if (vfe_id == 0)
221                 return MSM_VFE_VFE0_UB_SIZE_RDI;
222
223         return 0;
224 }
225
226 static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)
227 {
228         u32 bits = readl_relaxed(vfe->base + reg);
229
230         writel_relaxed(bits & ~clr_bits, vfe->base + reg);
231 }
232
233 static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
234 {
235         u32 bits = readl_relaxed(vfe->base + reg);
236
237         writel_relaxed(bits | set_bits, vfe->base + reg);
238 }
239
240 static void vfe_global_reset(struct vfe_device *vfe)
241 {
242         u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_TESTGEN         |
243                          VFE_0_GLOBAL_RESET_CMD_BUS_MISR        |
244                          VFE_0_GLOBAL_RESET_CMD_PM              |
245                          VFE_0_GLOBAL_RESET_CMD_TIMER           |
246                          VFE_0_GLOBAL_RESET_CMD_REGISTER        |
247                          VFE_0_GLOBAL_RESET_CMD_BUS_BDG         |
248                          VFE_0_GLOBAL_RESET_CMD_BUS             |
249                          VFE_0_GLOBAL_RESET_CMD_CAMIF           |
250                          VFE_0_GLOBAL_RESET_CMD_CORE;
251
252         writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD);
253 }
254
255 static void vfe_halt_request(struct vfe_device *vfe)
256 {
257         writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ,
258                        vfe->base + VFE_0_BUS_BDG_CMD);
259 }
260
261 static void vfe_halt_clear(struct vfe_device *vfe)
262 {
263         writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD);
264 }
265
266 static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)
267 {
268         if (enable)
269                 vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
270                             1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT);
271         else
272                 vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
273                             1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT);
274 }
275
276 static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable)
277 {
278         if (enable)
279                 vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
280                         1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT);
281         else
282                 vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
283                         1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT);
284 }
285
286 #define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N))
287
288 static int vfe_word_per_line(u32 format, u32 pixel_per_line)
289 {
290         int val = 0;
291
292         switch (format) {
293         case V4L2_PIX_FMT_NV12:
294         case V4L2_PIX_FMT_NV21:
295         case V4L2_PIX_FMT_NV16:
296         case V4L2_PIX_FMT_NV61:
297                 val = CALC_WORD(pixel_per_line, 1, 8);
298                 break;
299         case V4L2_PIX_FMT_YUYV:
300         case V4L2_PIX_FMT_YVYU:
301         case V4L2_PIX_FMT_UYVY:
302         case V4L2_PIX_FMT_VYUY:
303                 val = CALC_WORD(pixel_per_line, 2, 8);
304                 break;
305         }
306
307         return val;
308 }
309
310 static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane,
311                              u16 *width, u16 *height, u16 *bytesperline)
312 {
313         switch (pix->pixelformat) {
314         case V4L2_PIX_FMT_NV12:
315         case V4L2_PIX_FMT_NV21:
316                 *width = pix->width;
317                 *height = pix->height;
318                 *bytesperline = pix->plane_fmt[0].bytesperline;
319                 if (plane == 1)
320                         *height /= 2;
321                 break;
322         case V4L2_PIX_FMT_NV16:
323         case V4L2_PIX_FMT_NV61:
324                 *width = pix->width;
325                 *height = pix->height;
326                 *bytesperline = pix->plane_fmt[0].bytesperline;
327                 break;
328         }
329 }
330
331 static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm,
332                               struct v4l2_pix_format_mplane *pix,
333                               u8 plane, u32 enable)
334 {
335         u32 reg;
336
337         if (enable) {
338                 u16 width = 0, height = 0, bytesperline = 0, wpl;
339
340                 vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline);
341
342                 wpl = vfe_word_per_line(pix->pixelformat, width);
343
344                 reg = height - 1;
345                 reg |= ((wpl + 1) / 2 - 1) << 16;
346
347                 writel_relaxed(reg, vfe->base +
348                                VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
349
350                 wpl = vfe_word_per_line(pix->pixelformat, bytesperline);
351
352                 reg = 0x3;
353                 reg |= (height - 1) << 4;
354                 reg |= wpl << 16;
355
356                 writel_relaxed(reg, vfe->base +
357                                VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
358         } else {
359                 writel_relaxed(0, vfe->base +
360                                VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
361                 writel_relaxed(0, vfe->base +
362                                VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
363         }
364 }
365
366 static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per)
367 {
368         u32 reg;
369
370         reg = readl_relaxed(vfe->base +
371                             VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
372
373         reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK);
374
375         reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT)
376                 & VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK;
377
378         writel_relaxed(reg,
379                        vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
380 }
381
382 static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm,
383                                          u32 pattern)
384 {
385         writel_relaxed(pattern,
386                vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm));
387 }
388
389 static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm,
390                               u16 offset, u16 depth)
391 {
392         u32 reg;
393
394         reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) |
395                 depth;
396         writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm));
397 }
398
399 static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm)
400 {
401         wmb();
402         writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD);
403         wmb();
404 }
405
406 static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr)
407 {
408         writel_relaxed(addr,
409                        vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm));
410 }
411
412 static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr)
413 {
414         writel_relaxed(addr,
415                        vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm));
416 }
417
418 static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm)
419 {
420         u32 reg;
421
422         reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS);
423
424         return (reg >> wm) & 0x1;
425 }
426
427 static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable)
428 {
429         if (enable)
430                 writel_relaxed(0x10000009, vfe->base + VFE_0_BUS_CFG);
431         else
432                 writel_relaxed(0, vfe->base + VFE_0_BUS_CFG);
433 }
434
435 static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm,
436                                       enum vfe_line_id id)
437 {
438         u32 reg;
439
440         reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
441         reg |= VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(id);
442         vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg);
443
444         reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
445         reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) &
446                 VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK;
447         vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg);
448
449         switch (id) {
450         case VFE_LINE_RDI0:
451         default:
452                 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
453                       VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
454                 break;
455         case VFE_LINE_RDI1:
456                 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
457                       VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
458                 break;
459         case VFE_LINE_RDI2:
460                 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
461                       VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
462                 break;
463         }
464
465         if (wm % 2 == 1)
466                 reg <<= 16;
467
468         vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
469 }
470
471 static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm)
472 {
473         writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF,
474                        vfe->base +
475                        VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm));
476 }
477
478 static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm,
479                                            enum vfe_line_id id)
480 {
481         u32 reg;
482
483         reg = VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(id);
484         vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(0), reg);
485
486         reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
487         vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg);
488
489         switch (id) {
490         case VFE_LINE_RDI0:
491         default:
492                 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
493                       VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
494                 break;
495         case VFE_LINE_RDI1:
496                 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
497                       VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
498                 break;
499         case VFE_LINE_RDI2:
500                 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
501                       VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
502                 break;
503         }
504
505         if (wm % 2 == 1)
506                 reg <<= 16;
507
508         vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
509 }
510
511 static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output,
512                              u8 enable)
513 {
514         struct vfe_line *line = container_of(output, struct vfe_line, output);
515         u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
516         u32 reg;
517         unsigned int i;
518
519         for (i = 0; i < output->wm_num; i++) {
520                 if (i == 0) {
521                         reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA <<
522                                 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
523                 } else if (i == 1) {
524                         reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
525                         if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16)
526                                 reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
527                 } else {
528                         /* On current devices output->wm_num is always <= 2 */
529                         break;
530                 }
531
532                 if (output->wm_idx[i] % 2 == 1)
533                         reg <<= 16;
534
535                 if (enable)
536                         vfe_reg_set(vfe,
537                                     VFE_0_BUS_XBAR_CFG_x(output->wm_idx[i]),
538                                     reg);
539                 else
540                         vfe_reg_clr(vfe,
541                                     VFE_0_BUS_XBAR_CFG_x(output->wm_idx[i]),
542                                     reg);
543         }
544 }
545
546 static void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line,
547                                 u8 enable)
548 {
549         /* empty */
550 }
551 static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid)
552 {
553         vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id),
554                     VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK);
555
556         vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id),
557                     cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT);
558 }
559
560 static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
561 {
562         vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id);
563         wmb();
564         writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE);
565         wmb();
566 }
567
568 static inline void vfe_reg_update_clear(struct vfe_device *vfe,
569                                         enum vfe_line_id line_id)
570 {
571         vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id);
572 }
573
574 static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm,
575                                    enum vfe_line_id line_id, u8 enable)
576 {
577         u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) |
578                       VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
579         u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) |
580                       VFE_0_IRQ_MASK_1_RDIn_SOF(line_id);
581
582         if (enable) {
583                 vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
584                 vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
585         } else {
586                 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
587                 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
588         }
589 }
590
591 static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp,
592                                     enum vfe_line_id line_id, u8 enable)
593 {
594         struct vfe_output *output = &vfe->line[line_id].output;
595         unsigned int i;
596         u32 irq_en0;
597         u32 irq_en1;
598         u32 comp_mask = 0;
599
600         irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF;
601         irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF;
602         irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp);
603         irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
604         irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR;
605         for (i = 0; i < output->wm_num; i++) {
606                 irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(
607                                                         output->wm_idx[i]);
608                 comp_mask |= (1 << output->wm_idx[i]) << comp * 8;
609         }
610
611         if (enable) {
612                 vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
613                 vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
614                 vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
615         } else {
616                 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
617                 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
618                 vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
619         }
620 }
621
622 static void vfe_enable_irq_common(struct vfe_device *vfe)
623 {
624         u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK;
625         u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION |
626                       VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK;
627
628         vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
629         vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
630 }
631
632 static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)
633 {
634         u32 val, even_cfg, odd_cfg;
635
636         writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG);
637
638         val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD;
639         writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0);
640
641         val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2;
642         writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);
643
644         switch (line->fmt[MSM_VFE_PAD_SINK].code) {
645         case MEDIA_BUS_FMT_YUYV8_2X8:
646                 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;
647                 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;
648                 break;
649         case MEDIA_BUS_FMT_YVYU8_2X8:
650                 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;
651                 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;
652                 break;
653         case MEDIA_BUS_FMT_UYVY8_2X8:
654         default:
655                 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;
656                 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;
657                 break;
658         case MEDIA_BUS_FMT_VYUY8_2X8:
659                 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;
660                 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;
661                 break;
662         }
663
664         writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG);
665         writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG);
666 }
667
668 static inline u8 vfe_calc_interp_reso(u16 input, u16 output)
669 {
670         if (input / output >= 16)
671                 return 0;
672
673         if (input / output >= 8)
674                 return 1;
675
676         if (input / output >= 4)
677                 return 2;
678
679         return 3;
680 }
681
682 static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line)
683 {
684         u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
685         u32 reg;
686         u16 input, output;
687         u8 interp_reso;
688         u32 phase_mult;
689
690         writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG);
691
692         input = line->fmt[MSM_VFE_PAD_SINK].width;
693         output = line->compose.width;
694         reg = (output << 16) | input;
695         writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE);
696
697         interp_reso = vfe_calc_interp_reso(input, output);
698         phase_mult = input * (1 << (13 + interp_reso)) / output;
699         reg = (interp_reso << 20) | phase_mult;
700         writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE);
701
702         input = line->fmt[MSM_VFE_PAD_SINK].height;
703         output = line->compose.height;
704         reg = (output << 16) | input;
705         writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE);
706
707         interp_reso = vfe_calc_interp_reso(input, output);
708         phase_mult = input * (1 << (13 + interp_reso)) / output;
709         reg = (interp_reso << 20) | phase_mult;
710         writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE);
711
712         writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG);
713
714         input = line->fmt[MSM_VFE_PAD_SINK].width;
715         output = line->compose.width / 2;
716         reg = (output << 16) | input;
717         writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE);
718
719         interp_reso = vfe_calc_interp_reso(input, output);
720         phase_mult = input * (1 << (13 + interp_reso)) / output;
721         reg = (interp_reso << 20) | phase_mult;
722         writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE);
723
724         input = line->fmt[MSM_VFE_PAD_SINK].height;
725         output = line->compose.height;
726         if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21)
727                 output = line->compose.height / 2;
728         reg = (output << 16) | input;
729         writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE);
730
731         interp_reso = vfe_calc_interp_reso(input, output);
732         phase_mult = input * (1 << (13 + interp_reso)) / output;
733         reg = (interp_reso << 20) | phase_mult;
734         writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE);
735 }
736
737 static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line)
738 {
739         u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
740         u32 reg;
741         u16 first, last;
742
743         first = line->crop.left;
744         last = line->crop.left + line->crop.width - 1;
745         reg = (first << 16) | last;
746         writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH);
747
748         first = line->crop.top;
749         last = line->crop.top + line->crop.height - 1;
750         reg = (first << 16) | last;
751         writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT);
752
753         first = line->crop.left / 2;
754         last = line->crop.left / 2 + line->crop.width / 2 - 1;
755         reg = (first << 16) | last;
756         writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH);
757
758         first = line->crop.top;
759         last = line->crop.top + line->crop.height - 1;
760         if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) {
761                 first = line->crop.top / 2;
762                 last = line->crop.top / 2 + line->crop.height / 2 - 1;
763         }
764         reg = (first << 16) | last;
765         writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT);
766 }
767
768 static void vfe_set_clamp_cfg(struct vfe_device *vfe)
769 {
770         u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 |
771                 VFE_0_CLAMP_ENC_MAX_CFG_CH1 |
772                 VFE_0_CLAMP_ENC_MAX_CFG_CH2;
773
774         writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG);
775
776         val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 |
777                 VFE_0_CLAMP_ENC_MIN_CFG_CH1 |
778                 VFE_0_CLAMP_ENC_MIN_CFG_CH2;
779
780         writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG);
781 }
782
783 static void vfe_set_qos(struct vfe_device *vfe)
784 {
785         u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG;
786         u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG;
787
788         writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0);
789         writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1);
790         writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2);
791         writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3);
792         writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4);
793         writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5);
794         writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6);
795         writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);
796 }
797
798 static void vfe_set_ds(struct vfe_device *vfe)
799 {
800         /* empty */
801 }
802
803 static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable)
804 {
805         u32 val = VFE_0_CGC_OVERRIDE_1_IMAGE_Mx_CGC_OVERRIDE(wm);
806
807         if (enable)
808                 vfe_reg_set(vfe, VFE_0_CGC_OVERRIDE_1, val);
809         else
810                 vfe_reg_clr(vfe, VFE_0_CGC_OVERRIDE_1, val);
811
812         wmb();
813 }
814
815 static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)
816 {
817         u32 val;
818
819         switch (line->fmt[MSM_VFE_PAD_SINK].code) {
820         case MEDIA_BUS_FMT_YUYV8_2X8:
821                 val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;
822                 break;
823         case MEDIA_BUS_FMT_YVYU8_2X8:
824                 val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;
825                 break;
826         case MEDIA_BUS_FMT_UYVY8_2X8:
827         default:
828                 val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;
829                 break;
830         case MEDIA_BUS_FMT_VYUY8_2X8:
831                 val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;
832                 break;
833         }
834
835         writel_relaxed(val, vfe->base + VFE_0_CORE_CFG);
836
837         val = line->fmt[MSM_VFE_PAD_SINK].width * 2;
838         val |= line->fmt[MSM_VFE_PAD_SINK].height << 16;
839         writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG);
840
841         val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
842         writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG);
843
844         val = line->fmt[MSM_VFE_PAD_SINK].height - 1;
845         writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG);
846
847         val = 0xffffffff;
848         writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG_0);
849
850         val = 0xffffffff;
851         writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN);
852
853         val = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
854         vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val);
855
856         val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN;
857         writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG);
858 }
859
860 static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable)
861 {
862         u32 cmd;
863
864         cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE;
865         writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
866         wmb();
867
868         if (enable)
869                 cmd = VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY;
870         else
871                 cmd = VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY;
872
873         writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
874 }
875
876 static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable)
877 {
878         u32 val = VFE_0_MODULE_CFG_DEMUX |
879                   VFE_0_MODULE_CFG_CHROMA_UPSAMPLE |
880                   VFE_0_MODULE_CFG_SCALE_ENC |
881                   VFE_0_MODULE_CFG_CROP_ENC;
882
883         if (enable)
884                 writel_relaxed(val, vfe->base + VFE_0_MODULE_CFG);
885         else
886                 writel_relaxed(0x0, vfe->base + VFE_0_MODULE_CFG);
887 }
888
889 static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)
890 {
891         u32 val;
892         int ret;
893
894         ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS,
895                                  val,
896                                  (val & VFE_0_CAMIF_STATUS_HALT),
897                                  CAMIF_TIMEOUT_SLEEP_US,
898                                  CAMIF_TIMEOUT_ALL_US);
899         if (ret < 0)
900                 dev_err(dev, "%s: camif stop timeout\n", __func__);
901
902         return ret;
903 }
904
905 static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
906 {
907         *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
908         *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
909
910         writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
911         writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
912
913         wmb();
914         writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
915 }
916
917 static void vfe_violation_read(struct vfe_device *vfe)
918 {
919         u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
920
921         pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
922 }
923
924 /*
925  * vfe_isr - ISPIF module interrupt handler
926  * @irq: Interrupt line
927  * @dev: VFE device
928  *
929  * Return IRQ_HANDLED on success
930  */
931 static irqreturn_t vfe_isr(int irq, void *dev)
932 {
933         struct vfe_device *vfe = dev;
934         u32 value0, value1;
935         int i, j;
936
937         vfe->ops->isr_read(vfe, &value0, &value1);
938
939         trace_printk("VFE: status0 = 0x%08x, status1 = 0x%08x\n",
940                      value0, value1);
941
942         if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
943                 vfe->isr_ops.reset_ack(vfe);
944
945         if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
946                 vfe->ops->violation_read(vfe);
947
948         if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
949                 vfe->isr_ops.halt_ack(vfe);
950
951         for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++)
952                 if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
953                         vfe->isr_ops.reg_update(vfe, i);
954
955         if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
956                 vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
957
958         for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
959                 if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
960                         vfe->isr_ops.sof(vfe, i);
961
962         for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
963                 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
964                         vfe->isr_ops.comp_done(vfe, i);
965                         for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
966                                 if (vfe->wm_output_map[j] == VFE_LINE_PIX)
967                                         value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
968                 }
969
970         for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
971                 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
972                         vfe->isr_ops.wm_done(vfe, i);
973
974         return IRQ_HANDLED;
975 }
976
977 const struct vfe_hw_ops vfe_ops_4_1 = {
978         .hw_version_read = vfe_hw_version_read,
979         .get_ub_size = vfe_get_ub_size,
980         .global_reset = vfe_global_reset,
981         .halt_request = vfe_halt_request,
982         .halt_clear = vfe_halt_clear,
983         .wm_enable = vfe_wm_enable,
984         .wm_frame_based = vfe_wm_frame_based,
985         .wm_line_based = vfe_wm_line_based,
986         .wm_set_framedrop_period = vfe_wm_set_framedrop_period,
987         .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern,
988         .wm_set_ub_cfg = vfe_wm_set_ub_cfg,
989         .bus_reload_wm = vfe_bus_reload_wm,
990         .wm_set_ping_addr = vfe_wm_set_ping_addr,
991         .wm_set_pong_addr = vfe_wm_set_pong_addr,
992         .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status,
993         .bus_enable_wr_if = vfe_bus_enable_wr_if,
994         .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
995         .wm_set_subsample = vfe_wm_set_subsample,
996         .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
997         .set_xbar_cfg = vfe_set_xbar_cfg,
998         .set_realign_cfg = vfe_set_realign_cfg,
999         .set_rdi_cid = vfe_set_rdi_cid,
1000         .reg_update = vfe_reg_update,
1001         .reg_update_clear = vfe_reg_update_clear,
1002         .enable_irq_wm_line = vfe_enable_irq_wm_line,
1003         .enable_irq_pix_line = vfe_enable_irq_pix_line,
1004         .enable_irq_common = vfe_enable_irq_common,
1005         .set_demux_cfg = vfe_set_demux_cfg,
1006         .set_scale_cfg = vfe_set_scale_cfg,
1007         .set_crop_cfg = vfe_set_crop_cfg,
1008         .set_clamp_cfg = vfe_set_clamp_cfg,
1009         .set_qos = vfe_set_qos,
1010         .set_ds = vfe_set_ds,
1011         .set_cgc_override = vfe_set_cgc_override,
1012         .set_camif_cfg = vfe_set_camif_cfg,
1013         .set_camif_cmd = vfe_set_camif_cmd,
1014         .set_module_cfg = vfe_set_module_cfg,
1015         .camif_wait_for_stop = vfe_camif_wait_for_stop,
1016         .isr_read = vfe_isr_read,
1017         .violation_read = vfe_violation_read,
1018         .isr = vfe_isr,
1019 };