• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/platform_device.h>
26 
27 #define CEDRUS_NAME			"cedrus"
28 
29 #define CEDRUS_CAPABILITY_UNTILED	BIT(0)
30 #define CEDRUS_CAPABILITY_H265_DEC	BIT(1)
31 
32 #define CEDRUS_QUIRK_NO_DMA_OFFSET	BIT(0)
33 
34 enum cedrus_codec {
35 	CEDRUS_CODEC_MPEG2,
36 	CEDRUS_CODEC_H264,
37 	CEDRUS_CODEC_H265,
38 	CEDRUS_CODEC_LAST,
39 };
40 
41 enum cedrus_irq_status {
42 	CEDRUS_IRQ_NONE,
43 	CEDRUS_IRQ_ERROR,
44 	CEDRUS_IRQ_OK,
45 };
46 
47 enum cedrus_h264_pic_type {
48 	CEDRUS_H264_PIC_TYPE_FRAME	= 0,
49 	CEDRUS_H264_PIC_TYPE_FIELD,
50 	CEDRUS_H264_PIC_TYPE_MBAFF,
51 };
52 
53 struct cedrus_control {
54 	struct v4l2_ctrl_config cfg;
55 	enum cedrus_codec	codec;
56 	unsigned char		required:1;
57 };
58 
59 struct cedrus_h264_run {
60 	const struct v4l2_ctrl_h264_decode_params	*decode_params;
61 	const struct v4l2_ctrl_h264_pps			*pps;
62 	const struct v4l2_ctrl_h264_scaling_matrix	*scaling_matrix;
63 	const struct v4l2_ctrl_h264_slice_params	*slice_params;
64 	const struct v4l2_ctrl_h264_sps			*sps;
65 	const struct v4l2_ctrl_h264_pred_weights	*pred_weights;
66 };
67 
68 struct cedrus_mpeg2_run {
69 	const struct v4l2_ctrl_mpeg2_slice_params	*slice_params;
70 	const struct v4l2_ctrl_mpeg2_quantization	*quantization;
71 };
72 
73 struct cedrus_h265_run {
74 	const struct v4l2_ctrl_hevc_sps			*sps;
75 	const struct v4l2_ctrl_hevc_pps			*pps;
76 	const struct v4l2_ctrl_hevc_slice_params	*slice_params;
77 };
78 
79 struct cedrus_run {
80 	struct vb2_v4l2_buffer	*src;
81 	struct vb2_v4l2_buffer	*dst;
82 
83 	union {
84 		struct cedrus_h264_run	h264;
85 		struct cedrus_mpeg2_run	mpeg2;
86 		struct cedrus_h265_run	h265;
87 	};
88 };
89 
90 struct cedrus_buffer {
91 	struct v4l2_m2m_buffer          m2m_buf;
92 
93 	union {
94 		struct {
95 			unsigned int			position;
96 			enum cedrus_h264_pic_type	pic_type;
97 		} h264;
98 	} codec;
99 };
100 
101 struct cedrus_ctx {
102 	struct v4l2_fh			fh;
103 	struct cedrus_dev		*dev;
104 
105 	struct v4l2_pix_format		src_fmt;
106 	struct v4l2_pix_format		dst_fmt;
107 	enum cedrus_codec		current_codec;
108 
109 	struct v4l2_ctrl_handler	hdl;
110 	struct v4l2_ctrl		**ctrls;
111 
112 	union {
113 		struct {
114 			void		*mv_col_buf;
115 			dma_addr_t	mv_col_buf_dma;
116 			ssize_t		mv_col_buf_field_size;
117 			ssize_t		mv_col_buf_size;
118 			void		*pic_info_buf;
119 			dma_addr_t	pic_info_buf_dma;
120 			ssize_t		pic_info_buf_size;
121 			void		*neighbor_info_buf;
122 			dma_addr_t	neighbor_info_buf_dma;
123 			void		*deblk_buf;
124 			dma_addr_t	deblk_buf_dma;
125 			ssize_t		deblk_buf_size;
126 			void		*intra_pred_buf;
127 			dma_addr_t	intra_pred_buf_dma;
128 			ssize_t		intra_pred_buf_size;
129 		} h264;
130 		struct {
131 			void		*mv_col_buf;
132 			dma_addr_t	mv_col_buf_addr;
133 			ssize_t		mv_col_buf_size;
134 			ssize_t		mv_col_buf_unit_size;
135 			void		*neighbor_info_buf;
136 			dma_addr_t	neighbor_info_buf_addr;
137 		} h265;
138 	} codec;
139 };
140 
141 struct cedrus_dec_ops {
142 	void (*irq_clear)(struct cedrus_ctx *ctx);
143 	void (*irq_disable)(struct cedrus_ctx *ctx);
144 	enum cedrus_irq_status (*irq_status)(struct cedrus_ctx *ctx);
145 	void (*setup)(struct cedrus_ctx *ctx, struct cedrus_run *run);
146 	int (*start)(struct cedrus_ctx *ctx);
147 	void (*stop)(struct cedrus_ctx *ctx);
148 	void (*trigger)(struct cedrus_ctx *ctx);
149 };
150 
151 struct cedrus_variant {
152 	unsigned int	capabilities;
153 	unsigned int	quirks;
154 	unsigned int	mod_rate;
155 };
156 
157 struct cedrus_dev {
158 	struct v4l2_device	v4l2_dev;
159 	struct video_device	vfd;
160 	struct media_device	mdev;
161 	struct media_pad	pad[2];
162 	struct platform_device	*pdev;
163 	struct device		*dev;
164 	struct v4l2_m2m_dev	*m2m_dev;
165 	struct cedrus_dec_ops	*dec_ops[CEDRUS_CODEC_LAST];
166 
167 	/* Device file mutex */
168 	struct mutex		dev_mutex;
169 
170 	void __iomem		*base;
171 
172 	struct clk		*mod_clk;
173 	struct clk		*ahb_clk;
174 	struct clk		*ram_clk;
175 
176 	struct reset_control	*rstc;
177 
178 	unsigned int		capabilities;
179 };
180 
181 extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
182 extern struct cedrus_dec_ops cedrus_dec_ops_h264;
183 extern struct cedrus_dec_ops cedrus_dec_ops_h265;
184 
cedrus_write(struct cedrus_dev * dev,u32 reg,u32 val)185 static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
186 {
187 	writel(val, dev->base + reg);
188 }
189 
cedrus_read(struct cedrus_dev * dev,u32 reg)190 static inline u32 cedrus_read(struct cedrus_dev *dev, u32 reg)
191 {
192 	return readl(dev->base + reg);
193 }
194 
cedrus_buf_addr(struct vb2_buffer * buf,struct v4l2_pix_format * pix_fmt,unsigned int plane)195 static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf,
196 					 struct v4l2_pix_format *pix_fmt,
197 					 unsigned int plane)
198 {
199 	dma_addr_t addr = vb2_dma_contig_plane_dma_addr(buf, 0);
200 
201 	return addr + (pix_fmt ? (dma_addr_t)pix_fmt->bytesperline *
202 	       pix_fmt->height * plane : 0);
203 }
204 
cedrus_dst_buf_addr(struct cedrus_ctx * ctx,int index,unsigned int plane)205 static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
206 					     int index, unsigned int plane)
207 {
208 	struct vb2_buffer *buf = NULL;
209 	struct vb2_queue *vq;
210 
211 	if (index < 0)
212 		return 0;
213 
214 	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
215 	if (vq)
216 		buf = vb2_get_buffer(vq, index);
217 
218 	return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
219 }
220 
221 static inline struct cedrus_buffer *
vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer * p)222 vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer *p)
223 {
224 	return container_of(p, struct cedrus_buffer, m2m_buf.vb);
225 }
226 
227 static inline struct cedrus_buffer *
vb2_to_cedrus_buffer(const struct vb2_buffer * p)228 vb2_to_cedrus_buffer(const struct vb2_buffer *p)
229 {
230 	return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
231 }
232 
233 void *cedrus_find_control_data(struct cedrus_ctx *ctx, u32 id);
234 
235 #endif
236