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