• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (C) 2018 BayLibre, SAS
4  * Author: Maxime Jourdan <mjourdan@baylibre.com>
5  */
6 
7 #ifndef __MESON_VDEC_CORE_H_
8 #define __MESON_VDEC_CORE_H_
9 
10 #include <linux/irqreturn.h>
11 #include <linux/regmap.h>
12 #include <linux/list.h>
13 #include <media/videobuf2-v4l2.h>
14 #include <media/v4l2-ctrls.h>
15 #include <media/v4l2-device.h>
16 #include <linux/soc/amlogic/meson-canvas.h>
17 
18 #include "vdec_platform.h"
19 
20 /* 32 buffers in 3-plane YUV420 */
21 #define MAX_CANVAS (32 * 3)
22 
23 struct amvdec_buffer {
24 	struct list_head list;
25 	struct vb2_buffer *vb;
26 };
27 
28 /**
29  * struct amvdec_timestamp - stores a src timestamp along with a VIFIFO offset
30  *
31  * @list: used to make lists out of this struct
32  * @tc: timecode from the v4l2 buffer
33  * @ts: timestamp from the VB2 buffer
34  * @offset: offset in the VIFIFO where the associated packet was written
35  * @flags: flags from the v4l2 buffer
36  * @used_count: times this timestamp was checked for a match with a dst buffer
37  */
38 struct amvdec_timestamp {
39 	struct list_head list;
40 	struct v4l2_timecode tc;
41 	u64 ts;
42 	u32 offset;
43 	u32 flags;
44 	u32 used_count;
45 };
46 
47 struct amvdec_session;
48 
49 /**
50  * struct amvdec_core - device parameters, singleton
51  *
52  * @dos_base: DOS memory base address
53  * @esparser_base: PARSER memory base address
54  * @regmap_ao: regmap for the AO bus
55  * @dev: core device
56  * @dev_dec: decoder device
57  * @platform: platform-specific data
58  * @canvas: canvas provider reference
59  * @dos_parser_clk: DOS_PARSER clock
60  * @dos_clk: DOS clock
61  * @vdec_1_clk: VDEC_1 clock
62  * @vdec_hevc_clk: VDEC_HEVC clock
63  * @vdec_hevcf_clk: VDEC_HEVCF clock
64  * @esparser_reset: RESET for the PARSER
65  * @vdev_dec: video device for the decoder
66  * @v4l2_dev: v4l2 device
67  * @cur_sess: current decoding session
68  * @lock: video device lock
69  */
70 struct amvdec_core {
71 	void __iomem *dos_base;
72 	void __iomem *esparser_base;
73 	struct regmap *regmap_ao;
74 
75 	struct device *dev;
76 	struct device *dev_dec;
77 	const struct vdec_platform *platform;
78 
79 	struct meson_canvas *canvas;
80 
81 	struct clk *dos_parser_clk;
82 	struct clk *dos_clk;
83 	struct clk *vdec_1_clk;
84 	struct clk *vdec_hevc_clk;
85 	struct clk *vdec_hevcf_clk;
86 
87 	struct reset_control *esparser_reset;
88 
89 	struct video_device *vdev_dec;
90 	struct v4l2_device v4l2_dev;
91 
92 	struct amvdec_session *cur_sess;
93 	struct mutex lock;
94 };
95 
96 /**
97  * struct amvdec_ops - vdec operations
98  *
99  * @start: mandatory call when the vdec needs to initialize
100  * @stop: mandatory call when the vdec needs to stop
101  * @conf_esparser: mandatory call to let the vdec configure the ESPARSER
102  * @vififo_level: mandatory call to get the current amount of data
103  *		  in the VIFIFO
104  * @use_offsets: mandatory call. Returns 1 if the VDEC supports vififo offsets
105  */
106 struct amvdec_ops {
107 	int (*start)(struct amvdec_session *sess);
108 	int (*stop)(struct amvdec_session *sess);
109 	void (*conf_esparser)(struct amvdec_session *sess);
110 	u32 (*vififo_level)(struct amvdec_session *sess);
111 };
112 
113 /**
114  * struct amvdec_codec_ops - codec operations
115  *
116  * @start: mandatory call when the codec needs to initialize
117  * @stop: mandatory call when the codec needs to stop
118  * @load_extended_firmware: optional call to load additional firmware bits
119  * @num_pending_bufs: optional call to get the number of dst buffers on hold
120  * @can_recycle: optional call to know if the codec is ready to recycle
121  *		 a dst buffer
122  * @recycle: optional call to tell the codec to recycle a dst buffer. Must go
123  *	     in pair with @can_recycle
124  * @drain: optional call if the codec has a custom way of draining
125  * @resume: optional call to resume after a resolution change
126  * @eos_sequence: optional call to get an end sequence to send to esparser
127  *		  for flush. Mutually exclusive with @drain.
128  * @isr: mandatory call when the ISR triggers
129  * @threaded_isr: mandatory call for the threaded ISR
130  */
131 struct amvdec_codec_ops {
132 	int (*start)(struct amvdec_session *sess);
133 	int (*stop)(struct amvdec_session *sess);
134 	int (*load_extended_firmware)(struct amvdec_session *sess,
135 				      const u8 *data, u32 len);
136 	u32 (*num_pending_bufs)(struct amvdec_session *sess);
137 	int (*can_recycle)(struct amvdec_core *core);
138 	void (*recycle)(struct amvdec_core *core, u32 buf_idx);
139 	void (*drain)(struct amvdec_session *sess);
140 	void (*resume)(struct amvdec_session *sess);
141 	const u8 * (*eos_sequence)(u32 *len);
142 	irqreturn_t (*isr)(struct amvdec_session *sess);
143 	irqreturn_t (*threaded_isr)(struct amvdec_session *sess);
144 };
145 
146 /**
147  * struct amvdec_format - describes one of the OUTPUT (src) format supported
148  *
149  * @pixfmt: V4L2 pixel format
150  * @min_buffers: minimum amount of CAPTURE (dst) buffers
151  * @max_buffers: maximum amount of CAPTURE (dst) buffers
152  * @max_width: maximum picture width supported
153  * @max_height: maximum picture height supported
154  * @flags: enum flags associated with this pixfmt
155  * @vdec_ops: the VDEC operations that support this format
156  * @codec_ops: the codec operations that support this format
157  * @firmware_path: Path to the firmware that supports this format
158  * @pixfmts_cap: list of CAPTURE pixel formats available with pixfmt
159  */
160 struct amvdec_format {
161 	u32 pixfmt;
162 	u32 min_buffers;
163 	u32 max_buffers;
164 	u32 max_width;
165 	u32 max_height;
166 	u32 flags;
167 
168 	struct amvdec_ops *vdec_ops;
169 	struct amvdec_codec_ops *codec_ops;
170 
171 	char *firmware_path;
172 	u32 pixfmts_cap[4];
173 };
174 
175 enum amvdec_status {
176 	STATUS_STOPPED,
177 	STATUS_INIT,
178 	STATUS_RUNNING,
179 	STATUS_NEEDS_RESUME,
180 };
181 
182 /**
183  * struct amvdec_session - decoding session parameters
184  *
185  * @core: reference to the vdec core struct
186  * @fh: v4l2 file handle
187  * @m2m_dev: v4l2 m2m device
188  * @m2m_ctx: v4l2 m2m context
189  * @ctrl_handler: V4L2 control handler
190  * @ctrl_min_buf_capture: V4L2 control V4L2_CID_MIN_BUFFERS_FOR_CAPTURE
191  * @lock: cap & out queues lock
192  * @fmt_out: vdec pixel format for the OUTPUT queue
193  * @pixfmt_cap: V4L2 pixel format for the CAPTURE queue
194  * @src_buffer_size: size in bytes of the OUTPUT buffers' only plane
195  * @width: current picture width
196  * @height: current picture height
197  * @colorspace: current colorspace
198  * @ycbcr_enc: current ycbcr_enc
199  * @quantization: current quantization
200  * @xfer_func: current transfer function
201  * @pixelaspect: Pixel Aspect Ratio reported by the decoder
202  * @esparser_queued_bufs: number of buffers currently queued into ESPARSER
203  * @esparser_queue_work: work struct for the ESPARSER to process src buffers
204  * @streamon_cap: stream on flag for capture queue
205  * @streamon_out: stream on flag for output queue
206  * @sequence_cap: capture sequence counter
207  * @sequence_out: output sequence counter
208  * @should_stop: flag set if userspace signaled EOS via command
209  *		 or empty buffer
210  * @keyframe_found: flag set once a keyframe has been parsed
211  * @num_dst_bufs: number of destination buffers
212  * @changed_format: the format changed
213  * @canvas_alloc: array of all the canvas IDs allocated
214  * @canvas_num: number of canvas IDs allocated
215  * @vififo_vaddr: virtual address for the VIFIFO
216  * @vififo_paddr: physical address for the VIFIFO
217  * @vififo_size: size of the VIFIFO dma alloc
218  * @bufs_recycle: list of buffers that need to be recycled
219  * @bufs_recycle_lock: lock for the bufs_recycle list
220  * @recycle_thread: task struct for the recycling thread
221  * @timestamps: chronological list of src timestamps
222  * @ts_spinlock: spinlock for the timestamps list
223  * @last_irq_jiffies: tracks last time the vdec triggered an IRQ
224  * @last_offset: tracks last offset of vififo
225  * @wrap_count: number of times the vififo wrapped around
226  * @fw_idx_to_vb2_idx: firmware buffer index to vb2 buffer index
227  * @status: current decoding status
228  * @priv: codec private data
229  */
230 struct amvdec_session {
231 	struct amvdec_core *core;
232 
233 	struct v4l2_fh fh;
234 	struct v4l2_m2m_dev *m2m_dev;
235 	struct v4l2_m2m_ctx *m2m_ctx;
236 	struct v4l2_ctrl_handler ctrl_handler;
237 	struct v4l2_ctrl *ctrl_min_buf_capture;
238 	struct mutex lock;
239 
240 	const struct amvdec_format *fmt_out;
241 	u32 pixfmt_cap;
242 	u32 src_buffer_size;
243 
244 	u32 width;
245 	u32 height;
246 	u32 colorspace;
247 	u8 ycbcr_enc;
248 	u8 quantization;
249 	u8 xfer_func;
250 
251 	struct v4l2_fract pixelaspect;
252 
253 	atomic_t esparser_queued_bufs;
254 	struct work_struct esparser_queue_work;
255 
256 	unsigned int streamon_cap, streamon_out;
257 	unsigned int sequence_cap, sequence_out;
258 	unsigned int should_stop;
259 	unsigned int keyframe_found;
260 	unsigned int num_dst_bufs;
261 	unsigned int changed_format;
262 
263 	u8 canvas_alloc[MAX_CANVAS];
264 	u32 canvas_num;
265 
266 	void *vififo_vaddr;
267 	dma_addr_t vififo_paddr;
268 	u32 vififo_size;
269 
270 	struct list_head bufs_recycle;
271 	struct mutex bufs_recycle_lock; /* bufs_recycle list lock */
272 	struct task_struct *recycle_thread;
273 
274 	struct list_head timestamps;
275 	spinlock_t ts_spinlock; /* timestamp list lock */
276 
277 	u64 last_irq_jiffies;
278 	u32 last_offset;
279 	u32 wrap_count;
280 	u32 fw_idx_to_vb2_idx[32];
281 
282 	enum amvdec_status status;
283 	void *priv;
284 };
285 
286 u32 amvdec_get_output_size(struct amvdec_session *sess);
287 
288 #endif
289