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