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_irq_status {
39 	CEDRUS_IRQ_NONE,
40 	CEDRUS_IRQ_ERROR,
41 	CEDRUS_IRQ_OK,
42 };
43 
44 enum cedrus_h264_pic_type {
45 	CEDRUS_H264_PIC_TYPE_FRAME	= 0,
46 	CEDRUS_H264_PIC_TYPE_FIELD,
47 	CEDRUS_H264_PIC_TYPE_MBAFF,
48 };
49 
50 struct cedrus_control {
51 	struct v4l2_ctrl_config cfg;
52 	unsigned int		capabilities;
53 };
54 
55 struct cedrus_h264_run {
56 	const struct v4l2_ctrl_h264_decode_params	*decode_params;
57 	const struct v4l2_ctrl_h264_pps			*pps;
58 	const struct v4l2_ctrl_h264_scaling_matrix	*scaling_matrix;
59 	const struct v4l2_ctrl_h264_slice_params	*slice_params;
60 	const struct v4l2_ctrl_h264_sps			*sps;
61 	const struct v4l2_ctrl_h264_pred_weights	*pred_weights;
62 };
63 
64 struct cedrus_mpeg2_run {
65 	const struct v4l2_ctrl_mpeg2_sequence		*sequence;
66 	const struct v4l2_ctrl_mpeg2_picture		*picture;
67 	const struct v4l2_ctrl_mpeg2_quantisation	*quantisation;
68 };
69 
70 struct cedrus_h265_run {
71 	const struct v4l2_ctrl_hevc_sps			*sps;
72 	const struct v4l2_ctrl_hevc_pps			*pps;
73 	const struct v4l2_ctrl_hevc_slice_params	*slice_params;
74 	const struct v4l2_ctrl_hevc_decode_params	*decode_params;
75 	const struct v4l2_ctrl_hevc_scaling_matrix	*scaling_matrix;
76 	const u32					*entry_points;
77 	u32						entry_points_count;
78 };
79 
80 struct cedrus_vp8_run {
81 	const struct v4l2_ctrl_vp8_frame		*frame_params;
82 };
83 
84 struct cedrus_run {
85 	struct vb2_v4l2_buffer	*src;
86 	struct vb2_v4l2_buffer	*dst;
87 
88 	union {
89 		struct cedrus_h264_run	h264;
90 		struct cedrus_mpeg2_run	mpeg2;
91 		struct cedrus_h265_run	h265;
92 		struct cedrus_vp8_run	vp8;
93 	};
94 };
95 
96 struct cedrus_buffer {
97 	struct v4l2_m2m_buffer          m2m_buf;
98 
99 	union {
100 		struct {
101 			unsigned int			position;
102 			enum cedrus_h264_pic_type	pic_type;
103 			void				*mv_col_buf;
104 			dma_addr_t			mv_col_buf_dma;
105 			ssize_t				mv_col_buf_size;
106 		} h264;
107 		struct {
108 			void		*mv_col_buf;
109 			dma_addr_t	mv_col_buf_dma;
110 			ssize_t		mv_col_buf_size;
111 		} h265;
112 	} codec;
113 };
114 
115 struct cedrus_ctx {
116 	struct v4l2_fh			fh;
117 	struct cedrus_dev		*dev;
118 
119 	struct v4l2_pix_format		src_fmt;
120 	struct v4l2_pix_format		dst_fmt;
121 	struct cedrus_dec_ops		*current_codec;
122 	unsigned int			bit_depth;
123 
124 	struct v4l2_ctrl_handler	hdl;
125 	struct v4l2_ctrl		**ctrls;
126 
127 	union {
128 		struct {
129 			void		*pic_info_buf;
130 			dma_addr_t	pic_info_buf_dma;
131 			ssize_t		pic_info_buf_size;
132 			void		*neighbor_info_buf;
133 			dma_addr_t	neighbor_info_buf_dma;
134 			void		*deblk_buf;
135 			dma_addr_t	deblk_buf_dma;
136 			ssize_t		deblk_buf_size;
137 			void		*intra_pred_buf;
138 			dma_addr_t	intra_pred_buf_dma;
139 			ssize_t		intra_pred_buf_size;
140 		} h264;
141 		struct {
142 			void		*neighbor_info_buf;
143 			dma_addr_t	neighbor_info_buf_addr;
144 			void		*entry_points_buf;
145 			dma_addr_t	entry_points_buf_addr;
146 		} h265;
147 		struct {
148 			unsigned int	last_frame_p_type;
149 			unsigned int	last_filter_type;
150 			unsigned int	last_sharpness_level;
151 
152 			u8		*entropy_probs_buf;
153 			dma_addr_t	entropy_probs_buf_dma;
154 		} vp8;
155 	} codec;
156 };
157 
158 struct cedrus_dec_ops {
159 	void (*irq_clear)(struct cedrus_ctx *ctx);
160 	void (*irq_disable)(struct cedrus_ctx *ctx);
161 	enum cedrus_irq_status (*irq_status)(struct cedrus_ctx *ctx);
162 	int (*setup)(struct cedrus_ctx *ctx, struct cedrus_run *run);
163 	int (*start)(struct cedrus_ctx *ctx);
164 	void (*stop)(struct cedrus_ctx *ctx);
165 	void (*trigger)(struct cedrus_ctx *ctx);
166 	unsigned int (*extra_cap_size)(struct cedrus_ctx *ctx,
167 				       struct v4l2_pix_format *pix_fmt);
168 };
169 
170 struct cedrus_variant {
171 	unsigned int	capabilities;
172 	unsigned int	mod_rate;
173 };
174 
175 struct cedrus_dev {
176 	struct v4l2_device	v4l2_dev;
177 	struct video_device	vfd;
178 	struct media_device	mdev;
179 	struct media_pad	pad[2];
180 	struct platform_device	*pdev;
181 	struct device		*dev;
182 	struct v4l2_m2m_dev	*m2m_dev;
183 
184 	/* Device file mutex */
185 	struct mutex		dev_mutex;
186 
187 	void __iomem		*base;
188 
189 	struct clk		*mod_clk;
190 	struct clk		*ahb_clk;
191 	struct clk		*ram_clk;
192 
193 	struct reset_control	*rstc;
194 
195 	unsigned int		capabilities;
196 
197 	struct delayed_work	watchdog_work;
198 };
199 
200 extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
201 extern struct cedrus_dec_ops cedrus_dec_ops_h264;
202 extern struct cedrus_dec_ops cedrus_dec_ops_h265;
203 extern struct cedrus_dec_ops cedrus_dec_ops_vp8;
204 
cedrus_write(struct cedrus_dev * dev,u32 reg,u32 val)205 static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
206 {
207 	writel(val, dev->base + reg);
208 }
209 
cedrus_read(struct cedrus_dev * dev,u32 reg)210 static inline u32 cedrus_read(struct cedrus_dev *dev, u32 reg)
211 {
212 	return readl(dev->base + reg);
213 }
214 
cedrus_wait_for(struct cedrus_dev * dev,u32 reg,u32 flag)215 static inline u32 cedrus_wait_for(struct cedrus_dev *dev, u32 reg, u32 flag)
216 {
217 	u32 value;
218 
219 	return readl_poll_timeout_atomic(dev->base + reg, value,
220 			(value & flag) == 0, 10, 1000);
221 }
222 
cedrus_buf_addr(struct vb2_buffer * buf,struct v4l2_pix_format * pix_fmt,unsigned int plane)223 static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf,
224 					 struct v4l2_pix_format *pix_fmt,
225 					 unsigned int plane)
226 {
227 	dma_addr_t addr = vb2_dma_contig_plane_dma_addr(buf, 0);
228 
229 	return addr + (pix_fmt ? (dma_addr_t)pix_fmt->bytesperline *
230 	       pix_fmt->height * plane : 0);
231 }
232 
cedrus_dst_buf_addr(struct cedrus_ctx * ctx,struct vb2_buffer * buf,unsigned int plane)233 static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
234 					     struct vb2_buffer *buf,
235 					     unsigned int plane)
236 {
237 	return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
238 }
239 
cedrus_write_ref_buf_addr(struct cedrus_ctx * ctx,struct vb2_queue * q,u64 timestamp,u32 luma_reg,u32 chroma_reg)240 static inline void cedrus_write_ref_buf_addr(struct cedrus_ctx *ctx,
241 					     struct vb2_queue *q,
242 					     u64 timestamp,
243 					     u32 luma_reg,
244 					     u32 chroma_reg)
245 {
246 	struct cedrus_dev *dev = ctx->dev;
247 	struct vb2_buffer *buf = vb2_find_buffer(q, timestamp);
248 
249 	cedrus_write(dev, luma_reg, cedrus_dst_buf_addr(ctx, buf, 0));
250 	cedrus_write(dev, chroma_reg, cedrus_dst_buf_addr(ctx, buf, 1));
251 }
252 
253 static inline struct cedrus_buffer *
vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer * p)254 vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer *p)
255 {
256 	return container_of(p, struct cedrus_buffer, m2m_buf.vb);
257 }
258 
259 static inline struct cedrus_buffer *
vb2_to_cedrus_buffer(const struct vb2_buffer * p)260 vb2_to_cedrus_buffer(const struct vb2_buffer *p)
261 {
262 	return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
263 }
264 
265 static inline bool
cedrus_is_capable(struct cedrus_ctx * ctx,unsigned int capabilities)266 cedrus_is_capable(struct cedrus_ctx *ctx, unsigned int capabilities)
267 {
268 	return (ctx->dev->capabilities & capabilities) == capabilities;
269 }
270 
271 void *cedrus_find_control_data(struct cedrus_ctx *ctx, u32 id);
272 u32 cedrus_get_num_of_controls(struct cedrus_ctx *ctx, u32 id);
273 
274 #endif
275