xref: /linux/drivers/media/platform/xilinx/xilinx-tpg.c (revision 4b660dbd9ee2059850fd30e0df420ca7a38a1856)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Xilinx Test Pattern Generator
4  *
5  * Copyright (C) 2013-2015 Ideas on Board
6  * Copyright (C) 2013-2015 Xilinx, Inc.
7  *
8  * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
9  *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10  */
11 
12 #include <linux/device.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/platform_device.h>
17 #include <linux/xilinx-v4l2-controls.h>
18 
19 #include <media/v4l2-async.h>
20 #include <media/v4l2-ctrls.h>
21 #include <media/v4l2-subdev.h>
22 
23 #include "xilinx-vip.h"
24 #include "xilinx-vtc.h"
25 
26 #define XTPG_CTRL_STATUS_SLAVE_ERROR		(1 << 16)
27 #define XTPG_CTRL_IRQ_SLAVE_ERROR		(1 << 16)
28 
29 #define XTPG_PATTERN_CONTROL			0x0100
30 #define XTPG_PATTERN_MASK			(0xf << 0)
31 #define XTPG_PATTERN_CONTROL_CROSS_HAIRS	(1 << 4)
32 #define XTPG_PATTERN_CONTROL_MOVING_BOX		(1 << 5)
33 #define XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT	6
34 #define XTPG_PATTERN_CONTROL_COLOR_MASK_MASK	(0xf << 6)
35 #define XTPG_PATTERN_CONTROL_STUCK_PIXEL	(1 << 9)
36 #define XTPG_PATTERN_CONTROL_NOISE		(1 << 10)
37 #define XTPG_PATTERN_CONTROL_MOTION		(1 << 12)
38 #define XTPG_MOTION_SPEED			0x0104
39 #define XTPG_CROSS_HAIRS			0x0108
40 #define XTPG_CROSS_HAIRS_ROW_SHIFT		0
41 #define XTPG_CROSS_HAIRS_ROW_MASK		(0xfff << 0)
42 #define XTPG_CROSS_HAIRS_COLUMN_SHIFT		16
43 #define XTPG_CROSS_HAIRS_COLUMN_MASK		(0xfff << 16)
44 #define XTPG_ZPLATE_HOR_CONTROL			0x010c
45 #define XTPG_ZPLATE_VER_CONTROL			0x0110
46 #define XTPG_ZPLATE_START_SHIFT			0
47 #define XTPG_ZPLATE_START_MASK			(0xffff << 0)
48 #define XTPG_ZPLATE_SPEED_SHIFT			16
49 #define XTPG_ZPLATE_SPEED_MASK			(0xffff << 16)
50 #define XTPG_BOX_SIZE				0x0114
51 #define XTPG_BOX_COLOR				0x0118
52 #define XTPG_STUCK_PIXEL_THRESH			0x011c
53 #define XTPG_NOISE_GAIN				0x0120
54 #define XTPG_BAYER_PHASE			0x0124
55 #define XTPG_BAYER_PHASE_RGGB			0
56 #define XTPG_BAYER_PHASE_GRBG			1
57 #define XTPG_BAYER_PHASE_GBRG			2
58 #define XTPG_BAYER_PHASE_BGGR			3
59 #define XTPG_BAYER_PHASE_OFF			4
60 
61 /*
62  * The minimum blanking value is one clock cycle for the front porch, one clock
63  * cycle for the sync pulse and one clock cycle for the back porch.
64  */
65 #define XTPG_MIN_HBLANK			3
66 #define XTPG_MAX_HBLANK			(XVTC_MAX_HSIZE - XVIP_MIN_WIDTH)
67 #define XTPG_MIN_VBLANK			3
68 #define XTPG_MAX_VBLANK			(XVTC_MAX_VSIZE - XVIP_MIN_HEIGHT)
69 
70 /**
71  * struct xtpg_device - Xilinx Test Pattern Generator device structure
72  * @xvip: Xilinx Video IP device
73  * @pads: media pads
74  * @npads: number of pads (1 or 2)
75  * @has_input: whether an input is connected to the sink pad
76  * @formats: active V4L2 media bus format for each pad
77  * @default_format: default V4L2 media bus format
78  * @vip_format: format information corresponding to the active format
79  * @bayer: boolean flag if TPG is set to any bayer format
80  * @ctrl_handler: control handler
81  * @hblank: horizontal blanking control
82  * @vblank: vertical blanking control
83  * @pattern: test pattern control
84  * @streaming: is the video stream active
85  * @vtc: video timing controller
86  * @vtmux_gpio: video timing mux GPIO
87  */
88 struct xtpg_device {
89 	struct xvip_device xvip;
90 
91 	struct media_pad pads[2];
92 	unsigned int npads;
93 	bool has_input;
94 
95 	struct v4l2_mbus_framefmt formats[2];
96 	struct v4l2_mbus_framefmt default_format;
97 	const struct xvip_video_format *vip_format;
98 	bool bayer;
99 
100 	struct v4l2_ctrl_handler ctrl_handler;
101 	struct v4l2_ctrl *hblank;
102 	struct v4l2_ctrl *vblank;
103 	struct v4l2_ctrl *pattern;
104 	bool streaming;
105 
106 	struct xvtc_device *vtc;
107 	struct gpio_desc *vtmux_gpio;
108 };
109 
110 static inline struct xtpg_device *to_tpg(struct v4l2_subdev *subdev)
111 {
112 	return container_of(subdev, struct xtpg_device, xvip.subdev);
113 }
114 
115 static u32 xtpg_get_bayer_phase(unsigned int code)
116 {
117 	switch (code) {
118 	case MEDIA_BUS_FMT_SRGGB8_1X8:
119 		return XTPG_BAYER_PHASE_RGGB;
120 	case MEDIA_BUS_FMT_SGRBG8_1X8:
121 		return XTPG_BAYER_PHASE_GRBG;
122 	case MEDIA_BUS_FMT_SGBRG8_1X8:
123 		return XTPG_BAYER_PHASE_GBRG;
124 	case MEDIA_BUS_FMT_SBGGR8_1X8:
125 		return XTPG_BAYER_PHASE_BGGR;
126 	default:
127 		return XTPG_BAYER_PHASE_OFF;
128 	}
129 }
130 
131 static void __xtpg_update_pattern_control(struct xtpg_device *xtpg,
132 					  bool passthrough, bool pattern)
133 {
134 	u32 pattern_mask = (1 << (xtpg->pattern->maximum + 1)) - 1;
135 
136 	/*
137 	 * If the TPG has no sink pad or no input connected to its sink pad
138 	 * passthrough mode can't be enabled.
139 	 */
140 	if (xtpg->npads == 1 || !xtpg->has_input)
141 		passthrough = false;
142 
143 	/* If passthrough mode is allowed unmask bit 0. */
144 	if (passthrough)
145 		pattern_mask &= ~1;
146 
147 	/* If test pattern mode is allowed unmask all other bits. */
148 	if (pattern)
149 		pattern_mask &= 1;
150 
151 	__v4l2_ctrl_modify_range(xtpg->pattern, 0, xtpg->pattern->maximum,
152 				 pattern_mask, pattern ? 9 : 0);
153 }
154 
155 static void xtpg_update_pattern_control(struct xtpg_device *xtpg,
156 					bool passthrough, bool pattern)
157 {
158 	mutex_lock(xtpg->ctrl_handler.lock);
159 	__xtpg_update_pattern_control(xtpg, passthrough, pattern);
160 	mutex_unlock(xtpg->ctrl_handler.lock);
161 }
162 
163 /* -----------------------------------------------------------------------------
164  * V4L2 Subdevice Video Operations
165  */
166 
167 static int xtpg_s_stream(struct v4l2_subdev *subdev, int enable)
168 {
169 	struct xtpg_device *xtpg = to_tpg(subdev);
170 	unsigned int width = xtpg->formats[0].width;
171 	unsigned int height = xtpg->formats[0].height;
172 	bool passthrough;
173 	u32 bayer_phase;
174 
175 	if (!enable) {
176 		xvip_stop(&xtpg->xvip);
177 		if (xtpg->vtc)
178 			xvtc_generator_stop(xtpg->vtc);
179 
180 		xtpg_update_pattern_control(xtpg, true, true);
181 		xtpg->streaming = false;
182 		return 0;
183 	}
184 
185 	xvip_set_frame_size(&xtpg->xvip, &xtpg->formats[0]);
186 
187 	if (xtpg->vtc) {
188 		struct xvtc_config config = {
189 			.hblank_start = width,
190 			.hsync_start = width + 1,
191 			.vblank_start = height,
192 			.vsync_start = height + 1,
193 		};
194 		unsigned int htotal;
195 		unsigned int vtotal;
196 
197 		htotal = min_t(unsigned int, XVTC_MAX_HSIZE,
198 			       v4l2_ctrl_g_ctrl(xtpg->hblank) + width);
199 		vtotal = min_t(unsigned int, XVTC_MAX_VSIZE,
200 			       v4l2_ctrl_g_ctrl(xtpg->vblank) + height);
201 
202 		config.hsync_end = htotal - 1;
203 		config.hsize = htotal;
204 		config.vsync_end = vtotal - 1;
205 		config.vsize = vtotal;
206 
207 		xvtc_generator_start(xtpg->vtc, &config);
208 	}
209 
210 	/*
211 	 * Configure the bayer phase and video timing mux based on the
212 	 * operation mode (passthrough or test pattern generation). The test
213 	 * pattern can be modified by the control set handler, we thus need to
214 	 * take the control lock here to avoid races.
215 	 */
216 	mutex_lock(xtpg->ctrl_handler.lock);
217 
218 	xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
219 			 XTPG_PATTERN_MASK, xtpg->pattern->cur.val);
220 
221 	/*
222 	 * Switching between passthrough and test pattern generation modes isn't
223 	 * allowed during streaming, update the control range accordingly.
224 	 */
225 	passthrough = xtpg->pattern->cur.val == 0;
226 	__xtpg_update_pattern_control(xtpg, passthrough, !passthrough);
227 
228 	xtpg->streaming = true;
229 
230 	mutex_unlock(xtpg->ctrl_handler.lock);
231 
232 	/*
233 	 * For TPG v5.0, the bayer phase needs to be off for the pass through
234 	 * mode, otherwise the external input would be subsampled.
235 	 */
236 	bayer_phase = passthrough ? XTPG_BAYER_PHASE_OFF
237 		    : xtpg_get_bayer_phase(xtpg->formats[0].code);
238 	xvip_write(&xtpg->xvip, XTPG_BAYER_PHASE, bayer_phase);
239 
240 	if (xtpg->vtmux_gpio)
241 		gpiod_set_value_cansleep(xtpg->vtmux_gpio, !passthrough);
242 
243 	xvip_start(&xtpg->xvip);
244 
245 	return 0;
246 }
247 
248 /* -----------------------------------------------------------------------------
249  * V4L2 Subdevice Pad Operations
250  */
251 
252 static struct v4l2_mbus_framefmt *
253 __xtpg_get_pad_format(struct xtpg_device *xtpg,
254 		      struct v4l2_subdev_state *sd_state,
255 		      unsigned int pad, u32 which)
256 {
257 	switch (which) {
258 	case V4L2_SUBDEV_FORMAT_TRY:
259 		return v4l2_subdev_state_get_format(sd_state, pad);
260 	case V4L2_SUBDEV_FORMAT_ACTIVE:
261 		return &xtpg->formats[pad];
262 	default:
263 		return NULL;
264 	}
265 }
266 
267 static int xtpg_get_format(struct v4l2_subdev *subdev,
268 			   struct v4l2_subdev_state *sd_state,
269 			   struct v4l2_subdev_format *fmt)
270 {
271 	struct xtpg_device *xtpg = to_tpg(subdev);
272 
273 	fmt->format = *__xtpg_get_pad_format(xtpg, sd_state, fmt->pad,
274 					     fmt->which);
275 
276 	return 0;
277 }
278 
279 static int xtpg_set_format(struct v4l2_subdev *subdev,
280 			   struct v4l2_subdev_state *sd_state,
281 			   struct v4l2_subdev_format *fmt)
282 {
283 	struct xtpg_device *xtpg = to_tpg(subdev);
284 	struct v4l2_mbus_framefmt *__format;
285 	u32 bayer_phase;
286 
287 	__format = __xtpg_get_pad_format(xtpg, sd_state, fmt->pad, fmt->which);
288 
289 	/* In two pads mode the source pad format is always identical to the
290 	 * sink pad format.
291 	 */
292 	if (xtpg->npads == 2 && fmt->pad == 1) {
293 		fmt->format = *__format;
294 		return 0;
295 	}
296 
297 	/* Bayer phase is configurable at runtime */
298 	if (xtpg->bayer) {
299 		bayer_phase = xtpg_get_bayer_phase(fmt->format.code);
300 		if (bayer_phase != XTPG_BAYER_PHASE_OFF)
301 			__format->code = fmt->format.code;
302 	}
303 
304 	xvip_set_format_size(__format, fmt);
305 
306 	fmt->format = *__format;
307 
308 	/* Propagate the format to the source pad. */
309 	if (xtpg->npads == 2) {
310 		__format = __xtpg_get_pad_format(xtpg, sd_state, 1,
311 						 fmt->which);
312 		*__format = fmt->format;
313 	}
314 
315 	return 0;
316 }
317 
318 /* -----------------------------------------------------------------------------
319  * V4L2 Subdevice Operations
320  */
321 
322 static int xtpg_enum_frame_size(struct v4l2_subdev *subdev,
323 				struct v4l2_subdev_state *sd_state,
324 				struct v4l2_subdev_frame_size_enum *fse)
325 {
326 	struct v4l2_mbus_framefmt *format;
327 
328 	format = v4l2_subdev_state_get_format(sd_state, fse->pad);
329 
330 	if (fse->index || fse->code != format->code)
331 		return -EINVAL;
332 
333 	/* Min / max values for pad 0 is always fixed in both one and two pads
334 	 * modes. In two pads mode, the source pad(= 1) size is identical to
335 	 * the sink pad size */
336 	if (fse->pad == 0) {
337 		fse->min_width = XVIP_MIN_WIDTH;
338 		fse->max_width = XVIP_MAX_WIDTH;
339 		fse->min_height = XVIP_MIN_HEIGHT;
340 		fse->max_height = XVIP_MAX_HEIGHT;
341 	} else {
342 		fse->min_width = format->width;
343 		fse->max_width = format->width;
344 		fse->min_height = format->height;
345 		fse->max_height = format->height;
346 	}
347 
348 	return 0;
349 }
350 
351 static int xtpg_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
352 {
353 	struct xtpg_device *xtpg = to_tpg(subdev);
354 	struct v4l2_mbus_framefmt *format;
355 
356 	format = v4l2_subdev_state_get_format(fh->state, 0);
357 	*format = xtpg->default_format;
358 
359 	if (xtpg->npads == 2) {
360 		format = v4l2_subdev_state_get_format(fh->state, 1);
361 		*format = xtpg->default_format;
362 	}
363 
364 	return 0;
365 }
366 
367 static int xtpg_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
368 {
369 	return 0;
370 }
371 
372 static int xtpg_s_ctrl(struct v4l2_ctrl *ctrl)
373 {
374 	struct xtpg_device *xtpg = container_of(ctrl->handler,
375 						struct xtpg_device,
376 						ctrl_handler);
377 	switch (ctrl->id) {
378 	case V4L2_CID_TEST_PATTERN:
379 		xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
380 				 XTPG_PATTERN_MASK, ctrl->val);
381 		return 0;
382 	case V4L2_CID_XILINX_TPG_CROSS_HAIRS:
383 		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
384 				XTPG_PATTERN_CONTROL_CROSS_HAIRS, ctrl->val);
385 		return 0;
386 	case V4L2_CID_XILINX_TPG_MOVING_BOX:
387 		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
388 				XTPG_PATTERN_CONTROL_MOVING_BOX, ctrl->val);
389 		return 0;
390 	case V4L2_CID_XILINX_TPG_COLOR_MASK:
391 		xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
392 				 XTPG_PATTERN_CONTROL_COLOR_MASK_MASK,
393 				 ctrl->val <<
394 				 XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT);
395 		return 0;
396 	case V4L2_CID_XILINX_TPG_STUCK_PIXEL:
397 		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
398 				XTPG_PATTERN_CONTROL_STUCK_PIXEL, ctrl->val);
399 		return 0;
400 	case V4L2_CID_XILINX_TPG_NOISE:
401 		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
402 				XTPG_PATTERN_CONTROL_NOISE, ctrl->val);
403 		return 0;
404 	case V4L2_CID_XILINX_TPG_MOTION:
405 		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
406 				XTPG_PATTERN_CONTROL_MOTION, ctrl->val);
407 		return 0;
408 	case V4L2_CID_XILINX_TPG_MOTION_SPEED:
409 		xvip_write(&xtpg->xvip, XTPG_MOTION_SPEED, ctrl->val);
410 		return 0;
411 	case V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW:
412 		xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS,
413 				 XTPG_CROSS_HAIRS_ROW_MASK,
414 				 ctrl->val << XTPG_CROSS_HAIRS_ROW_SHIFT);
415 		return 0;
416 	case V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN:
417 		xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS,
418 				 XTPG_CROSS_HAIRS_COLUMN_MASK,
419 				 ctrl->val << XTPG_CROSS_HAIRS_COLUMN_SHIFT);
420 		return 0;
421 	case V4L2_CID_XILINX_TPG_ZPLATE_HOR_START:
422 		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL,
423 				 XTPG_ZPLATE_START_MASK,
424 				 ctrl->val << XTPG_ZPLATE_START_SHIFT);
425 		return 0;
426 	case V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED:
427 		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL,
428 				 XTPG_ZPLATE_SPEED_MASK,
429 				 ctrl->val << XTPG_ZPLATE_SPEED_SHIFT);
430 		return 0;
431 	case V4L2_CID_XILINX_TPG_ZPLATE_VER_START:
432 		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL,
433 				 XTPG_ZPLATE_START_MASK,
434 				 ctrl->val << XTPG_ZPLATE_START_SHIFT);
435 		return 0;
436 	case V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED:
437 		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL,
438 				 XTPG_ZPLATE_SPEED_MASK,
439 				 ctrl->val << XTPG_ZPLATE_SPEED_SHIFT);
440 		return 0;
441 	case V4L2_CID_XILINX_TPG_BOX_SIZE:
442 		xvip_write(&xtpg->xvip, XTPG_BOX_SIZE, ctrl->val);
443 		return 0;
444 	case V4L2_CID_XILINX_TPG_BOX_COLOR:
445 		xvip_write(&xtpg->xvip, XTPG_BOX_COLOR, ctrl->val);
446 		return 0;
447 	case V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH:
448 		xvip_write(&xtpg->xvip, XTPG_STUCK_PIXEL_THRESH, ctrl->val);
449 		return 0;
450 	case V4L2_CID_XILINX_TPG_NOISE_GAIN:
451 		xvip_write(&xtpg->xvip, XTPG_NOISE_GAIN, ctrl->val);
452 		return 0;
453 	}
454 
455 	return 0;
456 }
457 
458 static const struct v4l2_ctrl_ops xtpg_ctrl_ops = {
459 	.s_ctrl	= xtpg_s_ctrl,
460 };
461 
462 static const struct v4l2_subdev_core_ops xtpg_core_ops = {
463 };
464 
465 static const struct v4l2_subdev_video_ops xtpg_video_ops = {
466 	.s_stream = xtpg_s_stream,
467 };
468 
469 static const struct v4l2_subdev_pad_ops xtpg_pad_ops = {
470 	.enum_mbus_code		= xvip_enum_mbus_code,
471 	.enum_frame_size	= xtpg_enum_frame_size,
472 	.get_fmt		= xtpg_get_format,
473 	.set_fmt		= xtpg_set_format,
474 };
475 
476 static const struct v4l2_subdev_ops xtpg_ops = {
477 	.core   = &xtpg_core_ops,
478 	.video  = &xtpg_video_ops,
479 	.pad    = &xtpg_pad_ops,
480 };
481 
482 static const struct v4l2_subdev_internal_ops xtpg_internal_ops = {
483 	.open	= xtpg_open,
484 	.close	= xtpg_close,
485 };
486 
487 /*
488  * Control Config
489  */
490 
491 static const char *const xtpg_pattern_strings[] = {
492 	"Passthrough",
493 	"Horizontal Ramp",
494 	"Vertical Ramp",
495 	"Temporal Ramp",
496 	"Solid Red",
497 	"Solid Green",
498 	"Solid Blue",
499 	"Solid Black",
500 	"Solid White",
501 	"Color Bars",
502 	"Zone Plate",
503 	"Tartan Color Bars",
504 	"Cross Hatch",
505 	"None",
506 	"Vertical/Horizontal Ramps",
507 	"Black/White Checker Board",
508 };
509 
510 static struct v4l2_ctrl_config xtpg_ctrls[] = {
511 	{
512 		.ops	= &xtpg_ctrl_ops,
513 		.id	= V4L2_CID_XILINX_TPG_CROSS_HAIRS,
514 		.name	= "Test Pattern: Cross Hairs",
515 		.type	= V4L2_CTRL_TYPE_BOOLEAN,
516 		.min	= false,
517 		.max	= true,
518 		.step	= 1,
519 		.def	= 0,
520 	}, {
521 		.ops	= &xtpg_ctrl_ops,
522 		.id	= V4L2_CID_XILINX_TPG_MOVING_BOX,
523 		.name	= "Test Pattern: Moving Box",
524 		.type	= V4L2_CTRL_TYPE_BOOLEAN,
525 		.min	= false,
526 		.max	= true,
527 		.step	= 1,
528 		.def	= 0,
529 	}, {
530 		.ops	= &xtpg_ctrl_ops,
531 		.id	= V4L2_CID_XILINX_TPG_COLOR_MASK,
532 		.name	= "Test Pattern: Color Mask",
533 		.type	= V4L2_CTRL_TYPE_BITMASK,
534 		.min	= 0,
535 		.max	= 0xf,
536 		.def	= 0,
537 	}, {
538 		.ops	= &xtpg_ctrl_ops,
539 		.id	= V4L2_CID_XILINX_TPG_STUCK_PIXEL,
540 		.name	= "Test Pattern: Stuck Pixel",
541 		.type	= V4L2_CTRL_TYPE_BOOLEAN,
542 		.min	= false,
543 		.max	= true,
544 		.step	= 1,
545 		.def	= 0,
546 	}, {
547 		.ops	= &xtpg_ctrl_ops,
548 		.id	= V4L2_CID_XILINX_TPG_NOISE,
549 		.name	= "Test Pattern: Noise",
550 		.type	= V4L2_CTRL_TYPE_BOOLEAN,
551 		.min	= false,
552 		.max	= true,
553 		.step	= 1,
554 		.def	= 0,
555 	}, {
556 		.ops	= &xtpg_ctrl_ops,
557 		.id	= V4L2_CID_XILINX_TPG_MOTION,
558 		.name	= "Test Pattern: Motion",
559 		.type	= V4L2_CTRL_TYPE_BOOLEAN,
560 		.min	= false,
561 		.max	= true,
562 		.step	= 1,
563 		.def	= 0,
564 	}, {
565 		.ops	= &xtpg_ctrl_ops,
566 		.id	= V4L2_CID_XILINX_TPG_MOTION_SPEED,
567 		.name	= "Test Pattern: Motion Speed",
568 		.type	= V4L2_CTRL_TYPE_INTEGER,
569 		.min	= 0,
570 		.max	= (1 << 8) - 1,
571 		.step	= 1,
572 		.def	= 4,
573 		.flags	= V4L2_CTRL_FLAG_SLIDER,
574 	}, {
575 		.ops	= &xtpg_ctrl_ops,
576 		.id	= V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW,
577 		.name	= "Test Pattern: Cross Hairs Row",
578 		.type	= V4L2_CTRL_TYPE_INTEGER,
579 		.min	= 0,
580 		.max	= (1 << 12) - 1,
581 		.step	= 1,
582 		.def	= 0x64,
583 		.flags	= V4L2_CTRL_FLAG_SLIDER,
584 	}, {
585 		.ops	= &xtpg_ctrl_ops,
586 		.id	= V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN,
587 		.name	= "Test Pattern: Cross Hairs Column",
588 		.type	= V4L2_CTRL_TYPE_INTEGER,
589 		.min	= 0,
590 		.max	= (1 << 12) - 1,
591 		.step	= 1,
592 		.def	= 0x64,
593 		.flags	= V4L2_CTRL_FLAG_SLIDER,
594 	}, {
595 		.ops	= &xtpg_ctrl_ops,
596 		.id	= V4L2_CID_XILINX_TPG_ZPLATE_HOR_START,
597 		.name	= "Test Pattern: Zplate Horizontal Start Pos",
598 		.type	= V4L2_CTRL_TYPE_INTEGER,
599 		.min	= 0,
600 		.max	= (1 << 16) - 1,
601 		.step	= 1,
602 		.def	= 0x1e,
603 		.flags	= V4L2_CTRL_FLAG_SLIDER,
604 	}, {
605 		.ops	= &xtpg_ctrl_ops,
606 		.id	= V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED,
607 		.name	= "Test Pattern: Zplate Horizontal Speed",
608 		.type	= V4L2_CTRL_TYPE_INTEGER,
609 		.min	= 0,
610 		.max	= (1 << 16) - 1,
611 		.step	= 1,
612 		.def	= 0,
613 		.flags	= V4L2_CTRL_FLAG_SLIDER,
614 	}, {
615 		.ops	= &xtpg_ctrl_ops,
616 		.id	= V4L2_CID_XILINX_TPG_ZPLATE_VER_START,
617 		.name	= "Test Pattern: Zplate Vertical Start Pos",
618 		.type	= V4L2_CTRL_TYPE_INTEGER,
619 		.min	= 0,
620 		.max	= (1 << 16) - 1,
621 		.step	= 1,
622 		.def	= 1,
623 		.flags	= V4L2_CTRL_FLAG_SLIDER,
624 	}, {
625 		.ops	= &xtpg_ctrl_ops,
626 		.id	= V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED,
627 		.name	= "Test Pattern: Zplate Vertical Speed",
628 		.type	= V4L2_CTRL_TYPE_INTEGER,
629 		.min	= 0,
630 		.max	= (1 << 16) - 1,
631 		.step	= 1,
632 		.def	= 0,
633 		.flags	= V4L2_CTRL_FLAG_SLIDER,
634 	}, {
635 		.ops	= &xtpg_ctrl_ops,
636 		.id	= V4L2_CID_XILINX_TPG_BOX_SIZE,
637 		.name	= "Test Pattern: Box Size",
638 		.type	= V4L2_CTRL_TYPE_INTEGER,
639 		.min	= 0,
640 		.max	= (1 << 12) - 1,
641 		.step	= 1,
642 		.def	= 0x32,
643 		.flags	= V4L2_CTRL_FLAG_SLIDER,
644 	}, {
645 		.ops	= &xtpg_ctrl_ops,
646 		.id	= V4L2_CID_XILINX_TPG_BOX_COLOR,
647 		.name	= "Test Pattern: Box Color(RGB)",
648 		.type	= V4L2_CTRL_TYPE_INTEGER,
649 		.min	= 0,
650 		.max	= (1 << 24) - 1,
651 		.step	= 1,
652 		.def	= 0,
653 	}, {
654 		.ops	= &xtpg_ctrl_ops,
655 		.id	= V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH,
656 		.name	= "Test Pattern: Stuck Pixel threshold",
657 		.type	= V4L2_CTRL_TYPE_INTEGER,
658 		.min	= 0,
659 		.max	= (1 << 16) - 1,
660 		.step	= 1,
661 		.def	= 0,
662 		.flags	= V4L2_CTRL_FLAG_SLIDER,
663 	}, {
664 		.ops	= &xtpg_ctrl_ops,
665 		.id	= V4L2_CID_XILINX_TPG_NOISE_GAIN,
666 		.name	= "Test Pattern: Noise Gain",
667 		.type	= V4L2_CTRL_TYPE_INTEGER,
668 		.min	= 0,
669 		.max	= (1 << 8) - 1,
670 		.step	= 1,
671 		.def	= 0,
672 		.flags	= V4L2_CTRL_FLAG_SLIDER,
673 	},
674 };
675 
676 /* -----------------------------------------------------------------------------
677  * Media Operations
678  */
679 
680 static const struct media_entity_operations xtpg_media_ops = {
681 	.link_validate = v4l2_subdev_link_validate,
682 };
683 
684 /* -----------------------------------------------------------------------------
685  * Power Management
686  */
687 
688 static int __maybe_unused xtpg_pm_suspend(struct device *dev)
689 {
690 	struct xtpg_device *xtpg = dev_get_drvdata(dev);
691 
692 	xvip_suspend(&xtpg->xvip);
693 
694 	return 0;
695 }
696 
697 static int __maybe_unused xtpg_pm_resume(struct device *dev)
698 {
699 	struct xtpg_device *xtpg = dev_get_drvdata(dev);
700 
701 	xvip_resume(&xtpg->xvip);
702 
703 	return 0;
704 }
705 
706 /* -----------------------------------------------------------------------------
707  * Platform Device Driver
708  */
709 
710 static int xtpg_parse_of(struct xtpg_device *xtpg)
711 {
712 	struct device *dev = xtpg->xvip.dev;
713 	struct device_node *node = xtpg->xvip.dev->of_node;
714 	struct device_node *ports;
715 	struct device_node *port;
716 	unsigned int nports = 0;
717 	bool has_endpoint = false;
718 
719 	ports = of_get_child_by_name(node, "ports");
720 	if (ports == NULL)
721 		ports = node;
722 
723 	for_each_child_of_node(ports, port) {
724 		const struct xvip_video_format *format;
725 		struct device_node *endpoint;
726 
727 		if (!of_node_name_eq(port, "port"))
728 			continue;
729 
730 		format = xvip_of_get_format(port);
731 		if (IS_ERR(format)) {
732 			dev_err(dev, "invalid format in DT");
733 			of_node_put(port);
734 			return PTR_ERR(format);
735 		}
736 
737 		/* Get and check the format description */
738 		if (!xtpg->vip_format) {
739 			xtpg->vip_format = format;
740 		} else if (xtpg->vip_format != format) {
741 			dev_err(dev, "in/out format mismatch in DT");
742 			of_node_put(port);
743 			return -EINVAL;
744 		}
745 
746 		if (nports == 0) {
747 			endpoint = of_get_next_child(port, NULL);
748 			if (endpoint)
749 				has_endpoint = true;
750 			of_node_put(endpoint);
751 		}
752 
753 		/* Count the number of ports. */
754 		nports++;
755 	}
756 
757 	if (nports != 1 && nports != 2) {
758 		dev_err(dev, "invalid number of ports %u\n", nports);
759 		return -EINVAL;
760 	}
761 
762 	xtpg->npads = nports;
763 	if (nports == 2 && has_endpoint)
764 		xtpg->has_input = true;
765 
766 	return 0;
767 }
768 
769 static int xtpg_probe(struct platform_device *pdev)
770 {
771 	struct v4l2_subdev *subdev;
772 	struct xtpg_device *xtpg;
773 	u32 i, bayer_phase;
774 	int ret;
775 
776 	xtpg = devm_kzalloc(&pdev->dev, sizeof(*xtpg), GFP_KERNEL);
777 	if (!xtpg)
778 		return -ENOMEM;
779 
780 	xtpg->xvip.dev = &pdev->dev;
781 
782 	ret = xtpg_parse_of(xtpg);
783 	if (ret < 0)
784 		return ret;
785 
786 	ret = xvip_init_resources(&xtpg->xvip);
787 	if (ret < 0)
788 		return ret;
789 
790 	xtpg->vtmux_gpio = devm_gpiod_get_optional(&pdev->dev, "timing",
791 						   GPIOD_OUT_HIGH);
792 	if (IS_ERR(xtpg->vtmux_gpio)) {
793 		ret = PTR_ERR(xtpg->vtmux_gpio);
794 		goto error_resource;
795 	}
796 
797 	xtpg->vtc = xvtc_of_get(pdev->dev.of_node);
798 	if (IS_ERR(xtpg->vtc)) {
799 		ret = PTR_ERR(xtpg->vtc);
800 		goto error_resource;
801 	}
802 
803 	/* Reset and initialize the core */
804 	xvip_reset(&xtpg->xvip);
805 
806 	/* Initialize V4L2 subdevice and media entity. Pad numbers depend on the
807 	 * number of pads.
808 	 */
809 	if (xtpg->npads == 2) {
810 		xtpg->pads[0].flags = MEDIA_PAD_FL_SINK;
811 		xtpg->pads[1].flags = MEDIA_PAD_FL_SOURCE;
812 	} else {
813 		xtpg->pads[0].flags = MEDIA_PAD_FL_SOURCE;
814 	}
815 
816 	/* Initialize the default format */
817 	xtpg->default_format.code = xtpg->vip_format->code;
818 	xtpg->default_format.field = V4L2_FIELD_NONE;
819 	xtpg->default_format.colorspace = V4L2_COLORSPACE_SRGB;
820 	xvip_get_frame_size(&xtpg->xvip, &xtpg->default_format);
821 
822 	bayer_phase = xtpg_get_bayer_phase(xtpg->vip_format->code);
823 	if (bayer_phase != XTPG_BAYER_PHASE_OFF)
824 		xtpg->bayer = true;
825 
826 	xtpg->formats[0] = xtpg->default_format;
827 	if (xtpg->npads == 2)
828 		xtpg->formats[1] = xtpg->default_format;
829 
830 	/* Initialize V4L2 subdevice and media entity */
831 	subdev = &xtpg->xvip.subdev;
832 	v4l2_subdev_init(subdev, &xtpg_ops);
833 	subdev->dev = &pdev->dev;
834 	subdev->internal_ops = &xtpg_internal_ops;
835 	strscpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
836 	v4l2_set_subdevdata(subdev, xtpg);
837 	subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
838 	subdev->entity.ops = &xtpg_media_ops;
839 
840 	ret = media_entity_pads_init(&subdev->entity, xtpg->npads, xtpg->pads);
841 	if (ret < 0)
842 		goto error;
843 
844 	v4l2_ctrl_handler_init(&xtpg->ctrl_handler, 3 + ARRAY_SIZE(xtpg_ctrls));
845 
846 	xtpg->vblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops,
847 					 V4L2_CID_VBLANK, XTPG_MIN_VBLANK,
848 					 XTPG_MAX_VBLANK, 1, 100);
849 	xtpg->hblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops,
850 					 V4L2_CID_HBLANK, XTPG_MIN_HBLANK,
851 					 XTPG_MAX_HBLANK, 1, 100);
852 	xtpg->pattern = v4l2_ctrl_new_std_menu_items(&xtpg->ctrl_handler,
853 					&xtpg_ctrl_ops, V4L2_CID_TEST_PATTERN,
854 					ARRAY_SIZE(xtpg_pattern_strings) - 1,
855 					1, 9, xtpg_pattern_strings);
856 
857 	for (i = 0; i < ARRAY_SIZE(xtpg_ctrls); i++)
858 		v4l2_ctrl_new_custom(&xtpg->ctrl_handler, &xtpg_ctrls[i], NULL);
859 
860 	if (xtpg->ctrl_handler.error) {
861 		dev_err(&pdev->dev, "failed to add controls\n");
862 		ret = xtpg->ctrl_handler.error;
863 		goto error;
864 	}
865 	subdev->ctrl_handler = &xtpg->ctrl_handler;
866 
867 	xtpg_update_pattern_control(xtpg, true, true);
868 
869 	ret = v4l2_ctrl_handler_setup(&xtpg->ctrl_handler);
870 	if (ret < 0) {
871 		dev_err(&pdev->dev, "failed to set controls\n");
872 		goto error;
873 	}
874 
875 	platform_set_drvdata(pdev, xtpg);
876 
877 	xvip_print_version(&xtpg->xvip);
878 
879 	ret = v4l2_async_register_subdev(subdev);
880 	if (ret < 0) {
881 		dev_err(&pdev->dev, "failed to register subdev\n");
882 		goto error;
883 	}
884 
885 	return 0;
886 
887 error:
888 	v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
889 	media_entity_cleanup(&subdev->entity);
890 	xvtc_put(xtpg->vtc);
891 error_resource:
892 	xvip_cleanup_resources(&xtpg->xvip);
893 	return ret;
894 }
895 
896 static void xtpg_remove(struct platform_device *pdev)
897 {
898 	struct xtpg_device *xtpg = platform_get_drvdata(pdev);
899 	struct v4l2_subdev *subdev = &xtpg->xvip.subdev;
900 
901 	v4l2_async_unregister_subdev(subdev);
902 	v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
903 	media_entity_cleanup(&subdev->entity);
904 
905 	xvip_cleanup_resources(&xtpg->xvip);
906 }
907 
908 static SIMPLE_DEV_PM_OPS(xtpg_pm_ops, xtpg_pm_suspend, xtpg_pm_resume);
909 
910 static const struct of_device_id xtpg_of_id_table[] = {
911 	{ .compatible = "xlnx,v-tpg-5.0" },
912 	{ }
913 };
914 MODULE_DEVICE_TABLE(of, xtpg_of_id_table);
915 
916 static struct platform_driver xtpg_driver = {
917 	.driver = {
918 		.name		= "xilinx-tpg",
919 		.pm		= &xtpg_pm_ops,
920 		.of_match_table	= xtpg_of_id_table,
921 	},
922 	.probe			= xtpg_probe,
923 	.remove_new		= xtpg_remove,
924 };
925 
926 module_platform_driver(xtpg_driver);
927 
928 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
929 MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver");
930 MODULE_LICENSE("GPL v2");
931