1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Cedrus VPU driver
4  *
5  * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
6  * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
7  * Copyright (C) 2018 Bootlin
8  *
9  * Based on the vim2m driver, that is:
10  *
11  * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
12  * Pawel Osciak, <pawel@osciak.com>
13  * Marek Szyprowski, <m.szyprowski@samsung.com>
14  */
15 
16 #ifndef _CEDRUS_H_
17 #define _CEDRUS_H_
18 
19 #include <media/v4l2-ctrls.h>
20 #include <media/v4l2-device.h>
21 #include <media/v4l2-mem2mem.h>
22 #include <media/videobuf2-v4l2.h>
23 #include <media/videobuf2-dma-contig.h>
24 
25 #include <linux/iopoll.h>
26 #include <linux/platform_device.h>
27 #include <linux/workqueue.h>
28 
29 #define CEDRUS_NAME			"cedrus"
30 
31 #define CEDRUS_CAPABILITY_UNTILED	BIT(0)
32 #define CEDRUS_CAPABILITY_H265_DEC	BIT(1)
33 #define CEDRUS_CAPABILITY_H264_DEC	BIT(2)
34 #define CEDRUS_CAPABILITY_MPEG2_DEC	BIT(3)
35 #define CEDRUS_CAPABILITY_VP8_DEC	BIT(4)
36 #define CEDRUS_CAPABILITY_H265_10_DEC	BIT(5)
37 
38 enum cedrus_codec {
39 	CEDRUS_CODEC_MPEG2,
40 	CEDRUS_CODEC_H264,
41 	CEDRUS_CODEC_H265,
42 	CEDRUS_CODEC_VP8,
43 	CEDRUS_CODEC_LAST,
44 };
45 
46 enum cedrus_irq_status {
47 	CEDRUS_IRQ_NONE,
48 	CEDRUS_IRQ_ERROR,
49 	CEDRUS_IRQ_OK,
50 };
51 
52 enum cedrus_h264_pic_type {
53 	CEDRUS_H264_PIC_TYPE_FRAME	= 0,
54 	CEDRUS_H264_PIC_TYPE_FIELD,
55 	CEDRUS_H264_PIC_TYPE_MBAFF,
56 };
57 
58 struct cedrus_control {
59 	struct v4l2_ctrl_config cfg;
60 	enum cedrus_codec	codec;
61 };
62 
63 struct cedrus_h264_run {
64 	const struct v4l2_ctrl_h264_decode_params	*decode_params;
65 	const struct v4l2_ctrl_h264_pps			*pps;
66 	const struct v4l2_ctrl_h264_scaling_matrix	*scaling_matrix;
67 	const struct v4l2_ctrl_h264_slice_params	*slice_params;
68 	const struct v4l2_ctrl_h264_sps			*sps;
69 	const struct v4l2_ctrl_h264_pred_weights	*pred_weights;
70 };
71 
72 struct cedrus_mpeg2_run {
73 	const struct v4l2_ctrl_mpeg2_sequence		*sequence;
74 	const struct v4l2_ctrl_mpeg2_picture		*picture;
75 	const struct v4l2_ctrl_mpeg2_quantisation	*quantisation;
76 };
77 
78 struct cedrus_h265_run {
79 	const struct v4l2_ctrl_hevc_sps			*sps;
80 	const struct v4l2_ctrl_hevc_pps			*pps;
81 	const struct v4l2_ctrl_hevc_slice_params	*slice_params;
82 	const struct v4l2_ctrl_hevc_decode_params	*decode_params;
83 	const struct v4l2_ctrl_hevc_scaling_matrix	*scaling_matrix;
84 };
85 
86 struct cedrus_vp8_run {
87 	const struct v4l2_ctrl_vp8_frame		*frame_params;
88 };
89 
90 struct cedrus_run {
91 	struct vb2_v4l2_buffer	*src;
92 	struct vb2_v4l2_buffer	*dst;
93 
94 	union {
95 		struct cedrus_h264_run	h264;
96 		struct cedrus_mpeg2_run	mpeg2;
97 		struct cedrus_h265_run	h265;
98 		struct cedrus_vp8_run	vp8;
99 	};
100 };
101 
102 struct cedrus_buffer {
103 	struct v4l2_m2m_buffer          m2m_buf;
104 
105 	union {
106 		struct {
107 			unsigned int			position;
108 			enum cedrus_h264_pic_type	pic_type;
109 		} h264;
110 	} codec;
111 };
112 
113 struct cedrus_ctx {
114 	struct v4l2_fh			fh;
115 	struct cedrus_dev		*dev;
116 
117 	struct v4l2_pix_format		src_fmt;
118 	struct v4l2_pix_format		dst_fmt;
119 	enum cedrus_codec		current_codec;
120 
121 	struct v4l2_ctrl_handler	hdl;
122 	struct v4l2_ctrl		**ctrls;
123 
124 	union {
125 		struct {
126 			void		*mv_col_buf;
127 			dma_addr_t	mv_col_buf_dma;
128 			ssize_t		mv_col_buf_field_size;
129 			ssize_t		mv_col_buf_size;
130 			void		*pic_info_buf;
131 			dma_addr_t	pic_info_buf_dma;
132 			ssize_t		pic_info_buf_size;
133 			void		*neighbor_info_buf;
134 			dma_addr_t	neighbor_info_buf_dma;
135 			void		*deblk_buf;
136 			dma_addr_t	deblk_buf_dma;
137 			ssize_t		deblk_buf_size;
138 			void		*intra_pred_buf;
139 			dma_addr_t	intra_pred_buf_dma;
140 			ssize_t		intra_pred_buf_size;
141 		} h264;
142 		struct {
143 			void		*mv_col_buf;
144 			dma_addr_t	mv_col_buf_addr;
145 			ssize_t		mv_col_buf_size;
146 			ssize_t		mv_col_buf_unit_size;
147 			void		*neighbor_info_buf;
148 			dma_addr_t	neighbor_info_buf_addr;
149 		} h265;
150 		struct {
151 			unsigned int	last_frame_p_type;
152 			unsigned int	last_filter_type;
153 			unsigned int	last_sharpness_level;
154 
155 			u8		*entropy_probs_buf;
156 			dma_addr_t	entropy_probs_buf_dma;
157 		} vp8;
158 	} codec;
159 };
160 
161 struct cedrus_dec_ops {
162 	void (*irq_clear)(struct cedrus_ctx *ctx);
163 	void (*irq_disable)(struct cedrus_ctx *ctx);
164 	enum cedrus_irq_status (*irq_status)(struct cedrus_ctx *ctx);
165 	void (*setup)(struct cedrus_ctx *ctx, struct cedrus_run *run);
166 	int (*start)(struct cedrus_ctx *ctx);
167 	void (*stop)(struct cedrus_ctx *ctx);
168 	void (*trigger)(struct cedrus_ctx *ctx);
169 };
170 
171 struct cedrus_variant {
172 	unsigned int	capabilities;
173 	unsigned int	mod_rate;
174 };
175 
176 struct cedrus_dev {
177 	struct v4l2_device	v4l2_dev;
178 	struct video_device	vfd;
179 	struct media_device	mdev;
180 	struct media_pad	pad[2];
181 	struct platform_device	*pdev;
182 	struct device		*dev;
183 	struct v4l2_m2m_dev	*m2m_dev;
184 	struct cedrus_dec_ops	*dec_ops[CEDRUS_CODEC_LAST];
185 
186 	/* Device file mutex */
187 	struct mutex		dev_mutex;
188 
189 	void __iomem		*base;
190 
191 	struct clk		*mod_clk;
192 	struct clk		*ahb_clk;
193 	struct clk		*ram_clk;
194 
195 	struct reset_control	*rstc;
196 
197 	unsigned int		capabilities;
198 
199 	struct delayed_work	watchdog_work;
200 };
201 
202 extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
203 extern struct cedrus_dec_ops cedrus_dec_ops_h264;
204 extern struct cedrus_dec_ops cedrus_dec_ops_h265;
205 extern struct cedrus_dec_ops cedrus_dec_ops_vp8;
206 
cedrus_write(struct cedrus_dev * dev,u32 reg,u32 val)207 static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
208 {
209 	writel(val, dev->base + reg);
210 }
211 
cedrus_read(struct cedrus_dev * dev,u32 reg)212 static inline u32 cedrus_read(struct cedrus_dev *dev, u32 reg)
213 {
214 	return readl(dev->base + reg);
215 }
216 
cedrus_wait_for(struct cedrus_dev * dev,u32 reg,u32 flag)217 static inline u32 cedrus_wait_for(struct cedrus_dev *dev, u32 reg, u32 flag)
218 {
219 	u32 value;
220 
221 	return readl_poll_timeout_atomic(dev->base + reg, value,
222 			(value & flag) == 0, 10, 1000);
223 }
224 
cedrus_buf_addr(struct vb2_buffer * buf,struct v4l2_pix_format * pix_fmt,unsigned int plane)225 static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf,
226 					 struct v4l2_pix_format *pix_fmt,
227 					 unsigned int plane)
228 {
229 	dma_addr_t addr = vb2_dma_contig_plane_dma_addr(buf, 0);
230 
231 	return addr + (pix_fmt ? (dma_addr_t)pix_fmt->bytesperline *
232 	       pix_fmt->height * plane : 0);
233 }
234 
cedrus_dst_buf_addr(struct cedrus_ctx * ctx,int index,unsigned int plane)235 static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
236 					     int index, unsigned int plane)
237 {
238 	struct vb2_buffer *buf = NULL;
239 	struct vb2_queue *vq;
240 
241 	if (index < 0)
242 		return 0;
243 
244 	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
245 	if (vq)
246 		buf = vb2_get_buffer(vq, index);
247 
248 	return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
249 }
250 
251 static inline struct cedrus_buffer *
vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer * p)252 vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer *p)
253 {
254 	return container_of(p, struct cedrus_buffer, m2m_buf.vb);
255 }
256 
257 static inline struct cedrus_buffer *
vb2_to_cedrus_buffer(const struct vb2_buffer * p)258 vb2_to_cedrus_buffer(const struct vb2_buffer *p)
259 {
260 	return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
261 }
262 
263 void *cedrus_find_control_data(struct cedrus_ctx *ctx, u32 id);
264 
265 #endif
266