]> Git Repo - linux.git/blob - drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
net: bgmac: Fix return value check for fixed_phy_register()
[linux.git] / drivers / media / platform / rockchip / 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_PIXEL_ENC V4L2_PIXEL_ENC_YUV
18
19 struct rkisp1_rsz_yuv_mbus_info {
20         u32 mbus_code;
21         u32 hdiv;
22         u32 vdiv;
23 };
24
25 static const struct rkisp1_rsz_yuv_mbus_info rkisp1_rsz_yuv_src_formats[] = {
26         {
27                 .mbus_code      = MEDIA_BUS_FMT_YUYV8_2X8, /* YUV422 */
28                 .hdiv           = 2,
29                 .vdiv           = 1,
30         },
31         {
32                 .mbus_code      = MEDIA_BUS_FMT_YUYV8_1_5X8, /* YUV420 */
33                 .hdiv           = 2,
34                 .vdiv           = 2,
35         },
36 };
37
38 static const struct rkisp1_rsz_yuv_mbus_info *rkisp1_rsz_get_yuv_mbus_info(u32 mbus_code)
39 {
40         unsigned int i;
41
42         for (i = 0; i < ARRAY_SIZE(rkisp1_rsz_yuv_src_formats); i++) {
43                 if (rkisp1_rsz_yuv_src_formats[i].mbus_code == mbus_code)
44                         return &rkisp1_rsz_yuv_src_formats[i];
45         }
46
47         return NULL;
48 }
49
50 enum rkisp1_shadow_regs_when {
51         RKISP1_SHADOW_REGS_SYNC,
52         RKISP1_SHADOW_REGS_ASYNC,
53 };
54
55 struct rkisp1_rsz_config {
56         /* constrains */
57         const int max_rsz_width;
58         const int max_rsz_height;
59         const int min_rsz_width;
60         const int min_rsz_height;
61         /* registers */
62         struct {
63                 u32 ctrl;
64                 u32 yuvmode_mask;
65                 u32 rawmode_mask;
66                 u32 h_offset;
67                 u32 v_offset;
68                 u32 h_size;
69                 u32 v_size;
70         } dual_crop;
71 };
72
73 static const struct rkisp1_rsz_config rkisp1_rsz_config_mp = {
74         /* constraints */
75         .max_rsz_width = RKISP1_RSZ_MP_SRC_MAX_WIDTH,
76         .max_rsz_height = RKISP1_RSZ_MP_SRC_MAX_HEIGHT,
77         .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
78         .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
79         /* registers */
80         .dual_crop = {
81                 .ctrl =                 RKISP1_CIF_DUAL_CROP_CTRL,
82                 .yuvmode_mask =         RKISP1_CIF_DUAL_CROP_MP_MODE_YUV,
83                 .rawmode_mask =         RKISP1_CIF_DUAL_CROP_MP_MODE_RAW,
84                 .h_offset =             RKISP1_CIF_DUAL_CROP_M_H_OFFS,
85                 .v_offset =             RKISP1_CIF_DUAL_CROP_M_V_OFFS,
86                 .h_size =               RKISP1_CIF_DUAL_CROP_M_H_SIZE,
87                 .v_size =               RKISP1_CIF_DUAL_CROP_M_V_SIZE,
88         },
89 };
90
91 static const struct rkisp1_rsz_config rkisp1_rsz_config_sp = {
92         /* constraints */
93         .max_rsz_width = RKISP1_RSZ_SP_SRC_MAX_WIDTH,
94         .max_rsz_height = RKISP1_RSZ_SP_SRC_MAX_HEIGHT,
95         .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
96         .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
97         /* registers */
98         .dual_crop = {
99                 .ctrl =                 RKISP1_CIF_DUAL_CROP_CTRL,
100                 .yuvmode_mask =         RKISP1_CIF_DUAL_CROP_SP_MODE_YUV,
101                 .rawmode_mask =         RKISP1_CIF_DUAL_CROP_SP_MODE_RAW,
102                 .h_offset =             RKISP1_CIF_DUAL_CROP_S_H_OFFS,
103                 .v_offset =             RKISP1_CIF_DUAL_CROP_S_V_OFFS,
104                 .h_size =               RKISP1_CIF_DUAL_CROP_S_H_SIZE,
105                 .v_size =               RKISP1_CIF_DUAL_CROP_S_V_SIZE,
106         },
107 };
108
109 static inline u32 rkisp1_rsz_read(struct rkisp1_resizer *rsz, u32 offset)
110 {
111         return rkisp1_read(rsz->rkisp1, rsz->regs_base + offset);
112 }
113
114 static inline void rkisp1_rsz_write(struct rkisp1_resizer *rsz, u32 offset,
115                                     u32 value)
116 {
117         rkisp1_write(rsz->rkisp1, rsz->regs_base + offset, value);
118 }
119
120 static struct v4l2_mbus_framefmt *
121 rkisp1_rsz_get_pad_fmt(struct rkisp1_resizer *rsz,
122                        struct v4l2_subdev_state *sd_state,
123                        unsigned int pad, u32 which)
124 {
125         struct v4l2_subdev_state state = {
126                 .pads = rsz->pad_cfg,
127         };
128         if (which == V4L2_SUBDEV_FORMAT_TRY)
129                 return v4l2_subdev_get_try_format(&rsz->sd, sd_state, pad);
130         else
131                 return v4l2_subdev_get_try_format(&rsz->sd, &state, pad);
132 }
133
134 static struct v4l2_rect *
135 rkisp1_rsz_get_pad_crop(struct rkisp1_resizer *rsz,
136                         struct v4l2_subdev_state *sd_state,
137                         unsigned int pad, u32 which)
138 {
139         struct v4l2_subdev_state state = {
140                 .pads = rsz->pad_cfg,
141         };
142         if (which == V4L2_SUBDEV_FORMAT_TRY)
143                 return v4l2_subdev_get_try_crop(&rsz->sd, sd_state, pad);
144         else
145                 return v4l2_subdev_get_try_crop(&rsz->sd, &state, pad);
146 }
147
148 /* ----------------------------------------------------------------------------
149  * Dual crop hw configs
150  */
151
152 static void rkisp1_dcrop_disable(struct rkisp1_resizer *rsz,
153                                  enum rkisp1_shadow_regs_when when)
154 {
155         u32 dc_ctrl = rkisp1_read(rsz->rkisp1, rsz->config->dual_crop.ctrl);
156         u32 mask = ~(rsz->config->dual_crop.yuvmode_mask |
157                      rsz->config->dual_crop.rawmode_mask);
158
159         dc_ctrl &= mask;
160         if (when == RKISP1_SHADOW_REGS_ASYNC)
161                 dc_ctrl |= RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD;
162         else
163                 dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
164         rkisp1_write(rsz->rkisp1, rsz->config->dual_crop.ctrl, dc_ctrl);
165 }
166
167 /* configure dual-crop unit */
168 static void rkisp1_dcrop_config(struct rkisp1_resizer *rsz)
169 {
170         struct rkisp1_device *rkisp1 = rsz->rkisp1;
171         struct v4l2_mbus_framefmt *sink_fmt;
172         struct v4l2_rect *sink_crop;
173         u32 dc_ctrl;
174
175         sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
176                                             V4L2_SUBDEV_FORMAT_ACTIVE);
177         sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
178                                           V4L2_SUBDEV_FORMAT_ACTIVE);
179
180         if (sink_crop->width == sink_fmt->width &&
181             sink_crop->height == sink_fmt->height &&
182             sink_crop->left == 0 && sink_crop->top == 0) {
183                 rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_SYNC);
184                 dev_dbg(rkisp1->dev, "capture %d crop disabled\n", rsz->id);
185                 return;
186         }
187
188         dc_ctrl = rkisp1_read(rkisp1, rsz->config->dual_crop.ctrl);
189         rkisp1_write(rkisp1, rsz->config->dual_crop.h_offset, sink_crop->left);
190         rkisp1_write(rkisp1, rsz->config->dual_crop.v_offset, sink_crop->top);
191         rkisp1_write(rkisp1, rsz->config->dual_crop.h_size, sink_crop->width);
192         rkisp1_write(rkisp1, rsz->config->dual_crop.v_size, sink_crop->height);
193         dc_ctrl |= rsz->config->dual_crop.yuvmode_mask;
194         dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
195         rkisp1_write(rkisp1, rsz->config->dual_crop.ctrl, dc_ctrl);
196
197         dev_dbg(rkisp1->dev, "stream %d crop: %dx%d -> %dx%d\n", rsz->id,
198                 sink_fmt->width, sink_fmt->height,
199                 sink_crop->width, sink_crop->height);
200 }
201
202 /* ----------------------------------------------------------------------------
203  * Resizer hw configs
204  */
205
206 static void rkisp1_rsz_update_shadow(struct rkisp1_resizer *rsz,
207                                      enum rkisp1_shadow_regs_when when)
208 {
209         u32 ctrl_cfg = rkisp1_rsz_read(rsz, RKISP1_CIF_RSZ_CTRL);
210
211         if (when == RKISP1_SHADOW_REGS_ASYNC)
212                 ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO;
213         else
214                 ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD;
215
216         rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_CTRL, ctrl_cfg);
217 }
218
219 static u32 rkisp1_rsz_calc_ratio(u32 len_sink, u32 len_src)
220 {
221         if (len_sink < len_src)
222                 return ((len_sink - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
223                        (len_src - 1);
224
225         return ((len_src - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
226                (len_sink - 1) + 1;
227 }
228
229 static void rkisp1_rsz_disable(struct rkisp1_resizer *rsz,
230                                enum rkisp1_shadow_regs_when when)
231 {
232         rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_CTRL, 0);
233
234         if (when == RKISP1_SHADOW_REGS_SYNC)
235                 rkisp1_rsz_update_shadow(rsz, when);
236 }
237
238 static void rkisp1_rsz_config_regs(struct rkisp1_resizer *rsz,
239                                    struct v4l2_rect *sink_y,
240                                    struct v4l2_rect *sink_c,
241                                    struct v4l2_rect *src_y,
242                                    struct v4l2_rect *src_c,
243                                    enum rkisp1_shadow_regs_when when)
244 {
245         u32 ratio, rsz_ctrl = 0;
246         unsigned int i;
247
248         /* No phase offset */
249         rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_PHASE_HY, 0);
250         rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_PHASE_HC, 0);
251         rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_PHASE_VY, 0);
252         rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_PHASE_VC, 0);
253
254         /* Linear interpolation */
255         for (i = 0; i < 64; i++) {
256                 rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_SCALE_LUT_ADDR, i);
257                 rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_SCALE_LUT, i);
258         }
259
260         if (sink_y->width != src_y->width) {
261                 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE;
262                 if (sink_y->width < src_y->width)
263                         rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP;
264                 ratio = rkisp1_rsz_calc_ratio(sink_y->width, src_y->width);
265                 rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_SCALE_HY, ratio);
266         }
267
268         if (sink_c->width != src_c->width) {
269                 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE;
270                 if (sink_c->width < src_c->width)
271                         rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP;
272                 ratio = rkisp1_rsz_calc_ratio(sink_c->width, src_c->width);
273                 rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_SCALE_HCB, ratio);
274                 rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_SCALE_HCR, ratio);
275         }
276
277         if (sink_y->height != src_y->height) {
278                 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE;
279                 if (sink_y->height < src_y->height)
280                         rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP;
281                 ratio = rkisp1_rsz_calc_ratio(sink_y->height, src_y->height);
282                 rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_SCALE_VY, ratio);
283         }
284
285         if (sink_c->height != src_c->height) {
286                 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE;
287                 if (sink_c->height < src_c->height)
288                         rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP;
289                 ratio = rkisp1_rsz_calc_ratio(sink_c->height, src_c->height);
290                 rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_SCALE_VC, ratio);
291         }
292
293         rkisp1_rsz_write(rsz, RKISP1_CIF_RSZ_CTRL, rsz_ctrl);
294
295         rkisp1_rsz_update_shadow(rsz, when);
296 }
297
298 static void rkisp1_rsz_config(struct rkisp1_resizer *rsz,
299                               enum rkisp1_shadow_regs_when when)
300 {
301         const struct rkisp1_rsz_yuv_mbus_info *sink_yuv_info, *src_yuv_info;
302         struct v4l2_rect sink_y, sink_c, src_y, src_c;
303         struct v4l2_mbus_framefmt *src_fmt, *sink_fmt;
304         struct v4l2_rect *sink_crop;
305
306         sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
307                                             V4L2_SUBDEV_FORMAT_ACTIVE);
308         src_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SRC,
309                                          V4L2_SUBDEV_FORMAT_ACTIVE);
310         src_yuv_info = rkisp1_rsz_get_yuv_mbus_info(src_fmt->code);
311         sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
312                                           V4L2_SUBDEV_FORMAT_ACTIVE);
313         sink_yuv_info = rkisp1_rsz_get_yuv_mbus_info(sink_fmt->code);
314
315         /*
316          * The resizer only works on yuv formats,
317          * so return if it is bayer format.
318          */
319         if (rsz->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
320                 rkisp1_rsz_disable(rsz, when);
321                 return;
322         }
323
324         sink_y.width = sink_crop->width;
325         sink_y.height = sink_crop->height;
326         src_y.width = src_fmt->width;
327         src_y.height = src_fmt->height;
328
329         sink_c.width = sink_y.width / sink_yuv_info->hdiv;
330         sink_c.height = sink_y.height / sink_yuv_info->vdiv;
331
332         /*
333          * The resizer is used not only to change the dimensions of the frame
334          * but also to change the scale for YUV formats,
335          * (4:2:2 -> 4:2:0 for example). So the width/height of the CbCr
336          * streams should be set according to the media bus format in the src pad.
337          */
338         src_c.width = src_y.width / src_yuv_info->hdiv;
339         src_c.height = src_y.height / src_yuv_info->vdiv;
340
341         if (sink_c.width == src_c.width && sink_c.height == src_c.height) {
342                 rkisp1_rsz_disable(rsz, when);
343                 return;
344         }
345
346         dev_dbg(rsz->rkisp1->dev, "stream %d rsz/scale: %dx%d -> %dx%d\n",
347                 rsz->id, sink_crop->width, sink_crop->height,
348                 src_fmt->width, src_fmt->height);
349         dev_dbg(rsz->rkisp1->dev, "chroma scaling %dx%d -> %dx%d\n",
350                 sink_c.width, sink_c.height, src_c.width, src_c.height);
351
352         /* set values in the hw */
353         rkisp1_rsz_config_regs(rsz, &sink_y, &sink_c, &src_y, &src_c, when);
354 }
355
356 /* ----------------------------------------------------------------------------
357  * Subdev pad operations
358  */
359
360 static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd,
361                                      struct v4l2_subdev_state *sd_state,
362                                      struct v4l2_subdev_mbus_code_enum *code)
363 {
364         struct rkisp1_resizer *rsz =
365                 container_of(sd, struct rkisp1_resizer, sd);
366         struct v4l2_subdev_pad_config dummy_cfg;
367         struct v4l2_subdev_state pad_state = {
368                 .pads = &dummy_cfg
369         };
370         u32 pad = code->pad;
371         int ret;
372
373         if (code->pad == RKISP1_RSZ_PAD_SRC) {
374                 /* supported mbus codes on the src are the same as in the capture */
375                 struct rkisp1_capture *cap = &rsz->rkisp1->capture_devs[rsz->id];
376
377                 return rkisp1_cap_enum_mbus_codes(cap, code);
378         }
379
380         /*
381          * The selfpath capture doesn't support bayer formats. Therefore the selfpath resizer
382          * should support only YUV422 on the sink pad
383          */
384         if (rsz->id == RKISP1_SELFPATH) {
385                 if (code->index > 0)
386                         return -EINVAL;
387                 code->code = MEDIA_BUS_FMT_YUYV8_2X8;
388                 return 0;
389         }
390
391         /* supported mbus codes on the sink pad are the same as isp src pad */
392         code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO;
393         ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code,
394                                &pad_state, code);
395
396         /* restore pad */
397         code->pad = pad;
398         code->flags = 0;
399         return ret;
400 }
401
402 static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
403                                   struct v4l2_subdev_state *sd_state)
404 {
405         struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
406         struct v4l2_rect *sink_crop;
407
408         sink_fmt = v4l2_subdev_get_try_format(sd, sd_state,
409                                               RKISP1_RSZ_PAD_SRC);
410         sink_fmt->width = RKISP1_DEFAULT_WIDTH;
411         sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
412         sink_fmt->field = V4L2_FIELD_NONE;
413         sink_fmt->code = RKISP1_DEF_FMT;
414         sink_fmt->colorspace = V4L2_COLORSPACE_SRGB;
415         sink_fmt->xfer_func = V4L2_XFER_FUNC_SRGB;
416         sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
417         sink_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
418
419         sink_crop = v4l2_subdev_get_try_crop(sd, sd_state,
420                                              RKISP1_RSZ_PAD_SINK);
421         sink_crop->width = RKISP1_DEFAULT_WIDTH;
422         sink_crop->height = RKISP1_DEFAULT_HEIGHT;
423         sink_crop->left = 0;
424         sink_crop->top = 0;
425
426         src_fmt = v4l2_subdev_get_try_format(sd, sd_state,
427                                              RKISP1_RSZ_PAD_SINK);
428         *src_fmt = *sink_fmt;
429
430         /* NOTE: there is no crop in the source pad, only in the sink */
431
432         return 0;
433 }
434
435 static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz,
436                                    struct v4l2_subdev_state *sd_state,
437                                    struct v4l2_mbus_framefmt *format,
438                                    unsigned int which)
439 {
440         const struct rkisp1_mbus_info *sink_mbus_info;
441         struct v4l2_mbus_framefmt *src_fmt, *sink_fmt;
442
443         sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK,
444                                           which);
445         src_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SRC,
446                                          which);
447         sink_mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
448
449         /* for YUV formats, userspace can change the mbus code on the src pad if it is supported */
450         if (sink_mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV &&
451             rkisp1_rsz_get_yuv_mbus_info(format->code))
452                 src_fmt->code = format->code;
453
454         src_fmt->width = clamp_t(u32, format->width,
455                                  rsz->config->min_rsz_width,
456                                  rsz->config->max_rsz_width);
457         src_fmt->height = clamp_t(u32, format->height,
458                                   rsz->config->min_rsz_height,
459                                   rsz->config->max_rsz_height);
460
461         *format = *src_fmt;
462 }
463
464 static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
465                                      struct v4l2_subdev_state *sd_state,
466                                      struct v4l2_rect *r,
467                                      unsigned int which)
468 {
469         const struct rkisp1_mbus_info *mbus_info;
470         struct v4l2_mbus_framefmt *sink_fmt;
471         struct v4l2_rect *sink_crop;
472
473         sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK,
474                                           which);
475         sink_crop = rkisp1_rsz_get_pad_crop(rsz, sd_state,
476                                             RKISP1_RSZ_PAD_SINK,
477                                             which);
478
479         /* Not crop for MP bayer raw data */
480         mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
481
482         if (rsz->id == RKISP1_MAINPATH &&
483             mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
484                 sink_crop->left = 0;
485                 sink_crop->top = 0;
486                 sink_crop->width = sink_fmt->width;
487                 sink_crop->height = sink_fmt->height;
488
489                 *r = *sink_crop;
490                 return;
491         }
492
493         sink_crop->left = ALIGN(r->left, 2);
494         sink_crop->width = ALIGN(r->width, 2);
495         sink_crop->top = r->top;
496         sink_crop->height = r->height;
497         rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
498
499         *r = *sink_crop;
500 }
501
502 static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
503                                     struct v4l2_subdev_state *sd_state,
504                                     struct v4l2_mbus_framefmt *format,
505                                     unsigned int which)
506 {
507         const struct rkisp1_mbus_info *mbus_info;
508         struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
509         struct v4l2_rect *sink_crop;
510         bool is_yuv;
511
512         sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK,
513                                           which);
514         src_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SRC,
515                                          which);
516         sink_crop = rkisp1_rsz_get_pad_crop(rsz, sd_state,
517                                             RKISP1_RSZ_PAD_SINK,
518                                             which);
519         if (rsz->id == RKISP1_SELFPATH)
520                 sink_fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
521         else
522                 sink_fmt->code = format->code;
523
524         mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
525         if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
526                 sink_fmt->code = RKISP1_DEF_FMT;
527                 mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
528         }
529         if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
530                 rsz->pixel_enc = mbus_info->pixel_enc;
531
532         sink_fmt->width = clamp_t(u32, format->width,
533                                   RKISP1_ISP_MIN_WIDTH,
534                                   RKISP1_ISP_MAX_WIDTH);
535         sink_fmt->height = clamp_t(u32, format->height,
536                                    RKISP1_ISP_MIN_HEIGHT,
537                                    RKISP1_ISP_MAX_HEIGHT);
538
539         /*
540          * Adjust the color space fields. Accept any color primaries and
541          * transfer function for both YUV and Bayer. For YUV any YCbCr encoding
542          * and quantization range is also accepted. For Bayer formats, the YCbCr
543          * encoding isn't applicable, and the quantization range can only be
544          * full.
545          */
546         is_yuv = mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV;
547
548         sink_fmt->colorspace = format->colorspace ? :
549                                (is_yuv ? V4L2_COLORSPACE_SRGB :
550                                 V4L2_COLORSPACE_RAW);
551         sink_fmt->xfer_func = format->xfer_func ? :
552                               V4L2_MAP_XFER_FUNC_DEFAULT(sink_fmt->colorspace);
553         if (is_yuv) {
554                 sink_fmt->ycbcr_enc = format->ycbcr_enc ? :
555                         V4L2_MAP_YCBCR_ENC_DEFAULT(sink_fmt->colorspace);
556                 sink_fmt->quantization = format->quantization ? :
557                         V4L2_MAP_QUANTIZATION_DEFAULT(false, sink_fmt->colorspace,
558                                                       sink_fmt->ycbcr_enc);
559         } else {
560                 /*
561                  * The YCbCr encoding isn't applicable for non-YUV formats, but
562                  * V4L2 has no "no encoding" value. Hardcode it to Rec. 601, it
563                  * should be ignored by userspace.
564                  */
565                 sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
566                 sink_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
567         }
568
569         *format = *sink_fmt;
570
571         /* Propagate the media bus code and color space to the source pad. */
572         src_fmt->code = sink_fmt->code;
573         src_fmt->colorspace = sink_fmt->colorspace;
574         src_fmt->xfer_func = sink_fmt->xfer_func;
575         src_fmt->ycbcr_enc = sink_fmt->ycbcr_enc;
576         src_fmt->quantization = sink_fmt->quantization;
577
578         /* Update sink crop */
579         rkisp1_rsz_set_sink_crop(rsz, sd_state, sink_crop, which);
580 }
581
582 static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd,
583                               struct v4l2_subdev_state *sd_state,
584                               struct v4l2_subdev_format *fmt)
585 {
586         struct rkisp1_resizer *rsz =
587                 container_of(sd, struct rkisp1_resizer, sd);
588
589         mutex_lock(&rsz->ops_lock);
590         fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, sd_state, fmt->pad,
591                                               fmt->which);
592         mutex_unlock(&rsz->ops_lock);
593         return 0;
594 }
595
596 static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd,
597                               struct v4l2_subdev_state *sd_state,
598                               struct v4l2_subdev_format *fmt)
599 {
600         struct rkisp1_resizer *rsz =
601                 container_of(sd, struct rkisp1_resizer, sd);
602
603         mutex_lock(&rsz->ops_lock);
604         if (fmt->pad == RKISP1_RSZ_PAD_SINK)
605                 rkisp1_rsz_set_sink_fmt(rsz, sd_state, &fmt->format,
606                                         fmt->which);
607         else
608                 rkisp1_rsz_set_src_fmt(rsz, sd_state, &fmt->format,
609                                        fmt->which);
610
611         mutex_unlock(&rsz->ops_lock);
612         return 0;
613 }
614
615 static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd,
616                                     struct v4l2_subdev_state *sd_state,
617                                     struct v4l2_subdev_selection *sel)
618 {
619         struct rkisp1_resizer *rsz =
620                 container_of(sd, struct rkisp1_resizer, sd);
621         struct v4l2_mbus_framefmt *mf_sink;
622         int ret = 0;
623
624         if (sel->pad == RKISP1_RSZ_PAD_SRC)
625                 return -EINVAL;
626
627         mutex_lock(&rsz->ops_lock);
628         switch (sel->target) {
629         case V4L2_SEL_TGT_CROP_BOUNDS:
630                 mf_sink = rkisp1_rsz_get_pad_fmt(rsz, sd_state,
631                                                  RKISP1_RSZ_PAD_SINK,
632                                                  sel->which);
633                 sel->r.height = mf_sink->height;
634                 sel->r.width = mf_sink->width;
635                 sel->r.left = 0;
636                 sel->r.top = 0;
637                 break;
638         case V4L2_SEL_TGT_CROP:
639                 sel->r = *rkisp1_rsz_get_pad_crop(rsz, sd_state,
640                                                   RKISP1_RSZ_PAD_SINK,
641                                                   sel->which);
642                 break;
643         default:
644                 ret = -EINVAL;
645         }
646
647         mutex_unlock(&rsz->ops_lock);
648         return ret;
649 }
650
651 static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd,
652                                     struct v4l2_subdev_state *sd_state,
653                                     struct v4l2_subdev_selection *sel)
654 {
655         struct rkisp1_resizer *rsz =
656                 container_of(sd, struct rkisp1_resizer, sd);
657
658         if (sel->target != V4L2_SEL_TGT_CROP || sel->pad == RKISP1_RSZ_PAD_SRC)
659                 return -EINVAL;
660
661         dev_dbg(rsz->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
662                 sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
663
664         mutex_lock(&rsz->ops_lock);
665         rkisp1_rsz_set_sink_crop(rsz, sd_state, &sel->r, sel->which);
666         mutex_unlock(&rsz->ops_lock);
667
668         return 0;
669 }
670
671 static const struct media_entity_operations rkisp1_rsz_media_ops = {
672         .link_validate = v4l2_subdev_link_validate,
673 };
674
675 static const struct v4l2_subdev_pad_ops rkisp1_rsz_pad_ops = {
676         .enum_mbus_code = rkisp1_rsz_enum_mbus_code,
677         .get_selection = rkisp1_rsz_get_selection,
678         .set_selection = rkisp1_rsz_set_selection,
679         .init_cfg = rkisp1_rsz_init_config,
680         .get_fmt = rkisp1_rsz_get_fmt,
681         .set_fmt = rkisp1_rsz_set_fmt,
682         .link_validate = v4l2_subdev_link_validate_default,
683 };
684
685 /* ----------------------------------------------------------------------------
686  * Stream operations
687  */
688
689 static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
690 {
691         struct rkisp1_resizer *rsz =
692                 container_of(sd, struct rkisp1_resizer, sd);
693         struct rkisp1_device *rkisp1 = rsz->rkisp1;
694         struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1];
695         enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC;
696
697         if (!enable) {
698                 rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
699                 rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
700                 return 0;
701         }
702
703         if (other->is_streaming)
704                 when = RKISP1_SHADOW_REGS_ASYNC;
705
706         mutex_lock(&rsz->ops_lock);
707         rkisp1_rsz_config(rsz, when);
708         rkisp1_dcrop_config(rsz);
709
710         mutex_unlock(&rsz->ops_lock);
711         return 0;
712 }
713
714 static const struct v4l2_subdev_video_ops rkisp1_rsz_video_ops = {
715         .s_stream = rkisp1_rsz_s_stream,
716 };
717
718 static const struct v4l2_subdev_ops rkisp1_rsz_ops = {
719         .video = &rkisp1_rsz_video_ops,
720         .pad = &rkisp1_rsz_pad_ops,
721 };
722
723 static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz)
724 {
725         if (!rsz->rkisp1)
726                 return;
727
728         v4l2_device_unregister_subdev(&rsz->sd);
729         media_entity_cleanup(&rsz->sd.entity);
730         mutex_destroy(&rsz->ops_lock);
731 }
732
733 static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
734 {
735         struct v4l2_subdev_state state = {
736                 .pads = rsz->pad_cfg,
737         };
738         static const char * const dev_names[] = {
739                 RKISP1_RSZ_MP_DEV_NAME,
740                 RKISP1_RSZ_SP_DEV_NAME
741         };
742         struct media_pad *pads = rsz->pads;
743         struct v4l2_subdev *sd = &rsz->sd;
744         int ret;
745
746         if (rsz->id == RKISP1_SELFPATH) {
747                 rsz->regs_base = RKISP1_CIF_SRSZ_BASE;
748                 rsz->config = &rkisp1_rsz_config_sp;
749         } else {
750                 rsz->regs_base = RKISP1_CIF_MRSZ_BASE;
751                 rsz->config = &rkisp1_rsz_config_mp;
752         }
753
754         v4l2_subdev_init(sd, &rkisp1_rsz_ops);
755         sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
756         sd->entity.ops = &rkisp1_rsz_media_ops;
757         sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
758         sd->owner = THIS_MODULE;
759         strscpy(sd->name, dev_names[rsz->id], sizeof(sd->name));
760
761         pads[RKISP1_RSZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
762                                           MEDIA_PAD_FL_MUST_CONNECT;
763         pads[RKISP1_RSZ_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE |
764                                          MEDIA_PAD_FL_MUST_CONNECT;
765
766         rsz->pixel_enc = RKISP1_DEF_PIXEL_ENC;
767
768         mutex_init(&rsz->ops_lock);
769         ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads);
770         if (ret)
771                 goto error;
772
773         ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd);
774         if (ret) {
775                 dev_err(sd->dev, "Failed to register resizer subdev\n");
776                 goto error;
777         }
778
779         rkisp1_rsz_init_config(sd, &state);
780         return 0;
781
782 error:
783         media_entity_cleanup(&sd->entity);
784         mutex_destroy(&rsz->ops_lock);
785         return ret;
786 }
787
788 int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
789 {
790         unsigned int i;
791         int ret;
792
793         for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
794                 struct rkisp1_resizer *rsz = &rkisp1->resizer_devs[i];
795
796                 rsz->rkisp1 = rkisp1;
797                 rsz->id = i;
798
799                 ret = rkisp1_rsz_register(rsz);
800                 if (ret) {
801                         rsz->rkisp1 = NULL;
802                         rkisp1_resizer_devs_unregister(rkisp1);
803                         return ret;
804                 }
805         }
806
807         return 0;
808 }
809
810 void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1)
811 {
812         struct rkisp1_resizer *mp = &rkisp1->resizer_devs[RKISP1_MAINPATH];
813         struct rkisp1_resizer *sp = &rkisp1->resizer_devs[RKISP1_SELFPATH];
814
815         rkisp1_rsz_unregister(mp);
816         rkisp1_rsz_unregister(sp);
817 }
This page took 0.079683 seconds and 4 git commands to generate.