objtool: Re-arrange validate_functions()
[linux-block.git] / drivers / staging / media / rkisp1 / rkisp1-resizer.c
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Rockchip ISP1 Driver - V4l resizer device
4  *
5  * Copyright (C) 2019 Collabora, Ltd.
6  *
7  * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
8  * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
9  */
10
11 #include "rkisp1-common.h"
12
13 #define RKISP1_RSZ_SP_DEV_NAME  RKISP1_DRIVER_NAME "_resizer_selfpath"
14 #define RKISP1_RSZ_MP_DEV_NAME  RKISP1_DRIVER_NAME "_resizer_mainpath"
15
16 #define RKISP1_DEF_FMT MEDIA_BUS_FMT_YUYV8_2X8
17 #define RKISP1_DEF_FMT_TYPE RKISP1_FMT_YUV
18
19 #define RKISP1_MBUS_FMT_HDIV 2
20 #define RKISP1_MBUS_FMT_VDIV 1
21
22 enum rkisp1_shadow_regs_when {
23         RKISP1_SHADOW_REGS_SYNC,
24         RKISP1_SHADOW_REGS_ASYNC,
25 };
26
27 struct rkisp1_rsz_config {
28         /* constrains */
29         const int max_rsz_width;
30         const int max_rsz_height;
31         const int min_rsz_width;
32         const int min_rsz_height;
33         /* registers */
34         struct {
35                 u32 ctrl;
36                 u32 ctrl_shd;
37                 u32 scale_hy;
38                 u32 scale_hcr;
39                 u32 scale_hcb;
40                 u32 scale_vy;
41                 u32 scale_vc;
42                 u32 scale_lut;
43                 u32 scale_lut_addr;
44                 u32 scale_hy_shd;
45                 u32 scale_hcr_shd;
46                 u32 scale_hcb_shd;
47                 u32 scale_vy_shd;
48                 u32 scale_vc_shd;
49                 u32 phase_hy;
50                 u32 phase_hc;
51                 u32 phase_vy;
52                 u32 phase_vc;
53                 u32 phase_hy_shd;
54                 u32 phase_hc_shd;
55                 u32 phase_vy_shd;
56                 u32 phase_vc_shd;
57         } rsz;
58         struct {
59                 u32 ctrl;
60                 u32 yuvmode_mask;
61                 u32 rawmode_mask;
62                 u32 h_offset;
63                 u32 v_offset;
64                 u32 h_size;
65                 u32 v_size;
66         } dual_crop;
67 };
68
69 static const struct rkisp1_rsz_config rkisp1_rsz_config_mp = {
70         /* constraints */
71         .max_rsz_width = RKISP1_RSZ_MP_SRC_MAX_WIDTH,
72         .max_rsz_height = RKISP1_RSZ_MP_SRC_MAX_HEIGHT,
73         .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
74         .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
75         /* registers */
76         .rsz = {
77                 .ctrl =                 RKISP1_CIF_MRSZ_CTRL,
78                 .scale_hy =             RKISP1_CIF_MRSZ_SCALE_HY,
79                 .scale_hcr =            RKISP1_CIF_MRSZ_SCALE_HCR,
80                 .scale_hcb =            RKISP1_CIF_MRSZ_SCALE_HCB,
81                 .scale_vy =             RKISP1_CIF_MRSZ_SCALE_VY,
82                 .scale_vc =             RKISP1_CIF_MRSZ_SCALE_VC,
83                 .scale_lut =            RKISP1_CIF_MRSZ_SCALE_LUT,
84                 .scale_lut_addr =       RKISP1_CIF_MRSZ_SCALE_LUT_ADDR,
85                 .scale_hy_shd =         RKISP1_CIF_MRSZ_SCALE_HY_SHD,
86                 .scale_hcr_shd =        RKISP1_CIF_MRSZ_SCALE_HCR_SHD,
87                 .scale_hcb_shd =        RKISP1_CIF_MRSZ_SCALE_HCB_SHD,
88                 .scale_vy_shd =         RKISP1_CIF_MRSZ_SCALE_VY_SHD,
89                 .scale_vc_shd =         RKISP1_CIF_MRSZ_SCALE_VC_SHD,
90                 .phase_hy =             RKISP1_CIF_MRSZ_PHASE_HY,
91                 .phase_hc =             RKISP1_CIF_MRSZ_PHASE_HC,
92                 .phase_vy =             RKISP1_CIF_MRSZ_PHASE_VY,
93                 .phase_vc =             RKISP1_CIF_MRSZ_PHASE_VC,
94                 .ctrl_shd =             RKISP1_CIF_MRSZ_CTRL_SHD,
95                 .phase_hy_shd =         RKISP1_CIF_MRSZ_PHASE_HY_SHD,
96                 .phase_hc_shd =         RKISP1_CIF_MRSZ_PHASE_HC_SHD,
97                 .phase_vy_shd =         RKISP1_CIF_MRSZ_PHASE_VY_SHD,
98                 .phase_vc_shd =         RKISP1_CIF_MRSZ_PHASE_VC_SHD,
99         },
100         .dual_crop = {
101                 .ctrl =                 RKISP1_CIF_DUAL_CROP_CTRL,
102                 .yuvmode_mask =         RKISP1_CIF_DUAL_CROP_MP_MODE_YUV,
103                 .rawmode_mask =         RKISP1_CIF_DUAL_CROP_MP_MODE_RAW,
104                 .h_offset =             RKISP1_CIF_DUAL_CROP_M_H_OFFS,
105                 .v_offset =             RKISP1_CIF_DUAL_CROP_M_V_OFFS,
106                 .h_size =               RKISP1_CIF_DUAL_CROP_M_H_SIZE,
107                 .v_size =               RKISP1_CIF_DUAL_CROP_M_V_SIZE,
108         },
109 };
110
111 static const struct rkisp1_rsz_config rkisp1_rsz_config_sp = {
112         /* constraints */
113         .max_rsz_width = RKISP1_RSZ_SP_SRC_MAX_WIDTH,
114         .max_rsz_height = RKISP1_RSZ_SP_SRC_MAX_HEIGHT,
115         .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
116         .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
117         /* registers */
118         .rsz = {
119                 .ctrl =                 RKISP1_CIF_SRSZ_CTRL,
120                 .scale_hy =             RKISP1_CIF_SRSZ_SCALE_HY,
121                 .scale_hcr =            RKISP1_CIF_SRSZ_SCALE_HCR,
122                 .scale_hcb =            RKISP1_CIF_SRSZ_SCALE_HCB,
123                 .scale_vy =             RKISP1_CIF_SRSZ_SCALE_VY,
124                 .scale_vc =             RKISP1_CIF_SRSZ_SCALE_VC,
125                 .scale_lut =            RKISP1_CIF_SRSZ_SCALE_LUT,
126                 .scale_lut_addr =       RKISP1_CIF_SRSZ_SCALE_LUT_ADDR,
127                 .scale_hy_shd =         RKISP1_CIF_SRSZ_SCALE_HY_SHD,
128                 .scale_hcr_shd =        RKISP1_CIF_SRSZ_SCALE_HCR_SHD,
129                 .scale_hcb_shd =        RKISP1_CIF_SRSZ_SCALE_HCB_SHD,
130                 .scale_vy_shd =         RKISP1_CIF_SRSZ_SCALE_VY_SHD,
131                 .scale_vc_shd =         RKISP1_CIF_SRSZ_SCALE_VC_SHD,
132                 .phase_hy =             RKISP1_CIF_SRSZ_PHASE_HY,
133                 .phase_hc =             RKISP1_CIF_SRSZ_PHASE_HC,
134                 .phase_vy =             RKISP1_CIF_SRSZ_PHASE_VY,
135                 .phase_vc =             RKISP1_CIF_SRSZ_PHASE_VC,
136                 .ctrl_shd =             RKISP1_CIF_SRSZ_CTRL_SHD,
137                 .phase_hy_shd =         RKISP1_CIF_SRSZ_PHASE_HY_SHD,
138                 .phase_hc_shd =         RKISP1_CIF_SRSZ_PHASE_HC_SHD,
139                 .phase_vy_shd =         RKISP1_CIF_SRSZ_PHASE_VY_SHD,
140                 .phase_vc_shd =         RKISP1_CIF_SRSZ_PHASE_VC_SHD,
141         },
142         .dual_crop = {
143                 .ctrl =                 RKISP1_CIF_DUAL_CROP_CTRL,
144                 .yuvmode_mask =         RKISP1_CIF_DUAL_CROP_SP_MODE_YUV,
145                 .rawmode_mask =         RKISP1_CIF_DUAL_CROP_SP_MODE_RAW,
146                 .h_offset =             RKISP1_CIF_DUAL_CROP_S_H_OFFS,
147                 .v_offset =             RKISP1_CIF_DUAL_CROP_S_V_OFFS,
148                 .h_size =               RKISP1_CIF_DUAL_CROP_S_H_SIZE,
149                 .v_size =               RKISP1_CIF_DUAL_CROP_S_V_SIZE,
150         },
151 };
152
153 static struct v4l2_mbus_framefmt *
154 rkisp1_rsz_get_pad_fmt(struct rkisp1_resizer *rsz,
155                        struct v4l2_subdev_pad_config *cfg,
156                        unsigned int pad, u32 which)
157 {
158         if (which == V4L2_SUBDEV_FORMAT_TRY)
159                 return v4l2_subdev_get_try_format(&rsz->sd, cfg, pad);
160         else
161                 return v4l2_subdev_get_try_format(&rsz->sd, rsz->pad_cfg, pad);
162 }
163
164 static struct v4l2_rect *
165 rkisp1_rsz_get_pad_crop(struct rkisp1_resizer *rsz,
166                         struct v4l2_subdev_pad_config *cfg,
167                         unsigned int pad, u32 which)
168 {
169         if (which == V4L2_SUBDEV_FORMAT_TRY)
170                 return v4l2_subdev_get_try_crop(&rsz->sd, cfg, pad);
171         else
172                 return v4l2_subdev_get_try_crop(&rsz->sd, rsz->pad_cfg, pad);
173 }
174
175 /* ----------------------------------------------------------------------------
176  * Dual crop hw configs
177  */
178
179 static void rkisp1_dcrop_disable(struct rkisp1_resizer *rsz,
180                                  enum rkisp1_shadow_regs_when when)
181 {
182         u32 dc_ctrl = rkisp1_read(rsz->rkisp1, rsz->config->dual_crop.ctrl);
183         u32 mask = ~(rsz->config->dual_crop.yuvmode_mask |
184                      rsz->config->dual_crop.rawmode_mask);
185
186         dc_ctrl &= mask;
187         if (when == RKISP1_SHADOW_REGS_ASYNC)
188                 dc_ctrl |= RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD;
189         else
190                 dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
191         rkisp1_write(rsz->rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl);
192 }
193
194 /* configure dual-crop unit */
195 static void rkisp1_dcrop_config(struct rkisp1_resizer *rsz)
196 {
197         struct rkisp1_device *rkisp1 = rsz->rkisp1;
198         struct v4l2_mbus_framefmt *sink_fmt;
199         struct v4l2_rect *sink_crop;
200         u32 dc_ctrl;
201
202         sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
203                                             V4L2_SUBDEV_FORMAT_ACTIVE);
204         sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
205                                           V4L2_SUBDEV_FORMAT_ACTIVE);
206
207         if (sink_crop->width == sink_fmt->width &&
208             sink_crop->height == sink_fmt->height &&
209             sink_crop->left == 0 && sink_crop->top == 0) {
210                 rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_SYNC);
211                 dev_dbg(rkisp1->dev, "capture %d crop disabled\n", rsz->id);
212                 return;
213         }
214
215         dc_ctrl = rkisp1_read(rkisp1, rsz->config->dual_crop.ctrl);
216         rkisp1_write(rkisp1, sink_crop->left, rsz->config->dual_crop.h_offset);
217         rkisp1_write(rkisp1, sink_crop->top, rsz->config->dual_crop.v_offset);
218         rkisp1_write(rkisp1, sink_crop->width, rsz->config->dual_crop.h_size);
219         rkisp1_write(rkisp1, sink_crop->height, rsz->config->dual_crop.v_size);
220         dc_ctrl |= rsz->config->dual_crop.yuvmode_mask;
221         dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
222         rkisp1_write(rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl);
223
224         dev_dbg(rkisp1->dev, "stream %d crop: %dx%d -> %dx%d\n", rsz->id,
225                 sink_fmt->width, sink_fmt->height,
226                 sink_crop->width, sink_crop->height);
227 }
228
229 /* ----------------------------------------------------------------------------
230  * Resizer hw configs
231  */
232
233 static void rkisp1_rsz_dump_regs(struct rkisp1_resizer *rsz)
234 {
235         dev_dbg(rsz->rkisp1->dev,
236                 "RSZ_CTRL 0x%08x/0x%08x\n"
237                 "RSZ_SCALE_HY %d/%d\n"
238                 "RSZ_SCALE_HCB %d/%d\n"
239                 "RSZ_SCALE_HCR %d/%d\n"
240                 "RSZ_SCALE_VY %d/%d\n"
241                 "RSZ_SCALE_VC %d/%d\n"
242                 "RSZ_PHASE_HY %d/%d\n"
243                 "RSZ_PHASE_HC %d/%d\n"
244                 "RSZ_PHASE_VY %d/%d\n"
245                 "RSZ_PHASE_VC %d/%d\n",
246                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl),
247                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl_shd),
248                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy),
249                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy_shd),
250                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb),
251                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb_shd),
252                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr),
253                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr_shd),
254                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy),
255                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy_shd),
256                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc),
257                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc_shd),
258                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy),
259                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy_shd),
260                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc),
261                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc_shd),
262                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy),
263                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy_shd),
264                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc),
265                 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc_shd));
266 }
267
268 static void rkisp1_rsz_update_shadow(struct rkisp1_resizer *rsz,
269                                      enum rkisp1_shadow_regs_when when)
270 {
271         u32 ctrl_cfg = rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl);
272
273         if (when == RKISP1_SHADOW_REGS_ASYNC)
274                 ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO;
275         else
276                 ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD;
277
278         rkisp1_write(rsz->rkisp1, ctrl_cfg, rsz->config->rsz.ctrl);
279 }
280
281 static u32 rkisp1_rsz_calc_ratio(u32 len_sink, u32 len_src)
282 {
283         if (len_sink < len_src)
284                 return ((len_sink - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
285                        (len_src - 1);
286
287         return ((len_src - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
288                (len_sink - 1) + 1;
289 }
290
291 static void rkisp1_rsz_disable(struct rkisp1_resizer *rsz,
292                                enum rkisp1_shadow_regs_when when)
293 {
294         rkisp1_write(rsz->rkisp1, 0, rsz->config->rsz.ctrl);
295
296         if (when == RKISP1_SHADOW_REGS_SYNC)
297                 rkisp1_rsz_update_shadow(rsz, when);
298 }
299
300 static void rkisp1_rsz_config_regs(struct rkisp1_resizer *rsz,
301                                    struct v4l2_rect *sink_y,
302                                    struct v4l2_rect *sink_c,
303                                    struct v4l2_rect *src_y,
304                                    struct v4l2_rect *src_c,
305                                    enum rkisp1_shadow_regs_when when)
306 {
307         struct rkisp1_device *rkisp1 = rsz->rkisp1;
308         u32 ratio, rsz_ctrl = 0;
309         unsigned int i;
310
311         /* No phase offset */
312         rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hy);
313         rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hc);
314         rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vy);
315         rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vc);
316
317         /* Linear interpolation */
318         for (i = 0; i < 64; i++) {
319                 rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut_addr);
320                 rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut);
321         }
322
323         if (sink_y->width != src_y->width) {
324                 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE;
325                 if (sink_y->width < src_y->width)
326                         rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP;
327                 ratio = rkisp1_rsz_calc_ratio(sink_y->width, src_y->width);
328                 rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hy);
329         }
330
331         if (sink_c->width != src_c->width) {
332                 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE;
333                 if (sink_c->width < src_c->width)
334                         rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP;
335                 ratio = rkisp1_rsz_calc_ratio(sink_c->width, src_c->width);
336                 rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcb);
337                 rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcr);
338         }
339
340         if (sink_y->height != src_y->height) {
341                 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE;
342                 if (sink_y->height < src_y->height)
343                         rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP;
344                 ratio = rkisp1_rsz_calc_ratio(sink_y->height, src_y->height);
345                 rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vy);
346         }
347
348         if (sink_c->height != src_c->height) {
349                 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE;
350                 if (sink_c->height < src_c->height)
351                         rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP;
352                 ratio = rkisp1_rsz_calc_ratio(sink_c->height, src_c->height);
353                 rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vc);
354         }
355
356         rkisp1_write(rkisp1, rsz_ctrl, rsz->config->rsz.ctrl);
357
358         rkisp1_rsz_update_shadow(rsz, when);
359 }
360
361 static void rkisp1_rsz_config(struct rkisp1_resizer *rsz,
362                               enum rkisp1_shadow_regs_when when)
363 {
364         u8 hdiv = RKISP1_MBUS_FMT_HDIV, vdiv = RKISP1_MBUS_FMT_VDIV;
365         struct v4l2_rect sink_y, sink_c, src_y, src_c;
366         struct v4l2_mbus_framefmt *src_fmt;
367         struct v4l2_rect *sink_crop;
368
369         sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
370                                             V4L2_SUBDEV_FORMAT_ACTIVE);
371         src_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SRC,
372                                          V4L2_SUBDEV_FORMAT_ACTIVE);
373
374         if (rsz->fmt_type == RKISP1_FMT_BAYER) {
375                 rkisp1_rsz_disable(rsz, when);
376                 return;
377         }
378
379         sink_y.width = sink_crop->width;
380         sink_y.height = sink_crop->height;
381         src_y.width = src_fmt->width;
382         src_y.height = src_fmt->height;
383
384         sink_c.width = sink_y.width / RKISP1_MBUS_FMT_HDIV;
385         sink_c.height = sink_y.height / RKISP1_MBUS_FMT_VDIV;
386
387         if (rsz->fmt_type == RKISP1_FMT_YUV) {
388                 struct rkisp1_capture *cap =
389                         &rsz->rkisp1->capture_devs[rsz->id];
390                 const struct v4l2_format_info *pixfmt_info =
391                         v4l2_format_info(cap->pix.fmt.pixelformat);
392
393                 hdiv = pixfmt_info->hdiv;
394                 vdiv = pixfmt_info->vdiv;
395         }
396         src_c.width = src_y.width / hdiv;
397         src_c.height = src_y.height / vdiv;
398
399         if (sink_c.width == src_c.width && sink_c.height == src_c.height) {
400                 rkisp1_rsz_disable(rsz, when);
401                 return;
402         }
403
404         dev_dbg(rsz->rkisp1->dev, "stream %d rsz/scale: %dx%d -> %dx%d\n",
405                 rsz->id, sink_crop->width, sink_crop->height,
406                 src_fmt->width, src_fmt->height);
407         dev_dbg(rsz->rkisp1->dev, "chroma scaling %dx%d -> %dx%d\n",
408                 sink_c.width, sink_c.height, src_c.width, src_c.height);
409
410         /* set values in the hw */
411         rkisp1_rsz_config_regs(rsz, &sink_y, &sink_c, &src_y, &src_c, when);
412
413         rkisp1_rsz_dump_regs(rsz);
414 }
415
416 /* ----------------------------------------------------------------------------
417  * Subdev pad operations
418  */
419
420 static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd,
421                                      struct v4l2_subdev_pad_config *cfg,
422                                      struct v4l2_subdev_mbus_code_enum *code)
423 {
424         struct rkisp1_resizer *rsz =
425                 container_of(sd, struct rkisp1_resizer, sd);
426         struct v4l2_subdev_pad_config dummy_cfg;
427         u32 pad = code->pad;
428         int ret;
429
430         /* supported mbus codes are the same in isp sink pad */
431         code->pad = RKISP1_ISP_PAD_SINK_VIDEO;
432         ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code,
433                                &dummy_cfg, code);
434
435         /* restore pad */
436         code->pad = pad;
437         return ret;
438 }
439
440 static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
441                                   struct v4l2_subdev_pad_config *cfg)
442 {
443         struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
444         struct v4l2_rect *sink_crop;
445
446         sink_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SRC);
447         sink_fmt->width = RKISP1_DEFAULT_WIDTH;
448         sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
449         sink_fmt->field = V4L2_FIELD_NONE;
450         sink_fmt->code = RKISP1_DEF_FMT;
451
452         sink_crop = v4l2_subdev_get_try_crop(sd, cfg, RKISP1_RSZ_PAD_SINK);
453         sink_crop->width = RKISP1_DEFAULT_WIDTH;
454         sink_crop->height = RKISP1_DEFAULT_HEIGHT;
455         sink_crop->left = 0;
456         sink_crop->top = 0;
457
458         src_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SINK);
459         *src_fmt = *sink_fmt;
460
461         /* NOTE: there is no crop in the source pad, only in the sink */
462
463         return 0;
464 }
465
466 static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz,
467                                    struct v4l2_subdev_pad_config *cfg,
468                                    struct v4l2_mbus_framefmt *format,
469                                    unsigned int which)
470 {
471         struct v4l2_mbus_framefmt *src_fmt;
472
473         src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which);
474         src_fmt->width = clamp_t(u32, format->width,
475                                  rsz->config->min_rsz_width,
476                                  rsz->config->max_rsz_width);
477         src_fmt->height = clamp_t(u32, format->height,
478                                   rsz->config->min_rsz_height,
479                                   rsz->config->max_rsz_height);
480
481         *format = *src_fmt;
482 }
483
484 static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
485                                      struct v4l2_subdev_pad_config *cfg,
486                                      struct v4l2_rect *r,
487                                      unsigned int which)
488 {
489         const struct rkisp1_isp_mbus_info *mbus_info;
490         struct v4l2_mbus_framefmt *sink_fmt;
491         struct v4l2_rect *sink_crop;
492
493         sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which);
494         sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
495                                             which);
496
497         /* Not crop for MP bayer raw data */
498         mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
499
500         if (rsz->id == RKISP1_MAINPATH &&
501             mbus_info->fmt_type == RKISP1_FMT_BAYER) {
502                 sink_crop->left = 0;
503                 sink_crop->top = 0;
504                 sink_crop->width = sink_fmt->width;
505                 sink_crop->height = sink_fmt->height;
506                 return;
507         }
508
509         sink_crop->left = ALIGN(r->left, 2);
510         sink_crop->width = ALIGN(r->width, 2);
511         sink_crop->top = r->top;
512         sink_crop->height = r->height;
513         rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
514
515         *r = *sink_crop;
516 }
517
518 static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
519                                     struct v4l2_subdev_pad_config *cfg,
520                                     struct v4l2_mbus_framefmt *format,
521                                     unsigned int which)
522 {
523         const struct rkisp1_isp_mbus_info *mbus_info;
524         struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
525         struct v4l2_rect *sink_crop;
526
527         sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which);
528         src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which);
529         sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
530                                             which);
531         sink_fmt->code = format->code;
532         mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
533         if (!mbus_info) {
534                 sink_fmt->code = RKISP1_DEF_FMT;
535                 mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
536         }
537         if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
538                 rsz->fmt_type = mbus_info->fmt_type;
539
540         if (rsz->id == RKISP1_MAINPATH &&
541             mbus_info->fmt_type == RKISP1_FMT_BAYER) {
542                 sink_crop->left = 0;
543                 sink_crop->top = 0;
544                 sink_crop->width = sink_fmt->width;
545                 sink_crop->height = sink_fmt->height;
546                 return;
547         }
548
549         /* Propagete to source pad */
550         src_fmt->code = sink_fmt->code;
551
552         sink_fmt->width = clamp_t(u32, format->width,
553                                   rsz->config->min_rsz_width,
554                                   rsz->config->max_rsz_width);
555         sink_fmt->height = clamp_t(u32, format->height,
556                                    rsz->config->min_rsz_height,
557                                    rsz->config->max_rsz_height);
558
559         *format = *sink_fmt;
560
561         /* Update sink crop */
562         rkisp1_rsz_set_sink_crop(rsz, cfg, sink_crop, which);
563 }
564
565 static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd,
566                               struct v4l2_subdev_pad_config *cfg,
567                               struct v4l2_subdev_format *fmt)
568 {
569         struct rkisp1_resizer *rsz =
570                 container_of(sd, struct rkisp1_resizer, sd);
571
572         fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, cfg, fmt->pad, fmt->which);
573         return 0;
574 }
575
576 static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd,
577                               struct v4l2_subdev_pad_config *cfg,
578                               struct v4l2_subdev_format *fmt)
579 {
580         struct rkisp1_resizer *rsz =
581                 container_of(sd, struct rkisp1_resizer, sd);
582
583         if (fmt->pad == RKISP1_RSZ_PAD_SINK)
584                 rkisp1_rsz_set_sink_fmt(rsz, cfg, &fmt->format, fmt->which);
585         else
586                 rkisp1_rsz_set_src_fmt(rsz, cfg, &fmt->format, fmt->which);
587
588         return 0;
589 }
590
591 static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd,
592                                     struct v4l2_subdev_pad_config *cfg,
593                                     struct v4l2_subdev_selection *sel)
594 {
595         struct rkisp1_resizer *rsz =
596                 container_of(sd, struct rkisp1_resizer, sd);
597         struct v4l2_mbus_framefmt *mf_sink;
598
599         if (sel->pad == RKISP1_RSZ_PAD_SRC)
600                 return -EINVAL;
601
602         switch (sel->target) {
603         case V4L2_SEL_TGT_CROP_BOUNDS:
604                 mf_sink = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK,
605                                                  sel->which);
606                 sel->r.height = mf_sink->height;
607                 sel->r.width = mf_sink->width;
608                 sel->r.left = 0;
609                 sel->r.top = 0;
610                 break;
611         case V4L2_SEL_TGT_CROP:
612                 sel->r = *rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
613                                                   sel->which);
614                 break;
615         default:
616                 return -EINVAL;
617         }
618
619         return 0;
620 }
621
622 static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd,
623                                     struct v4l2_subdev_pad_config *cfg,
624                                     struct v4l2_subdev_selection *sel)
625 {
626         struct rkisp1_resizer *rsz =
627                 container_of(sd, struct rkisp1_resizer, sd);
628
629         if (sel->target != V4L2_SEL_TGT_CROP || sel->pad == RKISP1_RSZ_PAD_SRC)
630                 return -EINVAL;
631
632         dev_dbg(sd->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
633                 sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
634
635         rkisp1_rsz_set_sink_crop(rsz, cfg, &sel->r, sel->which);
636
637         return 0;
638 }
639
640 static const struct media_entity_operations rkisp1_rsz_media_ops = {
641         .link_validate = v4l2_subdev_link_validate,
642 };
643
644 static const struct v4l2_subdev_pad_ops rkisp1_rsz_pad_ops = {
645         .enum_mbus_code = rkisp1_rsz_enum_mbus_code,
646         .get_selection = rkisp1_rsz_get_selection,
647         .set_selection = rkisp1_rsz_set_selection,
648         .init_cfg = rkisp1_rsz_init_config,
649         .get_fmt = rkisp1_rsz_get_fmt,
650         .set_fmt = rkisp1_rsz_set_fmt,
651         .link_validate = v4l2_subdev_link_validate_default,
652 };
653
654 /* ----------------------------------------------------------------------------
655  * Stream operations
656  */
657
658 static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
659 {
660         struct rkisp1_resizer *rsz =
661                 container_of(sd, struct rkisp1_resizer, sd);
662         struct rkisp1_device *rkisp1 = rsz->rkisp1;
663         struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1];
664         enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC;
665
666         if (!enable) {
667                 rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
668                 rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
669                 return 0;
670         }
671
672         if (other->is_streaming)
673                 when = RKISP1_SHADOW_REGS_ASYNC;
674
675         rkisp1_rsz_config(rsz, when);
676         rkisp1_dcrop_config(rsz);
677
678         return 0;
679 }
680
681 static const struct v4l2_subdev_video_ops rkisp1_rsz_video_ops = {
682         .s_stream = rkisp1_rsz_s_stream,
683 };
684
685 static const struct v4l2_subdev_ops rkisp1_rsz_ops = {
686         .video = &rkisp1_rsz_video_ops,
687         .pad = &rkisp1_rsz_pad_ops,
688 };
689
690 static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz)
691 {
692         v4l2_device_unregister_subdev(&rsz->sd);
693         media_entity_cleanup(&rsz->sd.entity);
694 }
695
696 static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
697 {
698         const char * const dev_names[] = {RKISP1_RSZ_MP_DEV_NAME,
699                                           RKISP1_RSZ_SP_DEV_NAME};
700         struct media_pad *pads = rsz->pads;
701         struct v4l2_subdev *sd = &rsz->sd;
702         int ret;
703
704         if (rsz->id == RKISP1_SELFPATH)
705                 rsz->config = &rkisp1_rsz_config_sp;
706         else
707                 rsz->config = &rkisp1_rsz_config_mp;
708
709         v4l2_subdev_init(sd, &rkisp1_rsz_ops);
710         sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
711         sd->entity.ops = &rkisp1_rsz_media_ops;
712         sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
713         sd->owner = THIS_MODULE;
714         strscpy(sd->name, dev_names[rsz->id], sizeof(sd->name));
715
716         pads[RKISP1_RSZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
717                                           MEDIA_PAD_FL_MUST_CONNECT;
718         pads[RKISP1_RSZ_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE |
719                                          MEDIA_PAD_FL_MUST_CONNECT;
720
721         rsz->fmt_type = RKISP1_DEF_FMT_TYPE;
722
723         ret = media_entity_pads_init(&sd->entity, 2, pads);
724         if (ret)
725                 return ret;
726
727         ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd);
728         if (ret) {
729                 dev_err(sd->dev, "Failed to register resizer subdev\n");
730                 goto err_cleanup_media_entity;
731         }
732
733         rkisp1_rsz_init_config(sd, rsz->pad_cfg);
734         return 0;
735
736 err_cleanup_media_entity:
737         media_entity_cleanup(&sd->entity);
738
739         return ret;
740 }
741
742 int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
743 {
744         struct rkisp1_resizer *rsz;
745         unsigned int i, j;
746         int ret;
747
748         for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
749                 rsz = &rkisp1->resizer_devs[i];
750                 rsz->rkisp1 = rkisp1;
751                 rsz->id = i;
752                 ret = rkisp1_rsz_register(rsz);
753                 if (ret)
754                         goto err_unreg_resizer_devs;
755         }
756
757         return 0;
758
759 err_unreg_resizer_devs:
760         for (j = 0; j < i; j++) {
761                 rsz = &rkisp1->resizer_devs[j];
762                 rkisp1_rsz_unregister(rsz);
763         }
764
765         return ret;
766 }
767
768 void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1)
769 {
770         struct rkisp1_resizer *mp = &rkisp1->resizer_devs[RKISP1_MAINPATH];
771         struct rkisp1_resizer *sp = &rkisp1->resizer_devs[RKISP1_SELFPATH];
772
773         rkisp1_rsz_unregister(mp);
774         rkisp1_rsz_unregister(sp);
775 }