1123475Swpaul// SPDX-License-Identifier: GPL-2.0
2123475Swpaul/*
3123475Swpaul * Xilinx Test Pattern Generator
4123475Swpaul *
5123475Swpaul * Copyright (C) 2013-2015 Ideas on Board
6123475Swpaul * Copyright (C) 2013-2015 Xilinx, Inc.
7123475Swpaul *
8123475Swpaul * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
9123475Swpaul *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10123475Swpaul */
11123475Swpaul
12123475Swpaul#include <linux/device.h>
13123475Swpaul#include <linux/gpio/consumer.h>
14123475Swpaul#include <linux/module.h>
15123475Swpaul#include <linux/of.h>
16123475Swpaul#include <linux/platform_device.h>
17123475Swpaul#include <linux/xilinx-v4l2-controls.h>
18123475Swpaul
19123475Swpaul#include <media/v4l2-async.h>
20123475Swpaul#include <media/v4l2-ctrls.h>
21123475Swpaul#include <media/v4l2-subdev.h>
22123475Swpaul
23123475Swpaul#include "xilinx-vip.h"
24123475Swpaul#include "xilinx-vtc.h"
25123475Swpaul
26123475Swpaul#define XTPG_CTRL_STATUS_SLAVE_ERROR		(1 << 16)
27123475Swpaul#define XTPG_CTRL_IRQ_SLAVE_ERROR		(1 << 16)
28123475Swpaul
29123475Swpaul#define XTPG_PATTERN_CONTROL			0x0100
30123475Swpaul#define XTPG_PATTERN_MASK			(0xf << 0)
31123475Swpaul#define XTPG_PATTERN_CONTROL_CROSS_HAIRS	(1 << 4)
32123475Swpaul#define XTPG_PATTERN_CONTROL_MOVING_BOX		(1 << 5)
33123475Swpaul#define XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT	6
34123475Swpaul#define XTPG_PATTERN_CONTROL_COLOR_MASK_MASK	(0xf << 6)
35123475Swpaul#define XTPG_PATTERN_CONTROL_STUCK_PIXEL	(1 << 9)
36123475Swpaul#define XTPG_PATTERN_CONTROL_NOISE		(1 << 10)
37123475Swpaul#define XTPG_PATTERN_CONTROL_MOTION		(1 << 12)
38123475Swpaul#define XTPG_MOTION_SPEED			0x0104
39123475Swpaul#define XTPG_CROSS_HAIRS			0x0108
40123475Swpaul#define XTPG_CROSS_HAIRS_ROW_SHIFT		0
41123475Swpaul#define XTPG_CROSS_HAIRS_ROW_MASK		(0xfff << 0)
42123475Swpaul#define XTPG_CROSS_HAIRS_COLUMN_SHIFT		16
43123475Swpaul#define XTPG_CROSS_HAIRS_COLUMN_MASK		(0xfff << 16)
44123475Swpaul#define XTPG_ZPLATE_HOR_CONTROL			0x010c
45123475Swpaul#define XTPG_ZPLATE_VER_CONTROL			0x0110
46123475Swpaul#define XTPG_ZPLATE_START_SHIFT			0
47123475Swpaul#define XTPG_ZPLATE_START_MASK			(0xffff << 0)
48123475Swpaul#define XTPG_ZPLATE_SPEED_SHIFT			16
49123475Swpaul#define XTPG_ZPLATE_SPEED_MASK			(0xffff << 16)
50123475Swpaul#define XTPG_BOX_SIZE				0x0114
51123475Swpaul#define XTPG_BOX_COLOR				0x0118
52123475Swpaul#define XTPG_STUCK_PIXEL_THRESH			0x011c
53123475Swpaul#define XTPG_NOISE_GAIN				0x0120
54123475Swpaul#define XTPG_BAYER_PHASE			0x0124
55123475Swpaul#define XTPG_BAYER_PHASE_RGGB			0
56123475Swpaul#define XTPG_BAYER_PHASE_GRBG			1
57123475Swpaul#define XTPG_BAYER_PHASE_GBRG			2
58123475Swpaul#define XTPG_BAYER_PHASE_BGGR			3
59123475Swpaul#define XTPG_BAYER_PHASE_OFF			4
60123475Swpaul
61123475Swpaul/*
62123475Swpaul * The minimum blanking value is one clock cycle for the front porch, one clock
63123475Swpaul * cycle for the sync pulse and one clock cycle for the back porch.
64123475Swpaul */
65123475Swpaul#define XTPG_MIN_HBLANK			3
66123475Swpaul#define XTPG_MAX_HBLANK			(XVTC_MAX_HSIZE - XVIP_MIN_WIDTH)
67123475Swpaul#define XTPG_MIN_VBLANK			3
68123475Swpaul#define XTPG_MAX_VBLANK			(XVTC_MAX_VSIZE - XVIP_MIN_HEIGHT)
69123475Swpaul
70123475Swpaul/**
71123475Swpaul * struct xtpg_device - Xilinx Test Pattern Generator device structure
72123475Swpaul * @xvip: Xilinx Video IP device
73123475Swpaul * @pads: media pads
74123475Swpaul * @npads: number of pads (1 or 2)
75123475Swpaul * @has_input: whether an input is connected to the sink pad
76123475Swpaul * @formats: active V4L2 media bus format for each pad
77123475Swpaul * @default_format: default V4L2 media bus format
78123475Swpaul * @vip_format: format information corresponding to the active format
79123475Swpaul * @bayer: boolean flag if TPG is set to any bayer format
80123475Swpaul * @ctrl_handler: control handler
81123475Swpaul * @hblank: horizontal blanking control
82123475Swpaul * @vblank: vertical blanking control
83123475Swpaul * @pattern: test pattern control
84123475Swpaul * @streaming: is the video stream active
85123475Swpaul * @vtc: video timing controller
86123475Swpaul * @vtmux_gpio: video timing mux GPIO
87123475Swpaul */
88123475Swpaulstruct xtpg_device {
89123475Swpaul	struct xvip_device xvip;
90123475Swpaul
91123475Swpaul	struct media_pad pads[2];
92123475Swpaul	unsigned int npads;
93123475Swpaul	bool has_input;
94123475Swpaul
95123475Swpaul	struct v4l2_mbus_framefmt formats[2];
96123475Swpaul	struct v4l2_mbus_framefmt default_format;
97123475Swpaul	const struct xvip_video_format *vip_format;
98123475Swpaul	bool bayer;
99123475Swpaul
100123475Swpaul	struct v4l2_ctrl_handler ctrl_handler;
101123475Swpaul	struct v4l2_ctrl *hblank;
102123475Swpaul	struct v4l2_ctrl *vblank;
103123475Swpaul	struct v4l2_ctrl *pattern;
104123475Swpaul	bool streaming;
105123475Swpaul
106123475Swpaul	struct xvtc_device *vtc;
107123475Swpaul	struct gpio_desc *vtmux_gpio;
108123475Swpaul};
109123475Swpaul
110123475Swpaulstatic inline struct xtpg_device *to_tpg(struct v4l2_subdev *subdev)
111123475Swpaul{
112123475Swpaul	return container_of(subdev, struct xtpg_device, xvip.subdev);
113123475Swpaul}
114123475Swpaul
115123475Swpaulstatic u32 xtpg_get_bayer_phase(unsigned int code)
116123475Swpaul{
117123475Swpaul	switch (code) {
118123475Swpaul	case MEDIA_BUS_FMT_SRGGB8_1X8:
119123475Swpaul		return XTPG_BAYER_PHASE_RGGB;
120123475Swpaul	case MEDIA_BUS_FMT_SGRBG8_1X8:
121123475Swpaul		return XTPG_BAYER_PHASE_GRBG;
122123475Swpaul	case MEDIA_BUS_FMT_SGBRG8_1X8:
123123475Swpaul		return XTPG_BAYER_PHASE_GBRG;
124123475Swpaul	case MEDIA_BUS_FMT_SBGGR8_1X8:
125123475Swpaul		return XTPG_BAYER_PHASE_BGGR;
126123475Swpaul	default:
127123475Swpaul		return XTPG_BAYER_PHASE_OFF;
128123475Swpaul	}
129123475Swpaul}
130123475Swpaul
131123475Swpaulstatic void __xtpg_update_pattern_control(struct xtpg_device *xtpg,
132123475Swpaul					  bool passthrough, bool pattern)
133123475Swpaul{
134123475Swpaul	u32 pattern_mask = (1 << (xtpg->pattern->maximum + 1)) - 1;
135123475Swpaul
136123475Swpaul	/*
137123475Swpaul	 * If the TPG has no sink pad or no input connected to its sink pad
138123475Swpaul	 * passthrough mode can't be enabled.
139123475Swpaul	 */
140123475Swpaul	if (xtpg->npads == 1 || !xtpg->has_input)
141123475Swpaul		passthrough = false;
142123475Swpaul
143123475Swpaul	/* If passthrough mode is allowed unmask bit 0. */
144123475Swpaul	if (passthrough)
145123475Swpaul		pattern_mask &= ~1;
146123475Swpaul
147123475Swpaul	/* If test pattern mode is allowed unmask all other bits. */
148123475Swpaul	if (pattern)
149123483Swpaul		pattern_mask &= 1;
150123475Swpaul
151123475Swpaul	__v4l2_ctrl_modify_range(xtpg->pattern, 0, xtpg->pattern->maximum,
152123475Swpaul				 pattern_mask, pattern ? 9 : 0);
153123475Swpaul}
154123475Swpaul
155123483Swpaulstatic void xtpg_update_pattern_control(struct xtpg_device *xtpg,
156123483Swpaul					bool passthrough, bool pattern)
157123483Swpaul{
158123483Swpaul	mutex_lock(xtpg->ctrl_handler.lock);
159123483Swpaul	__xtpg_update_pattern_control(xtpg, passthrough, pattern);
160123483Swpaul	mutex_unlock(xtpg->ctrl_handler.lock);
161123483Swpaul}
162123483Swpaul
163123475Swpaul/* -----------------------------------------------------------------------------
164123475Swpaul * V4L2 Subdevice Video Operations
165123475Swpaul */
166123475Swpaul
167123475Swpaulstatic int xtpg_s_stream(struct v4l2_subdev *subdev, int enable)
168123475Swpaul{
169123475Swpaul	struct xtpg_device *xtpg = to_tpg(subdev);
170123475Swpaul	unsigned int width = xtpg->formats[0].width;
171123475Swpaul	unsigned int height = xtpg->formats[0].height;
172123475Swpaul	bool passthrough;
173123475Swpaul	u32 bayer_phase;
174123475Swpaul
175123475Swpaul	if (!enable) {
176123475Swpaul		xvip_stop(&xtpg->xvip);
177123475Swpaul		if (xtpg->vtc)
178123475Swpaul			xvtc_generator_stop(xtpg->vtc);
179123475Swpaul
180123475Swpaul		xtpg_update_pattern_control(xtpg, true, true);
181123475Swpaul		xtpg->streaming = false;
182123475Swpaul		return 0;
183123475Swpaul	}
184123480Swpaul
185123475Swpaul	xvip_set_frame_size(&xtpg->xvip, &xtpg->formats[0]);
186123475Swpaul
187123475Swpaul	if (xtpg->vtc) {
188123475Swpaul		struct xvtc_config config = {
189123475Swpaul			.hblank_start = width,
190123480Swpaul			.hsync_start = width + 1,
191123480Swpaul			.vblank_start = height,
192123475Swpaul			.vsync_start = height + 1,
193123475Swpaul		};
194123475Swpaul		unsigned int htotal;
195123475Swpaul		unsigned int vtotal;
196123475Swpaul
197123475Swpaul		htotal = min_t(unsigned int, XVTC_MAX_HSIZE,
198123475Swpaul			       v4l2_ctrl_g_ctrl(xtpg->hblank) + width);
199123475Swpaul		vtotal = min_t(unsigned int, XVTC_MAX_VSIZE,
200123475Swpaul			       v4l2_ctrl_g_ctrl(xtpg->vblank) + height);
201123475Swpaul
202123475Swpaul		config.hsync_end = htotal - 1;
203123475Swpaul		config.hsize = htotal;
204123475Swpaul		config.vsync_end = vtotal - 1;
205123475Swpaul		config.vsize = vtotal;
206123475Swpaul
207123475Swpaul		xvtc_generator_start(xtpg->vtc, &config);
208123475Swpaul	}
209123475Swpaul
210123475Swpaul	/*
211123475Swpaul	 * Configure the bayer phase and video timing mux based on the
212123475Swpaul	 * operation mode (passthrough or test pattern generation). The test
213123475Swpaul	 * pattern can be modified by the control set handler, we thus need to
214123475Swpaul	 * take the control lock here to avoid races.
215123475Swpaul	 */
216123475Swpaul	mutex_lock(xtpg->ctrl_handler.lock);
217123483Swpaul
218123475Swpaul	xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
219123475Swpaul			 XTPG_PATTERN_MASK, xtpg->pattern->cur.val);
220123475Swpaul
221123475Swpaul	/*
222123475Swpaul	 * Switching between passthrough and test pattern generation modes isn't
223123475Swpaul	 * allowed during streaming, update the control range accordingly.
224123475Swpaul	 */
225123475Swpaul	passthrough = xtpg->pattern->cur.val == 0;
226123475Swpaul	__xtpg_update_pattern_control(xtpg, passthrough, !passthrough);
227123475Swpaul
228123475Swpaul	xtpg->streaming = true;
229123475Swpaul
230123475Swpaul	mutex_unlock(xtpg->ctrl_handler.lock);
231123475Swpaul
232123475Swpaul	/*
233123475Swpaul	 * For TPG v5.0, the bayer phase needs to be off for the pass through
234123475Swpaul	 * mode, otherwise the external input would be subsampled.
235123475Swpaul	 */
236123475Swpaul	bayer_phase = passthrough ? XTPG_BAYER_PHASE_OFF
237123475Swpaul		    : xtpg_get_bayer_phase(xtpg->formats[0].code);
238123475Swpaul	xvip_write(&xtpg->xvip, XTPG_BAYER_PHASE, bayer_phase);
239123475Swpaul
240123483Swpaul	if (xtpg->vtmux_gpio)
241123483Swpaul		gpiod_set_value_cansleep(xtpg->vtmux_gpio, !passthrough);
242123475Swpaul
243123475Swpaul	xvip_start(&xtpg->xvip);
244123475Swpaul
245123475Swpaul	return 0;
246123475Swpaul}
247123475Swpaul
248123475Swpaul/* -----------------------------------------------------------------------------
249123475Swpaul * V4L2 Subdevice Pad Operations
250123475Swpaul */
251123475Swpaul
252123475Swpaulstatic struct v4l2_mbus_framefmt *
253123475Swpaul__xtpg_get_pad_format(struct xtpg_device *xtpg,
254123475Swpaul		      struct v4l2_subdev_state *sd_state,
255123475Swpaul		      unsigned int pad, u32 which)
256123475Swpaul{
257123475Swpaul	switch (which) {
258123475Swpaul	case V4L2_SUBDEV_FORMAT_TRY:
259123475Swpaul		return v4l2_subdev_state_get_format(sd_state, pad);
260123475Swpaul	case V4L2_SUBDEV_FORMAT_ACTIVE:
261123475Swpaul		return &xtpg->formats[pad];
262123475Swpaul	default:
263123475Swpaul		return NULL;
264123475Swpaul	}
265123475Swpaul}
266123475Swpaul
267123475Swpaulstatic int xtpg_get_format(struct v4l2_subdev *subdev,
268123475Swpaul			   struct v4l2_subdev_state *sd_state,
269123475Swpaul			   struct v4l2_subdev_format *fmt)
270123475Swpaul{
271123475Swpaul	struct xtpg_device *xtpg = to_tpg(subdev);
272123475Swpaul
273123475Swpaul	fmt->format = *__xtpg_get_pad_format(xtpg, sd_state, fmt->pad,
274123475Swpaul					     fmt->which);
275123475Swpaul
276123475Swpaul	return 0;
277123475Swpaul}
278123475Swpaul
279123475Swpaulstatic int xtpg_set_format(struct v4l2_subdev *subdev,
280123475Swpaul			   struct v4l2_subdev_state *sd_state,
281123475Swpaul			   struct v4l2_subdev_format *fmt)
282123475Swpaul{
283123475Swpaul	struct xtpg_device *xtpg = to_tpg(subdev);
284123475Swpaul	struct v4l2_mbus_framefmt *__format;
285123475Swpaul	u32 bayer_phase;
286123475Swpaul
287123475Swpaul	__format = __xtpg_get_pad_format(xtpg, sd_state, fmt->pad, fmt->which);
288123475Swpaul
289123475Swpaul	/* In two pads mode the source pad format is always identical to the
290123475Swpaul	 * sink pad format.
291123475Swpaul	 */
292123475Swpaul	if (xtpg->npads == 2 && fmt->pad == 1) {
293123475Swpaul		fmt->format = *__format;
294123475Swpaul		return 0;
295123475Swpaul	}
296123475Swpaul
297123475Swpaul	/* Bayer phase is configurable at runtime */
298123475Swpaul	if (xtpg->bayer) {
299123475Swpaul		bayer_phase = xtpg_get_bayer_phase(fmt->format.code);
300123475Swpaul		if (bayer_phase != XTPG_BAYER_PHASE_OFF)
301123475Swpaul			__format->code = fmt->format.code;
302123475Swpaul	}
303123475Swpaul
304123475Swpaul	xvip_set_format_size(__format, fmt);
305123475Swpaul
306123475Swpaul	fmt->format = *__format;
307123475Swpaul
308123475Swpaul	/* Propagate the format to the source pad. */
309123475Swpaul	if (xtpg->npads == 2) {
310123475Swpaul		__format = __xtpg_get_pad_format(xtpg, sd_state, 1,
311123475Swpaul						 fmt->which);
312123475Swpaul		*__format = fmt->format;
313123475Swpaul	}
314123475Swpaul
315123475Swpaul	return 0;
316123475Swpaul}
317123475Swpaul
318123475Swpaul/* -----------------------------------------------------------------------------
319123475Swpaul * V4L2 Subdevice Operations
320123475Swpaul */
321123475Swpaul
322123475Swpaulstatic int xtpg_enum_frame_size(struct v4l2_subdev *subdev,
323123475Swpaul				struct v4l2_subdev_state *sd_state,
324123475Swpaul				struct v4l2_subdev_frame_size_enum *fse)
325123475Swpaul{
326123475Swpaul	struct v4l2_mbus_framefmt *format;
327123475Swpaul
328123475Swpaul	format = v4l2_subdev_state_get_format(sd_state, fse->pad);
329123475Swpaul
330123475Swpaul	if (fse->index || fse->code != format->code)
331123475Swpaul		return -EINVAL;
332123475Swpaul
333123475Swpaul	/* Min / max values for pad 0 is always fixed in both one and two pads
334123475Swpaul	 * modes. In two pads mode, the source pad(= 1) size is identical to
335123475Swpaul	 * the sink pad size */
336123475Swpaul	if (fse->pad == 0) {
337123475Swpaul		fse->min_width = XVIP_MIN_WIDTH;
338123475Swpaul		fse->max_width = XVIP_MAX_WIDTH;
339123475Swpaul		fse->min_height = XVIP_MIN_HEIGHT;
340123475Swpaul		fse->max_height = XVIP_MAX_HEIGHT;
341123475Swpaul	} else {
342123475Swpaul		fse->min_width = format->width;
343123475Swpaul		fse->max_width = format->width;
344123475Swpaul		fse->min_height = format->height;
345123475Swpaul		fse->max_height = format->height;
346123475Swpaul	}
347123475Swpaul
348123475Swpaul	return 0;
349123475Swpaul}
350123475Swpaul
351123475Swpaulstatic int xtpg_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
352123475Swpaul{
353123475Swpaul	struct xtpg_device *xtpg = to_tpg(subdev);
354123475Swpaul	struct v4l2_mbus_framefmt *format;
355123475Swpaul
356123475Swpaul	format = v4l2_subdev_state_get_format(fh->state, 0);
357123475Swpaul	*format = xtpg->default_format;
358123475Swpaul
359123475Swpaul	if (xtpg->npads == 2) {
360123475Swpaul		format = v4l2_subdev_state_get_format(fh->state, 1);
361123475Swpaul		*format = xtpg->default_format;
362123475Swpaul	}
363123475Swpaul
364123483Swpaul	return 0;
365123475Swpaul}
366123475Swpaul
367123475Swpaulstatic int xtpg_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
368123475Swpaul{
369123475Swpaul	return 0;
370123475Swpaul}
371123475Swpaul
372123483Swpaulstatic int xtpg_s_ctrl(struct v4l2_ctrl *ctrl)
373123483Swpaul{
374123483Swpaul	struct xtpg_device *xtpg = container_of(ctrl->handler,
375123483Swpaul						struct xtpg_device,
376123483Swpaul						ctrl_handler);
377123483Swpaul	switch (ctrl->id) {
378123483Swpaul	case V4L2_CID_TEST_PATTERN:
379123483Swpaul		xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
380123483Swpaul				 XTPG_PATTERN_MASK, ctrl->val);
381123475Swpaul		return 0;
382123475Swpaul	case V4L2_CID_XILINX_TPG_CROSS_HAIRS:
383123475Swpaul		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
384123475Swpaul				XTPG_PATTERN_CONTROL_CROSS_HAIRS, ctrl->val);
385123475Swpaul		return 0;
386123475Swpaul	case V4L2_CID_XILINX_TPG_MOVING_BOX:
387123475Swpaul		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
388123475Swpaul				XTPG_PATTERN_CONTROL_MOVING_BOX, ctrl->val);
389123475Swpaul		return 0;
390123475Swpaul	case V4L2_CID_XILINX_TPG_COLOR_MASK:
391123475Swpaul		xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
392123475Swpaul				 XTPG_PATTERN_CONTROL_COLOR_MASK_MASK,
393123475Swpaul				 ctrl->val <<
394123475Swpaul				 XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT);
395123475Swpaul		return 0;
396123475Swpaul	case V4L2_CID_XILINX_TPG_STUCK_PIXEL:
397123475Swpaul		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
398123475Swpaul				XTPG_PATTERN_CONTROL_STUCK_PIXEL, ctrl->val);
399123475Swpaul		return 0;
400123483Swpaul	case V4L2_CID_XILINX_TPG_NOISE:
401123483Swpaul		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
402123483Swpaul				XTPG_PATTERN_CONTROL_NOISE, ctrl->val);
403123483Swpaul		return 0;
404123483Swpaul	case V4L2_CID_XILINX_TPG_MOTION:
405123483Swpaul		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
406123483Swpaul				XTPG_PATTERN_CONTROL_MOTION, ctrl->val);
407123483Swpaul		return 0;
408123483Swpaul	case V4L2_CID_XILINX_TPG_MOTION_SPEED:
409123483Swpaul		xvip_write(&xtpg->xvip, XTPG_MOTION_SPEED, ctrl->val);
410123483Swpaul		return 0;
411123483Swpaul	case V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW:
412123483Swpaul		xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS,
413123483Swpaul				 XTPG_CROSS_HAIRS_ROW_MASK,
414123475Swpaul				 ctrl->val << XTPG_CROSS_HAIRS_ROW_SHIFT);
415123475Swpaul		return 0;
416123475Swpaul	case V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN:
417123475Swpaul		xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS,
418123475Swpaul				 XTPG_CROSS_HAIRS_COLUMN_MASK,
419123475Swpaul				 ctrl->val << XTPG_CROSS_HAIRS_COLUMN_SHIFT);
420123475Swpaul		return 0;
421123475Swpaul	case V4L2_CID_XILINX_TPG_ZPLATE_HOR_START:
422123475Swpaul		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL,
423123475Swpaul				 XTPG_ZPLATE_START_MASK,
424123475Swpaul				 ctrl->val << XTPG_ZPLATE_START_SHIFT);
425123475Swpaul		return 0;
426123475Swpaul	case V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED:
427123475Swpaul		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL,
428123475Swpaul				 XTPG_ZPLATE_SPEED_MASK,
429123475Swpaul				 ctrl->val << XTPG_ZPLATE_SPEED_SHIFT);
430123475Swpaul		return 0;
431123475Swpaul	case V4L2_CID_XILINX_TPG_ZPLATE_VER_START:
432123475Swpaul		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL,
433123475Swpaul				 XTPG_ZPLATE_START_MASK,
434123475Swpaul				 ctrl->val << XTPG_ZPLATE_START_SHIFT);
435123475Swpaul		return 0;
436123475Swpaul	case V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED:
437123475Swpaul		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL,
438123475Swpaul				 XTPG_ZPLATE_SPEED_MASK,
439123475Swpaul				 ctrl->val << XTPG_ZPLATE_SPEED_SHIFT);
440123475Swpaul		return 0;
441123475Swpaul	case V4L2_CID_XILINX_TPG_BOX_SIZE:
442123475Swpaul		xvip_write(&xtpg->xvip, XTPG_BOX_SIZE, ctrl->val);
443123475Swpaul		return 0;
444123475Swpaul	case V4L2_CID_XILINX_TPG_BOX_COLOR:
445123475Swpaul		xvip_write(&xtpg->xvip, XTPG_BOX_COLOR, ctrl->val);
446123475Swpaul		return 0;
447123475Swpaul	case V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH:
448123475Swpaul		xvip_write(&xtpg->xvip, XTPG_STUCK_PIXEL_THRESH, ctrl->val);
449123475Swpaul		return 0;
450123475Swpaul	case V4L2_CID_XILINX_TPG_NOISE_GAIN:
451123475Swpaul		xvip_write(&xtpg->xvip, XTPG_NOISE_GAIN, ctrl->val);
452123475Swpaul		return 0;
453123475Swpaul	}
454123475Swpaul
455123475Swpaul	return 0;
456123475Swpaul}
457123475Swpaul
458123475Swpaulstatic const struct v4l2_ctrl_ops xtpg_ctrl_ops = {
459123475Swpaul	.s_ctrl	= xtpg_s_ctrl,
460123475Swpaul};
461123475Swpaul
462123475Swpaulstatic const struct v4l2_subdev_core_ops xtpg_core_ops = {
463123475Swpaul};
464123475Swpaul
465123475Swpaulstatic const struct v4l2_subdev_video_ops xtpg_video_ops = {
466123475Swpaul	.s_stream = xtpg_s_stream,
467123475Swpaul};
468123475Swpaul
469123475Swpaulstatic const struct v4l2_subdev_pad_ops xtpg_pad_ops = {
470123475Swpaul	.enum_mbus_code		= xvip_enum_mbus_code,
471123475Swpaul	.enum_frame_size	= xtpg_enum_frame_size,
472123475Swpaul	.get_fmt		= xtpg_get_format,
473123475Swpaul	.set_fmt		= xtpg_set_format,
474123475Swpaul};
475123475Swpaul
476123475Swpaulstatic const struct v4l2_subdev_ops xtpg_ops = {
477123475Swpaul	.core   = &xtpg_core_ops,
478123475Swpaul	.video  = &xtpg_video_ops,
479123475Swpaul	.pad    = &xtpg_pad_ops,
480123475Swpaul};
481123475Swpaul
482123475Swpaulstatic const struct v4l2_subdev_internal_ops xtpg_internal_ops = {
483123475Swpaul	.open	= xtpg_open,
484123475Swpaul	.close	= xtpg_close,
485123475Swpaul};
486123475Swpaul
487123475Swpaul/*
488123475Swpaul * Control Config
489123475Swpaul */
490123475Swpaul
491123475Swpaulstatic const char *const xtpg_pattern_strings[] = {
492123475Swpaul	"Passthrough",
493123475Swpaul	"Horizontal Ramp",
494123475Swpaul	"Vertical Ramp",
495123475Swpaul	"Temporal Ramp",
496123475Swpaul	"Solid Red",
497123475Swpaul	"Solid Green",
498123475Swpaul	"Solid Blue",
499123475Swpaul	"Solid Black",
500123475Swpaul	"Solid White",
501123475Swpaul	"Color Bars",
502123475Swpaul	"Zone Plate",
503123475Swpaul	"Tartan Color Bars",
504123475Swpaul	"Cross Hatch",
505123475Swpaul	"None",
506123475Swpaul	"Vertical/Horizontal Ramps",
507123475Swpaul	"Black/White Checker Board",
508123475Swpaul};
509123475Swpaul
510123475Swpaulstatic struct v4l2_ctrl_config xtpg_ctrls[] = {
511123475Swpaul	{
512123475Swpaul		.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
680static const struct media_entity_operations xtpg_media_ops = {
681	.link_validate = v4l2_subdev_link_validate,
682};
683
684/* -----------------------------------------------------------------------------
685 * Power Management
686 */
687
688static 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
697static 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
710static 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
769static 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
887error:
888	v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
889	media_entity_cleanup(&subdev->entity);
890	xvtc_put(xtpg->vtc);
891error_resource:
892	xvip_cleanup_resources(&xtpg->xvip);
893	return ret;
894}
895
896static 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
908static SIMPLE_DEV_PM_OPS(xtpg_pm_ops, xtpg_pm_suspend, xtpg_pm_resume);
909
910static const struct of_device_id xtpg_of_id_table[] = {
911	{ .compatible = "xlnx,v-tpg-5.0" },
912	{ }
913};
914MODULE_DEVICE_TABLE(of, xtpg_of_id_table);
915
916static 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
926module_platform_driver(xtpg_driver);
927
928MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
929MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver");
930MODULE_LICENSE("GPL v2");
931