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
cedrus_file2ctx(struct file * file)158 static inline struct cedrus_ctx *cedrus_file2ctx(struct file *file)
159 {
160 return container_of(file_to_v4l2_fh(file), struct cedrus_ctx, fh);
161 }
162
163 struct cedrus_dec_ops {
164 void (*irq_clear)(struct cedrus_ctx *ctx);
165 void (*irq_disable)(struct cedrus_ctx *ctx);
166 enum cedrus_irq_status (*irq_status)(struct cedrus_ctx *ctx);
167 int (*setup)(struct cedrus_ctx *ctx, struct cedrus_run *run);
168 int (*start)(struct cedrus_ctx *ctx);
169 void (*stop)(struct cedrus_ctx *ctx);
170 void (*trigger)(struct cedrus_ctx *ctx);
171 unsigned int (*extra_cap_size)(struct cedrus_ctx *ctx,
172 struct v4l2_pix_format *pix_fmt);
173 };
174
175 struct cedrus_variant {
176 unsigned int capabilities;
177 unsigned int mod_rate;
178 };
179
180 struct cedrus_dev {
181 struct v4l2_device v4l2_dev;
182 struct video_device vfd;
183 struct media_device mdev;
184 struct media_pad pad[2];
185 struct platform_device *pdev;
186 struct device *dev;
187 struct v4l2_m2m_dev *m2m_dev;
188
189 /* Device file mutex */
190 struct mutex dev_mutex;
191
192 void __iomem *base;
193
194 struct clk *mod_clk;
195 struct clk *ahb_clk;
196 struct clk *ram_clk;
197
198 struct reset_control *rstc;
199
200 unsigned int capabilities;
201
202 struct delayed_work watchdog_work;
203 };
204
205 extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
206 extern struct cedrus_dec_ops cedrus_dec_ops_h264;
207 extern struct cedrus_dec_ops cedrus_dec_ops_h265;
208 extern struct cedrus_dec_ops cedrus_dec_ops_vp8;
209
cedrus_write(struct cedrus_dev * dev,u32 reg,u32 val)210 static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
211 {
212 writel(val, dev->base + reg);
213 }
214
cedrus_read(struct cedrus_dev * dev,u32 reg)215 static inline u32 cedrus_read(struct cedrus_dev *dev, u32 reg)
216 {
217 return readl(dev->base + reg);
218 }
219
cedrus_wait_for(struct cedrus_dev * dev,u32 reg,u32 flag)220 static inline u32 cedrus_wait_for(struct cedrus_dev *dev, u32 reg, u32 flag)
221 {
222 u32 value;
223
224 return readl_poll_timeout_atomic(dev->base + reg, value,
225 (value & flag) == 0, 10, 1000);
226 }
227
cedrus_buf_addr(struct vb2_buffer * buf,struct v4l2_pix_format * pix_fmt,unsigned int plane)228 static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf,
229 struct v4l2_pix_format *pix_fmt,
230 unsigned int plane)
231 {
232 dma_addr_t addr = vb2_dma_contig_plane_dma_addr(buf, 0);
233
234 return addr + (pix_fmt ? (dma_addr_t)pix_fmt->bytesperline *
235 pix_fmt->height * plane : 0);
236 }
237
cedrus_dst_buf_addr(struct cedrus_ctx * ctx,struct vb2_buffer * buf,unsigned int plane)238 static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
239 struct vb2_buffer *buf,
240 unsigned int plane)
241 {
242 return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
243 }
244
cedrus_write_ref_buf_addr(struct cedrus_ctx * ctx,struct vb2_queue * q,u64 timestamp,u32 luma_reg,u32 chroma_reg)245 static inline void cedrus_write_ref_buf_addr(struct cedrus_ctx *ctx,
246 struct vb2_queue *q,
247 u64 timestamp,
248 u32 luma_reg,
249 u32 chroma_reg)
250 {
251 struct cedrus_dev *dev = ctx->dev;
252 struct vb2_buffer *buf = vb2_find_buffer(q, timestamp);
253
254 cedrus_write(dev, luma_reg, cedrus_dst_buf_addr(ctx, buf, 0));
255 cedrus_write(dev, chroma_reg, cedrus_dst_buf_addr(ctx, buf, 1));
256 }
257
258 static inline struct cedrus_buffer *
vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer * p)259 vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer *p)
260 {
261 return container_of(p, struct cedrus_buffer, m2m_buf.vb);
262 }
263
264 static inline struct cedrus_buffer *
vb2_to_cedrus_buffer(const struct vb2_buffer * p)265 vb2_to_cedrus_buffer(const struct vb2_buffer *p)
266 {
267 return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
268 }
269
270 static inline bool
cedrus_is_capable(struct cedrus_ctx * ctx,unsigned int capabilities)271 cedrus_is_capable(struct cedrus_ctx *ctx, unsigned int capabilities)
272 {
273 return (ctx->dev->capabilities & capabilities) == capabilities;
274 }
275
276 void *cedrus_find_control_data(struct cedrus_ctx *ctx, u32 id);
277 u32 cedrus_get_num_of_controls(struct cedrus_ctx *ctx, u32 id);
278
279 #endif
280