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 
rkisp1_rsz_get_yuv_mbus_info(u32 mbus_code)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 
rkisp1_rsz_read(struct rkisp1_resizer * rsz,u32 offset)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 
rkisp1_rsz_write(struct rkisp1_resizer * rsz,u32 offset,u32 value)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 *
rkisp1_rsz_get_pad_fmt(struct rkisp1_resizer * rsz,struct v4l2_subdev_state * sd_state,unsigned int pad,u32 which)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 *
rkisp1_rsz_get_pad_crop(struct rkisp1_resizer * rsz,struct v4l2_subdev_state * sd_state,unsigned int pad,u32 which)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 
rkisp1_dcrop_disable(struct rkisp1_resizer * rsz,enum rkisp1_shadow_regs_when when)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 */
rkisp1_dcrop_config(struct rkisp1_resizer * rsz)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 
rkisp1_rsz_update_shadow(struct rkisp1_resizer * rsz,enum rkisp1_shadow_regs_when when)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 
rkisp1_rsz_calc_ratio(u32 len_sink,u32 len_src)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 
rkisp1_rsz_disable(struct rkisp1_resizer * rsz,enum rkisp1_shadow_regs_when when)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 
rkisp1_rsz_config_regs(struct rkisp1_resizer * rsz,struct v4l2_rect * sink_y,struct v4l2_rect * sink_c,struct v4l2_rect * src_y,struct v4l2_rect * src_c,enum rkisp1_shadow_regs_when when)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 
rkisp1_rsz_config(struct rkisp1_resizer * rsz,enum rkisp1_shadow_regs_when when)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 
rkisp1_rsz_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_mbus_code_enum * code)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 	unsigned int index = code->index;
367 	unsigned int i;
368 
369 	if (code->pad == RKISP1_RSZ_PAD_SRC) {
370 		/* supported mbus codes on the src are the same as in the capture */
371 		struct rkisp1_capture *cap = &rsz->rkisp1->capture_devs[rsz->id];
372 
373 		return rkisp1_cap_enum_mbus_codes(cap, code);
374 	}
375 
376 	/*
377 	 * The selfpath capture doesn't support bayer formats. Therefore the selfpath resizer
378 	 * should support only YUV422 on the sink pad
379 	 */
380 	if (rsz->id == RKISP1_SELFPATH) {
381 		if (code->index > 0)
382 			return -EINVAL;
383 		code->code = MEDIA_BUS_FMT_YUYV8_2X8;
384 		return 0;
385 	}
386 
387 	/*
388 	 * Supported mbus codes on the sink pad are the same as on the ISP
389 	 * source pad.
390 	 */
391 	for (i = 0; ; i++) {
392 		const struct rkisp1_mbus_info *fmt =
393 			rkisp1_mbus_info_get_by_index(i);
394 
395 		if (!fmt)
396 			break;
397 
398 		if (!(fmt->direction & RKISP1_ISP_SD_SRC))
399 			continue;
400 
401 		if (!index) {
402 			code->code = fmt->mbus_code;
403 			return 0;
404 		}
405 
406 		index--;
407 	}
408 
409 	return -EINVAL;
410 }
411 
rkisp1_rsz_init_config(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state)412 static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
413 				  struct v4l2_subdev_state *sd_state)
414 {
415 	struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
416 	struct v4l2_rect *sink_crop;
417 
418 	sink_fmt = v4l2_subdev_get_try_format(sd, sd_state,
419 					      RKISP1_RSZ_PAD_SRC);
420 	sink_fmt->width = RKISP1_DEFAULT_WIDTH;
421 	sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
422 	sink_fmt->field = V4L2_FIELD_NONE;
423 	sink_fmt->code = RKISP1_DEF_FMT;
424 	sink_fmt->colorspace = V4L2_COLORSPACE_SRGB;
425 	sink_fmt->xfer_func = V4L2_XFER_FUNC_SRGB;
426 	sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
427 	sink_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
428 
429 	sink_crop = v4l2_subdev_get_try_crop(sd, sd_state,
430 					     RKISP1_RSZ_PAD_SINK);
431 	sink_crop->width = RKISP1_DEFAULT_WIDTH;
432 	sink_crop->height = RKISP1_DEFAULT_HEIGHT;
433 	sink_crop->left = 0;
434 	sink_crop->top = 0;
435 
436 	src_fmt = v4l2_subdev_get_try_format(sd, sd_state,
437 					     RKISP1_RSZ_PAD_SINK);
438 	*src_fmt = *sink_fmt;
439 
440 	/* NOTE: there is no crop in the source pad, only in the sink */
441 
442 	return 0;
443 }
444 
rkisp1_rsz_set_src_fmt(struct rkisp1_resizer * rsz,struct v4l2_subdev_state * sd_state,struct v4l2_mbus_framefmt * format,unsigned int which)445 static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz,
446 				   struct v4l2_subdev_state *sd_state,
447 				   struct v4l2_mbus_framefmt *format,
448 				   unsigned int which)
449 {
450 	const struct rkisp1_mbus_info *sink_mbus_info;
451 	struct v4l2_mbus_framefmt *src_fmt, *sink_fmt;
452 
453 	sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK,
454 					  which);
455 	src_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SRC,
456 					 which);
457 	sink_mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
458 
459 	/* for YUV formats, userspace can change the mbus code on the src pad if it is supported */
460 	if (sink_mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV &&
461 	    rkisp1_rsz_get_yuv_mbus_info(format->code))
462 		src_fmt->code = format->code;
463 
464 	src_fmt->width = clamp_t(u32, format->width,
465 				 rsz->config->min_rsz_width,
466 				 rsz->config->max_rsz_width);
467 	src_fmt->height = clamp_t(u32, format->height,
468 				  rsz->config->min_rsz_height,
469 				  rsz->config->max_rsz_height);
470 
471 	*format = *src_fmt;
472 }
473 
rkisp1_rsz_set_sink_crop(struct rkisp1_resizer * rsz,struct v4l2_subdev_state * sd_state,struct v4l2_rect * r,unsigned int which)474 static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
475 				     struct v4l2_subdev_state *sd_state,
476 				     struct v4l2_rect *r,
477 				     unsigned int which)
478 {
479 	const struct rkisp1_mbus_info *mbus_info;
480 	struct v4l2_mbus_framefmt *sink_fmt;
481 	struct v4l2_rect *sink_crop;
482 
483 	sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK,
484 					  which);
485 	sink_crop = rkisp1_rsz_get_pad_crop(rsz, sd_state,
486 					    RKISP1_RSZ_PAD_SINK,
487 					    which);
488 
489 	/* Not crop for MP bayer raw data */
490 	mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
491 
492 	if (rsz->id == RKISP1_MAINPATH &&
493 	    mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
494 		sink_crop->left = 0;
495 		sink_crop->top = 0;
496 		sink_crop->width = sink_fmt->width;
497 		sink_crop->height = sink_fmt->height;
498 
499 		*r = *sink_crop;
500 		return;
501 	}
502 
503 	sink_crop->left = ALIGN(r->left, 2);
504 	sink_crop->width = ALIGN(r->width, 2);
505 	sink_crop->top = r->top;
506 	sink_crop->height = r->height;
507 	rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
508 
509 	*r = *sink_crop;
510 }
511 
rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer * rsz,struct v4l2_subdev_state * sd_state,struct v4l2_mbus_framefmt * format,unsigned int which)512 static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
513 				    struct v4l2_subdev_state *sd_state,
514 				    struct v4l2_mbus_framefmt *format,
515 				    unsigned int which)
516 {
517 	const struct rkisp1_mbus_info *mbus_info;
518 	struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
519 	struct v4l2_rect *sink_crop;
520 	bool is_yuv;
521 
522 	sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK,
523 					  which);
524 	src_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SRC,
525 					 which);
526 	sink_crop = rkisp1_rsz_get_pad_crop(rsz, sd_state,
527 					    RKISP1_RSZ_PAD_SINK,
528 					    which);
529 	if (rsz->id == RKISP1_SELFPATH)
530 		sink_fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
531 	else
532 		sink_fmt->code = format->code;
533 
534 	mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
535 	if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
536 		sink_fmt->code = RKISP1_DEF_FMT;
537 		mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
538 	}
539 	if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
540 		rsz->pixel_enc = mbus_info->pixel_enc;
541 
542 	sink_fmt->width = clamp_t(u32, format->width,
543 				  RKISP1_ISP_MIN_WIDTH,
544 				  RKISP1_ISP_MAX_WIDTH);
545 	sink_fmt->height = clamp_t(u32, format->height,
546 				   RKISP1_ISP_MIN_HEIGHT,
547 				   RKISP1_ISP_MAX_HEIGHT);
548 
549 	/*
550 	 * Adjust the color space fields. Accept any color primaries and
551 	 * transfer function for both YUV and Bayer. For YUV any YCbCr encoding
552 	 * and quantization range is also accepted. For Bayer formats, the YCbCr
553 	 * encoding isn't applicable, and the quantization range can only be
554 	 * full.
555 	 */
556 	is_yuv = mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV;
557 
558 	sink_fmt->colorspace = format->colorspace ? :
559 			       (is_yuv ? V4L2_COLORSPACE_SRGB :
560 				V4L2_COLORSPACE_RAW);
561 	sink_fmt->xfer_func = format->xfer_func ? :
562 			      V4L2_MAP_XFER_FUNC_DEFAULT(sink_fmt->colorspace);
563 	if (is_yuv) {
564 		sink_fmt->ycbcr_enc = format->ycbcr_enc ? :
565 			V4L2_MAP_YCBCR_ENC_DEFAULT(sink_fmt->colorspace);
566 		sink_fmt->quantization = format->quantization ? :
567 			V4L2_MAP_QUANTIZATION_DEFAULT(false, sink_fmt->colorspace,
568 						      sink_fmt->ycbcr_enc);
569 	} else {
570 		/*
571 		 * The YCbCr encoding isn't applicable for non-YUV formats, but
572 		 * V4L2 has no "no encoding" value. Hardcode it to Rec. 601, it
573 		 * should be ignored by userspace.
574 		 */
575 		sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
576 		sink_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
577 	}
578 
579 	*format = *sink_fmt;
580 
581 	/* Propagate the media bus code and color space to the source pad. */
582 	src_fmt->code = sink_fmt->code;
583 	src_fmt->colorspace = sink_fmt->colorspace;
584 	src_fmt->xfer_func = sink_fmt->xfer_func;
585 	src_fmt->ycbcr_enc = sink_fmt->ycbcr_enc;
586 	src_fmt->quantization = sink_fmt->quantization;
587 
588 	/* Update sink crop */
589 	rkisp1_rsz_set_sink_crop(rsz, sd_state, sink_crop, which);
590 }
591 
rkisp1_rsz_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * fmt)592 static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd,
593 			      struct v4l2_subdev_state *sd_state,
594 			      struct v4l2_subdev_format *fmt)
595 {
596 	struct rkisp1_resizer *rsz =
597 		container_of(sd, struct rkisp1_resizer, sd);
598 
599 	mutex_lock(&rsz->ops_lock);
600 	fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, sd_state, fmt->pad,
601 					      fmt->which);
602 	mutex_unlock(&rsz->ops_lock);
603 	return 0;
604 }
605 
rkisp1_rsz_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * fmt)606 static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd,
607 			      struct v4l2_subdev_state *sd_state,
608 			      struct v4l2_subdev_format *fmt)
609 {
610 	struct rkisp1_resizer *rsz =
611 		container_of(sd, struct rkisp1_resizer, sd);
612 
613 	mutex_lock(&rsz->ops_lock);
614 	if (fmt->pad == RKISP1_RSZ_PAD_SINK)
615 		rkisp1_rsz_set_sink_fmt(rsz, sd_state, &fmt->format,
616 					fmt->which);
617 	else
618 		rkisp1_rsz_set_src_fmt(rsz, sd_state, &fmt->format,
619 				       fmt->which);
620 
621 	mutex_unlock(&rsz->ops_lock);
622 	return 0;
623 }
624 
rkisp1_rsz_get_selection(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_selection * sel)625 static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd,
626 				    struct v4l2_subdev_state *sd_state,
627 				    struct v4l2_subdev_selection *sel)
628 {
629 	struct rkisp1_resizer *rsz =
630 		container_of(sd, struct rkisp1_resizer, sd);
631 	struct v4l2_mbus_framefmt *mf_sink;
632 	int ret = 0;
633 
634 	if (sel->pad == RKISP1_RSZ_PAD_SRC)
635 		return -EINVAL;
636 
637 	mutex_lock(&rsz->ops_lock);
638 	switch (sel->target) {
639 	case V4L2_SEL_TGT_CROP_BOUNDS:
640 		mf_sink = rkisp1_rsz_get_pad_fmt(rsz, sd_state,
641 						 RKISP1_RSZ_PAD_SINK,
642 						 sel->which);
643 		sel->r.height = mf_sink->height;
644 		sel->r.width = mf_sink->width;
645 		sel->r.left = 0;
646 		sel->r.top = 0;
647 		break;
648 	case V4L2_SEL_TGT_CROP:
649 		sel->r = *rkisp1_rsz_get_pad_crop(rsz, sd_state,
650 						  RKISP1_RSZ_PAD_SINK,
651 						  sel->which);
652 		break;
653 	default:
654 		ret = -EINVAL;
655 	}
656 
657 	mutex_unlock(&rsz->ops_lock);
658 	return ret;
659 }
660 
rkisp1_rsz_set_selection(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_selection * sel)661 static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd,
662 				    struct v4l2_subdev_state *sd_state,
663 				    struct v4l2_subdev_selection *sel)
664 {
665 	struct rkisp1_resizer *rsz =
666 		container_of(sd, struct rkisp1_resizer, sd);
667 
668 	if (sel->target != V4L2_SEL_TGT_CROP || sel->pad == RKISP1_RSZ_PAD_SRC)
669 		return -EINVAL;
670 
671 	dev_dbg(rsz->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
672 		sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
673 
674 	mutex_lock(&rsz->ops_lock);
675 	rkisp1_rsz_set_sink_crop(rsz, sd_state, &sel->r, sel->which);
676 	mutex_unlock(&rsz->ops_lock);
677 
678 	return 0;
679 }
680 
681 static const struct media_entity_operations rkisp1_rsz_media_ops = {
682 	.link_validate = v4l2_subdev_link_validate,
683 };
684 
685 static const struct v4l2_subdev_pad_ops rkisp1_rsz_pad_ops = {
686 	.enum_mbus_code = rkisp1_rsz_enum_mbus_code,
687 	.get_selection = rkisp1_rsz_get_selection,
688 	.set_selection = rkisp1_rsz_set_selection,
689 	.init_cfg = rkisp1_rsz_init_config,
690 	.get_fmt = rkisp1_rsz_get_fmt,
691 	.set_fmt = rkisp1_rsz_set_fmt,
692 	.link_validate = v4l2_subdev_link_validate_default,
693 };
694 
695 /* ----------------------------------------------------------------------------
696  * Stream operations
697  */
698 
rkisp1_rsz_s_stream(struct v4l2_subdev * sd,int enable)699 static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
700 {
701 	struct rkisp1_resizer *rsz =
702 		container_of(sd, struct rkisp1_resizer, sd);
703 	struct rkisp1_device *rkisp1 = rsz->rkisp1;
704 	struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1];
705 	enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC;
706 
707 	if (!enable) {
708 		rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
709 		rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
710 		return 0;
711 	}
712 
713 	if (other->is_streaming)
714 		when = RKISP1_SHADOW_REGS_ASYNC;
715 
716 	mutex_lock(&rsz->ops_lock);
717 	rkisp1_rsz_config(rsz, when);
718 	rkisp1_dcrop_config(rsz);
719 
720 	mutex_unlock(&rsz->ops_lock);
721 	return 0;
722 }
723 
724 static const struct v4l2_subdev_video_ops rkisp1_rsz_video_ops = {
725 	.s_stream = rkisp1_rsz_s_stream,
726 };
727 
728 static const struct v4l2_subdev_ops rkisp1_rsz_ops = {
729 	.video = &rkisp1_rsz_video_ops,
730 	.pad = &rkisp1_rsz_pad_ops,
731 };
732 
rkisp1_rsz_unregister(struct rkisp1_resizer * rsz)733 static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz)
734 {
735 	if (!rsz->rkisp1)
736 		return;
737 
738 	v4l2_device_unregister_subdev(&rsz->sd);
739 	media_entity_cleanup(&rsz->sd.entity);
740 	mutex_destroy(&rsz->ops_lock);
741 }
742 
rkisp1_rsz_register(struct rkisp1_resizer * rsz)743 static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
744 {
745 	struct v4l2_subdev_state state = {
746 		.pads = rsz->pad_cfg,
747 	};
748 	static const char * const dev_names[] = {
749 		RKISP1_RSZ_MP_DEV_NAME,
750 		RKISP1_RSZ_SP_DEV_NAME
751 	};
752 	struct media_pad *pads = rsz->pads;
753 	struct v4l2_subdev *sd = &rsz->sd;
754 	int ret;
755 
756 	if (rsz->id == RKISP1_SELFPATH) {
757 		rsz->regs_base = RKISP1_CIF_SRSZ_BASE;
758 		rsz->config = &rkisp1_rsz_config_sp;
759 	} else {
760 		rsz->regs_base = RKISP1_CIF_MRSZ_BASE;
761 		rsz->config = &rkisp1_rsz_config_mp;
762 	}
763 
764 	v4l2_subdev_init(sd, &rkisp1_rsz_ops);
765 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
766 	sd->entity.ops = &rkisp1_rsz_media_ops;
767 	sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
768 	sd->owner = THIS_MODULE;
769 	strscpy(sd->name, dev_names[rsz->id], sizeof(sd->name));
770 
771 	pads[RKISP1_RSZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
772 					  MEDIA_PAD_FL_MUST_CONNECT;
773 	pads[RKISP1_RSZ_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE |
774 					 MEDIA_PAD_FL_MUST_CONNECT;
775 
776 	rsz->pixel_enc = RKISP1_DEF_PIXEL_ENC;
777 
778 	mutex_init(&rsz->ops_lock);
779 	ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads);
780 	if (ret)
781 		goto error;
782 
783 	ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd);
784 	if (ret) {
785 		dev_err(sd->dev, "Failed to register resizer subdev\n");
786 		goto error;
787 	}
788 
789 	rkisp1_rsz_init_config(sd, &state);
790 	return 0;
791 
792 error:
793 	media_entity_cleanup(&sd->entity);
794 	mutex_destroy(&rsz->ops_lock);
795 	return ret;
796 }
797 
rkisp1_resizer_devs_register(struct rkisp1_device * rkisp1)798 int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
799 {
800 	unsigned int i;
801 	int ret;
802 
803 	for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
804 		struct rkisp1_resizer *rsz = &rkisp1->resizer_devs[i];
805 
806 		rsz->rkisp1 = rkisp1;
807 		rsz->id = i;
808 
809 		ret = rkisp1_rsz_register(rsz);
810 		if (ret) {
811 			rsz->rkisp1 = NULL;
812 			rkisp1_resizer_devs_unregister(rkisp1);
813 			return ret;
814 		}
815 	}
816 
817 	return 0;
818 }
819 
rkisp1_resizer_devs_unregister(struct rkisp1_device * rkisp1)820 void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1)
821 {
822 	struct rkisp1_resizer *mp = &rkisp1->resizer_devs[RKISP1_MAINPATH];
823 	struct rkisp1_resizer *sp = &rkisp1->resizer_devs[RKISP1_SELFPATH];
824 
825 	rkisp1_rsz_unregister(mp);
826 	rkisp1_rsz_unregister(sp);
827 }
828