xref: /openbmc/linux/drivers/media/test-drivers/visl/visl.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1*0c078e31SDaniel Almeida /* SPDX-License-Identifier: GPL-2.0 */
2*0c078e31SDaniel Almeida /*
3*0c078e31SDaniel Almeida  * A virtual stateless device for stateless uAPI development purposes.
4*0c078e31SDaniel Almeida  *
5*0c078e31SDaniel Almeida  * This tool's objective is to help the development and testing of userspace
6*0c078e31SDaniel Almeida  * applications that use the V4L2 stateless API to decode media.
7*0c078e31SDaniel Almeida  *
8*0c078e31SDaniel Almeida  * A userspace implementation can use visl to run a decoding loop even when no
9*0c078e31SDaniel Almeida  * hardware is available or when the kernel uAPI for the codec has not been
10*0c078e31SDaniel Almeida  * upstreamed yet. This can reveal bugs at an early stage.
11*0c078e31SDaniel Almeida  *
12*0c078e31SDaniel Almeida  * This driver can also trace the contents of the V4L2 controls submitted to it.
13*0c078e31SDaniel Almeida  * It can also dump the contents of the vb2 buffers through a debugfs
14*0c078e31SDaniel Almeida  * interface. This is in many ways similar to the tracing infrastructure
15*0c078e31SDaniel Almeida  * available for other popular encode/decode APIs out there and can help develop
16*0c078e31SDaniel Almeida  * a userspace application by using another (working) one as a reference.
17*0c078e31SDaniel Almeida  *
18*0c078e31SDaniel Almeida  * Note that no actual decoding of video frames is performed by visl. The V4L2
19*0c078e31SDaniel Almeida  * test pattern generator is used to write various debug information to the
20*0c078e31SDaniel Almeida  * capture buffers instead.
21*0c078e31SDaniel Almeida  *
22*0c078e31SDaniel Almeida  * Copyright (C) 2022 Collabora, Ltd.
23*0c078e31SDaniel Almeida  *
24*0c078e31SDaniel Almeida  * Based on the vim2m driver, that is:
25*0c078e31SDaniel Almeida  *
26*0c078e31SDaniel Almeida  * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
27*0c078e31SDaniel Almeida  * Pawel Osciak, <pawel@osciak.com>
28*0c078e31SDaniel Almeida  * Marek Szyprowski, <m.szyprowski@samsung.com>
29*0c078e31SDaniel Almeida  *
30*0c078e31SDaniel Almeida  * Based on the vicodec driver, that is:
31*0c078e31SDaniel Almeida  *
32*0c078e31SDaniel Almeida  * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
33*0c078e31SDaniel Almeida  *
34*0c078e31SDaniel Almeida  * Based on the Cedrus VPU driver, that is:
35*0c078e31SDaniel Almeida  *
36*0c078e31SDaniel Almeida  * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
37*0c078e31SDaniel Almeida  * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
38*0c078e31SDaniel Almeida  * Copyright (C) 2018 Bootlin
39*0c078e31SDaniel Almeida  */
40*0c078e31SDaniel Almeida 
41*0c078e31SDaniel Almeida #ifndef _VISL_H_
42*0c078e31SDaniel Almeida #define _VISL_H_
43*0c078e31SDaniel Almeida 
44*0c078e31SDaniel Almeida #include <linux/debugfs.h>
45*0c078e31SDaniel Almeida #include <linux/list.h>
46*0c078e31SDaniel Almeida 
47*0c078e31SDaniel Almeida #include <media/v4l2-ctrls.h>
48*0c078e31SDaniel Almeida #include <media/v4l2-device.h>
49*0c078e31SDaniel Almeida #include <media/tpg/v4l2-tpg.h>
50*0c078e31SDaniel Almeida 
51*0c078e31SDaniel Almeida #define VISL_NAME		"visl"
52*0c078e31SDaniel Almeida #define VISL_M2M_NQUEUES	2
53*0c078e31SDaniel Almeida 
54*0c078e31SDaniel Almeida #define TPG_STR_BUF_SZ		2048
55*0c078e31SDaniel Almeida 
56*0c078e31SDaniel Almeida extern unsigned int visl_transtime_ms;
57*0c078e31SDaniel Almeida 
58*0c078e31SDaniel Almeida struct visl_ctrls {
59*0c078e31SDaniel Almeida 	const struct visl_ctrl_desc *ctrls;
60*0c078e31SDaniel Almeida 	unsigned int num_ctrls;
61*0c078e31SDaniel Almeida };
62*0c078e31SDaniel Almeida 
63*0c078e31SDaniel Almeida struct visl_coded_format_desc {
64*0c078e31SDaniel Almeida 	u32 pixelformat;
65*0c078e31SDaniel Almeida 	struct v4l2_frmsize_stepwise frmsize;
66*0c078e31SDaniel Almeida 	const struct visl_ctrls *ctrls;
67*0c078e31SDaniel Almeida 	unsigned int num_decoded_fmts;
68*0c078e31SDaniel Almeida 	const u32 *decoded_fmts;
69*0c078e31SDaniel Almeida };
70*0c078e31SDaniel Almeida 
71*0c078e31SDaniel Almeida extern const struct visl_coded_format_desc visl_coded_fmts[];
72*0c078e31SDaniel Almeida extern const size_t num_coded_fmts;
73*0c078e31SDaniel Almeida 
74*0c078e31SDaniel Almeida enum {
75*0c078e31SDaniel Almeida 	V4L2_M2M_SRC = 0,
76*0c078e31SDaniel Almeida 	V4L2_M2M_DST = 1,
77*0c078e31SDaniel Almeida };
78*0c078e31SDaniel Almeida 
79*0c078e31SDaniel Almeida extern unsigned int visl_debug;
80*0c078e31SDaniel Almeida #define dprintk(dev, fmt, arg...) \
81*0c078e31SDaniel Almeida 	v4l2_dbg(1, visl_debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
82*0c078e31SDaniel Almeida 
83*0c078e31SDaniel Almeida extern int visl_dprintk_frame_start;
84*0c078e31SDaniel Almeida extern unsigned int visl_dprintk_nframes;
85*0c078e31SDaniel Almeida extern bool keep_bitstream_buffers;
86*0c078e31SDaniel Almeida extern int bitstream_trace_frame_start;
87*0c078e31SDaniel Almeida extern unsigned int bitstream_trace_nframes;
88*0c078e31SDaniel Almeida 
89*0c078e31SDaniel Almeida #define frame_dprintk(dev, current, fmt, arg...) \
90*0c078e31SDaniel Almeida 	do { \
91*0c078e31SDaniel Almeida 		if (visl_dprintk_frame_start > -1 && \
92*0c078e31SDaniel Almeida 		    (current) >= visl_dprintk_frame_start && \
93*0c078e31SDaniel Almeida 		    (current) < visl_dprintk_frame_start + visl_dprintk_nframes) \
94*0c078e31SDaniel Almeida 			dprintk(dev, fmt, ## arg); \
95*0c078e31SDaniel Almeida 	} while (0) \
96*0c078e31SDaniel Almeida 
97*0c078e31SDaniel Almeida struct visl_q_data {
98*0c078e31SDaniel Almeida 	unsigned int		sequence;
99*0c078e31SDaniel Almeida };
100*0c078e31SDaniel Almeida 
101*0c078e31SDaniel Almeida struct visl_dev {
102*0c078e31SDaniel Almeida 	struct v4l2_device	v4l2_dev;
103*0c078e31SDaniel Almeida 	struct video_device	vfd;
104*0c078e31SDaniel Almeida #ifdef CONFIG_MEDIA_CONTROLLER
105*0c078e31SDaniel Almeida 	struct media_device	mdev;
106*0c078e31SDaniel Almeida #endif
107*0c078e31SDaniel Almeida 
108*0c078e31SDaniel Almeida 	struct mutex		dev_mutex;
109*0c078e31SDaniel Almeida 
110*0c078e31SDaniel Almeida 	struct v4l2_m2m_dev	*m2m_dev;
111*0c078e31SDaniel Almeida 
112*0c078e31SDaniel Almeida #ifdef CONFIG_VISL_DEBUGFS
113*0c078e31SDaniel Almeida 	struct dentry		*debugfs_root;
114*0c078e31SDaniel Almeida 	struct dentry		*bitstream_debugfs;
115*0c078e31SDaniel Almeida 	struct list_head	bitstream_blobs;
116*0c078e31SDaniel Almeida 
117*0c078e31SDaniel Almeida 	/* Protects the "blob" list */
118*0c078e31SDaniel Almeida 	struct mutex		bitstream_lock;
119*0c078e31SDaniel Almeida #endif
120*0c078e31SDaniel Almeida };
121*0c078e31SDaniel Almeida 
122*0c078e31SDaniel Almeida enum visl_codec {
123*0c078e31SDaniel Almeida 	VISL_CODEC_NONE,
124*0c078e31SDaniel Almeida 	VISL_CODEC_FWHT,
125*0c078e31SDaniel Almeida 	VISL_CODEC_MPEG2,
126*0c078e31SDaniel Almeida 	VISL_CODEC_VP8,
127*0c078e31SDaniel Almeida 	VISL_CODEC_VP9,
128*0c078e31SDaniel Almeida 	VISL_CODEC_H264,
129*0c078e31SDaniel Almeida 	VISL_CODEC_HEVC,
130*0c078e31SDaniel Almeida };
131*0c078e31SDaniel Almeida 
132*0c078e31SDaniel Almeida struct visl_blob {
133*0c078e31SDaniel Almeida 	struct list_head list;
134*0c078e31SDaniel Almeida 	struct dentry *dentry;
135*0c078e31SDaniel Almeida 	struct debugfs_blob_wrapper blob;
136*0c078e31SDaniel Almeida };
137*0c078e31SDaniel Almeida 
138*0c078e31SDaniel Almeida struct visl_ctx {
139*0c078e31SDaniel Almeida 	struct v4l2_fh		fh;
140*0c078e31SDaniel Almeida 	struct visl_dev	*dev;
141*0c078e31SDaniel Almeida 	struct v4l2_ctrl_handler hdl;
142*0c078e31SDaniel Almeida 
143*0c078e31SDaniel Almeida 	struct mutex		vb_mutex;
144*0c078e31SDaniel Almeida 
145*0c078e31SDaniel Almeida 	struct visl_q_data	q_data[VISL_M2M_NQUEUES];
146*0c078e31SDaniel Almeida 	enum   visl_codec	current_codec;
147*0c078e31SDaniel Almeida 
148*0c078e31SDaniel Almeida 	const struct visl_coded_format_desc *coded_format_desc;
149*0c078e31SDaniel Almeida 
150*0c078e31SDaniel Almeida 	struct v4l2_format	coded_fmt;
151*0c078e31SDaniel Almeida 	struct v4l2_format	decoded_fmt;
152*0c078e31SDaniel Almeida 
153*0c078e31SDaniel Almeida 	struct tpg_data		tpg;
154*0c078e31SDaniel Almeida 	u64			capture_streamon_jiffies;
155*0c078e31SDaniel Almeida 	char			*tpg_str_buf;
156*0c078e31SDaniel Almeida };
157*0c078e31SDaniel Almeida 
158*0c078e31SDaniel Almeida struct visl_ctrl_desc {
159*0c078e31SDaniel Almeida 	struct v4l2_ctrl_config cfg;
160*0c078e31SDaniel Almeida };
161*0c078e31SDaniel Almeida 
visl_file_to_ctx(struct file * file)162*0c078e31SDaniel Almeida static inline struct visl_ctx *visl_file_to_ctx(struct file *file)
163*0c078e31SDaniel Almeida {
164*0c078e31SDaniel Almeida 	return container_of(file->private_data, struct visl_ctx, fh);
165*0c078e31SDaniel Almeida }
166*0c078e31SDaniel Almeida 
visl_v4l2fh_to_ctx(struct v4l2_fh * v4l2_fh)167*0c078e31SDaniel Almeida static inline struct visl_ctx *visl_v4l2fh_to_ctx(struct v4l2_fh *v4l2_fh)
168*0c078e31SDaniel Almeida {
169*0c078e31SDaniel Almeida 	return container_of(v4l2_fh, struct visl_ctx, fh);
170*0c078e31SDaniel Almeida }
171*0c078e31SDaniel Almeida 
172*0c078e31SDaniel Almeida void *visl_find_control_data(struct visl_ctx *ctx, u32 id);
173*0c078e31SDaniel Almeida struct v4l2_ctrl *visl_find_control(struct visl_ctx *ctx, u32 id);
174*0c078e31SDaniel Almeida u32 visl_control_num_elems(struct visl_ctx *ctx, u32 id);
175*0c078e31SDaniel Almeida 
176*0c078e31SDaniel Almeida #endif /* _VISL_H_ */
177