18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Memory-to-memory device framework for Video for Linux 2.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Helper functions for devices that use memory buffers for both source
68c2ecf20Sopenharmony_ci * and destination.
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Copyright (c) 2009 Samsung Electronics Co., Ltd.
98c2ecf20Sopenharmony_ci * Pawel Osciak, <pawel@osciak.com>
108c2ecf20Sopenharmony_ci * Marek Szyprowski, <m.szyprowski@samsung.com>
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#ifndef _MEDIA_V4L2_MEM2MEM_H
148c2ecf20Sopenharmony_ci#define _MEDIA_V4L2_MEM2MEM_H
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include <media/videobuf2-v4l2.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/**
198c2ecf20Sopenharmony_ci * struct v4l2_m2m_ops - mem-to-mem device driver callbacks
208c2ecf20Sopenharmony_ci * @device_run:	required. Begin the actual job (transaction) inside this
218c2ecf20Sopenharmony_ci *		callback.
228c2ecf20Sopenharmony_ci *		The job does NOT have to end before this callback returns
238c2ecf20Sopenharmony_ci *		(and it will be the usual case). When the job finishes,
248c2ecf20Sopenharmony_ci *		v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish()
258c2ecf20Sopenharmony_ci *		has to be called.
268c2ecf20Sopenharmony_ci * @job_ready:	optional. Should return 0 if the driver does not have a job
278c2ecf20Sopenharmony_ci *		fully prepared to run yet (i.e. it will not be able to finish a
288c2ecf20Sopenharmony_ci *		transaction without sleeping). If not provided, it will be
298c2ecf20Sopenharmony_ci *		assumed that one source and one destination buffer are all
308c2ecf20Sopenharmony_ci *		that is required for the driver to perform one full transaction.
318c2ecf20Sopenharmony_ci *		This method may not sleep.
328c2ecf20Sopenharmony_ci * @job_abort:	optional. Informs the driver that it has to abort the currently
338c2ecf20Sopenharmony_ci *		running transaction as soon as possible (i.e. as soon as it can
348c2ecf20Sopenharmony_ci *		stop the device safely; e.g. in the next interrupt handler),
358c2ecf20Sopenharmony_ci *		even if the transaction would not have been finished by then.
368c2ecf20Sopenharmony_ci *		After the driver performs the necessary steps, it has to call
378c2ecf20Sopenharmony_ci *		v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish() as
388c2ecf20Sopenharmony_ci *		if the transaction ended normally.
398c2ecf20Sopenharmony_ci *		This function does not have to (and will usually not) wait
408c2ecf20Sopenharmony_ci *		until the device enters a state when it can be stopped.
418c2ecf20Sopenharmony_ci */
428c2ecf20Sopenharmony_cistruct v4l2_m2m_ops {
438c2ecf20Sopenharmony_ci	void (*device_run)(void *priv);
448c2ecf20Sopenharmony_ci	int (*job_ready)(void *priv);
458c2ecf20Sopenharmony_ci	void (*job_abort)(void *priv);
468c2ecf20Sopenharmony_ci};
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistruct video_device;
498c2ecf20Sopenharmony_cistruct v4l2_m2m_dev;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci/**
528c2ecf20Sopenharmony_ci * struct v4l2_m2m_queue_ctx - represents a queue for buffers ready to be
538c2ecf20Sopenharmony_ci *	processed
548c2ecf20Sopenharmony_ci *
558c2ecf20Sopenharmony_ci * @q:		pointer to struct &vb2_queue
568c2ecf20Sopenharmony_ci * @rdy_queue:	List of V4L2 mem-to-mem queues
578c2ecf20Sopenharmony_ci * @rdy_spinlock: spin lock to protect the struct usage
588c2ecf20Sopenharmony_ci * @num_rdy:	number of buffers ready to be processed
598c2ecf20Sopenharmony_ci * @buffered:	is the queue buffered?
608c2ecf20Sopenharmony_ci *
618c2ecf20Sopenharmony_ci * Queue for buffers ready to be processed as soon as this
628c2ecf20Sopenharmony_ci * instance receives access to the device.
638c2ecf20Sopenharmony_ci */
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cistruct v4l2_m2m_queue_ctx {
668c2ecf20Sopenharmony_ci	struct vb2_queue	q;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	struct list_head	rdy_queue;
698c2ecf20Sopenharmony_ci	spinlock_t		rdy_spinlock;
708c2ecf20Sopenharmony_ci	u8			num_rdy;
718c2ecf20Sopenharmony_ci	bool			buffered;
728c2ecf20Sopenharmony_ci};
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci/**
758c2ecf20Sopenharmony_ci * struct v4l2_m2m_ctx - Memory to memory context structure
768c2ecf20Sopenharmony_ci *
778c2ecf20Sopenharmony_ci * @q_lock: struct &mutex lock
788c2ecf20Sopenharmony_ci * @new_frame: valid in the device_run callback: if true, then this
798c2ecf20Sopenharmony_ci *		starts a new frame; if false, then this is a new slice
808c2ecf20Sopenharmony_ci *		for an existing frame. This is always true unless
818c2ecf20Sopenharmony_ci *		V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF is set, which
828c2ecf20Sopenharmony_ci *		indicates slicing support.
838c2ecf20Sopenharmony_ci * @is_draining: indicates device is in draining phase
848c2ecf20Sopenharmony_ci * @last_src_buf: indicate the last source buffer for draining
858c2ecf20Sopenharmony_ci * @next_buf_last: next capture queud buffer will be tagged as last
868c2ecf20Sopenharmony_ci * @has_stopped: indicate the device has been stopped
878c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context
888c2ecf20Sopenharmony_ci * @cap_q_ctx: Capture (output to memory) queue context
898c2ecf20Sopenharmony_ci * @out_q_ctx: Output (input from memory) queue context
908c2ecf20Sopenharmony_ci * @queue: List of memory to memory contexts
918c2ecf20Sopenharmony_ci * @job_flags: Job queue flags, used internally by v4l2-mem2mem.c:
928c2ecf20Sopenharmony_ci *		%TRANS_QUEUED, %TRANS_RUNNING and %TRANS_ABORT.
938c2ecf20Sopenharmony_ci * @finished: Wait queue used to signalize when a job queue finished.
948c2ecf20Sopenharmony_ci * @priv: Instance private data
958c2ecf20Sopenharmony_ci *
968c2ecf20Sopenharmony_ci * The memory to memory context is specific to a file handle, NOT to e.g.
978c2ecf20Sopenharmony_ci * a device.
988c2ecf20Sopenharmony_ci */
998c2ecf20Sopenharmony_cistruct v4l2_m2m_ctx {
1008c2ecf20Sopenharmony_ci	/* optional cap/out vb2 queues lock */
1018c2ecf20Sopenharmony_ci	struct mutex			*q_lock;
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	bool				new_frame;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	bool				is_draining;
1068c2ecf20Sopenharmony_ci	struct vb2_v4l2_buffer		*last_src_buf;
1078c2ecf20Sopenharmony_ci	bool				next_buf_last;
1088c2ecf20Sopenharmony_ci	bool				has_stopped;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	/* internal use only */
1118c2ecf20Sopenharmony_ci	struct v4l2_m2m_dev		*m2m_dev;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	struct v4l2_m2m_queue_ctx	cap_q_ctx;
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	struct v4l2_m2m_queue_ctx	out_q_ctx;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	/* For device job queue */
1188c2ecf20Sopenharmony_ci	struct list_head		queue;
1198c2ecf20Sopenharmony_ci	unsigned long			job_flags;
1208c2ecf20Sopenharmony_ci	wait_queue_head_t		finished;
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	void				*priv;
1238c2ecf20Sopenharmony_ci};
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci/**
1268c2ecf20Sopenharmony_ci * struct v4l2_m2m_buffer - Memory to memory buffer
1278c2ecf20Sopenharmony_ci *
1288c2ecf20Sopenharmony_ci * @vb: pointer to struct &vb2_v4l2_buffer
1298c2ecf20Sopenharmony_ci * @list: list of m2m buffers
1308c2ecf20Sopenharmony_ci */
1318c2ecf20Sopenharmony_cistruct v4l2_m2m_buffer {
1328c2ecf20Sopenharmony_ci	struct vb2_v4l2_buffer	vb;
1338c2ecf20Sopenharmony_ci	struct list_head	list;
1348c2ecf20Sopenharmony_ci};
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/**
1378c2ecf20Sopenharmony_ci * v4l2_m2m_get_curr_priv() - return driver private data for the currently
1388c2ecf20Sopenharmony_ci * running instance or NULL if no instance is running
1398c2ecf20Sopenharmony_ci *
1408c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context
1418c2ecf20Sopenharmony_ci */
1428c2ecf20Sopenharmony_civoid *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev);
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci/**
1458c2ecf20Sopenharmony_ci * v4l2_m2m_get_vq() - return vb2_queue for the given type
1468c2ecf20Sopenharmony_ci *
1478c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
1488c2ecf20Sopenharmony_ci * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type
1498c2ecf20Sopenharmony_ci */
1508c2ecf20Sopenharmony_cistruct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx,
1518c2ecf20Sopenharmony_ci				       enum v4l2_buf_type type);
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci/**
1548c2ecf20Sopenharmony_ci * v4l2_m2m_try_schedule() - check whether an instance is ready to be added to
1558c2ecf20Sopenharmony_ci * the pending job queue and add it if so.
1568c2ecf20Sopenharmony_ci *
1578c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
1588c2ecf20Sopenharmony_ci *
1598c2ecf20Sopenharmony_ci * There are three basic requirements an instance has to meet to be able to run:
1608c2ecf20Sopenharmony_ci * 1) at least one source buffer has to be queued,
1618c2ecf20Sopenharmony_ci * 2) at least one destination buffer has to be queued,
1628c2ecf20Sopenharmony_ci * 3) streaming has to be on.
1638c2ecf20Sopenharmony_ci *
1648c2ecf20Sopenharmony_ci * If a queue is buffered (for example a decoder hardware ringbuffer that has
1658c2ecf20Sopenharmony_ci * to be drained before doing streamoff), allow scheduling without v4l2 buffers
1668c2ecf20Sopenharmony_ci * on that queue.
1678c2ecf20Sopenharmony_ci *
1688c2ecf20Sopenharmony_ci * There may also be additional, custom requirements. In such case the driver
1698c2ecf20Sopenharmony_ci * should supply a custom callback (job_ready in v4l2_m2m_ops) that should
1708c2ecf20Sopenharmony_ci * return 1 if the instance is ready.
1718c2ecf20Sopenharmony_ci * An example of the above could be an instance that requires more than one
1728c2ecf20Sopenharmony_ci * src/dst buffer per transaction.
1738c2ecf20Sopenharmony_ci */
1748c2ecf20Sopenharmony_civoid v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx);
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci/**
1778c2ecf20Sopenharmony_ci * v4l2_m2m_job_finish() - inform the framework that a job has been finished
1788c2ecf20Sopenharmony_ci * and have it clean up
1798c2ecf20Sopenharmony_ci *
1808c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context
1818c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
1828c2ecf20Sopenharmony_ci *
1838c2ecf20Sopenharmony_ci * Called by a driver to yield back the device after it has finished with it.
1848c2ecf20Sopenharmony_ci * Should be called as soon as possible after reaching a state which allows
1858c2ecf20Sopenharmony_ci * other instances to take control of the device.
1868c2ecf20Sopenharmony_ci *
1878c2ecf20Sopenharmony_ci * This function has to be called only after &v4l2_m2m_ops->device_run
1888c2ecf20Sopenharmony_ci * callback has been called on the driver. To prevent recursion, it should
1898c2ecf20Sopenharmony_ci * not be called directly from the &v4l2_m2m_ops->device_run callback though.
1908c2ecf20Sopenharmony_ci */
1918c2ecf20Sopenharmony_civoid v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
1928c2ecf20Sopenharmony_ci			 struct v4l2_m2m_ctx *m2m_ctx);
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci/**
1958c2ecf20Sopenharmony_ci * v4l2_m2m_buf_done_and_job_finish() - return source/destination buffers with
1968c2ecf20Sopenharmony_ci * state and inform the framework that a job has been finished and have it
1978c2ecf20Sopenharmony_ci * clean up
1988c2ecf20Sopenharmony_ci *
1998c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context
2008c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
2018c2ecf20Sopenharmony_ci * @state: vb2 buffer state passed to v4l2_m2m_buf_done().
2028c2ecf20Sopenharmony_ci *
2038c2ecf20Sopenharmony_ci * Drivers that set V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF must use this
2048c2ecf20Sopenharmony_ci * function instead of job_finish() to take held buffers into account. It is
2058c2ecf20Sopenharmony_ci * optional for other drivers.
2068c2ecf20Sopenharmony_ci *
2078c2ecf20Sopenharmony_ci * This function removes the source buffer from the ready list and returns
2088c2ecf20Sopenharmony_ci * it with the given state. The same is done for the destination buffer, unless
2098c2ecf20Sopenharmony_ci * it is marked 'held'. In that case the buffer is kept on the ready list.
2108c2ecf20Sopenharmony_ci *
2118c2ecf20Sopenharmony_ci * After that the job is finished (see job_finish()).
2128c2ecf20Sopenharmony_ci *
2138c2ecf20Sopenharmony_ci * This allows for multiple output buffers to be used to fill in a single
2148c2ecf20Sopenharmony_ci * capture buffer. This is typically used by stateless decoders where
2158c2ecf20Sopenharmony_ci * multiple e.g. H.264 slices contribute to a single decoded frame.
2168c2ecf20Sopenharmony_ci */
2178c2ecf20Sopenharmony_civoid v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev,
2188c2ecf20Sopenharmony_ci				      struct v4l2_m2m_ctx *m2m_ctx,
2198c2ecf20Sopenharmony_ci				      enum vb2_buffer_state state);
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_cistatic inline void
2228c2ecf20Sopenharmony_civ4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state)
2238c2ecf20Sopenharmony_ci{
2248c2ecf20Sopenharmony_ci	vb2_buffer_done(&buf->vb2_buf, state);
2258c2ecf20Sopenharmony_ci}
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci/**
2288c2ecf20Sopenharmony_ci * v4l2_m2m_clear_state() - clear encoding/decoding state
2298c2ecf20Sopenharmony_ci *
2308c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
2318c2ecf20Sopenharmony_ci */
2328c2ecf20Sopenharmony_cistatic inline void
2338c2ecf20Sopenharmony_civ4l2_m2m_clear_state(struct v4l2_m2m_ctx *m2m_ctx)
2348c2ecf20Sopenharmony_ci{
2358c2ecf20Sopenharmony_ci	m2m_ctx->next_buf_last = false;
2368c2ecf20Sopenharmony_ci	m2m_ctx->is_draining = false;
2378c2ecf20Sopenharmony_ci	m2m_ctx->has_stopped = false;
2388c2ecf20Sopenharmony_ci}
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci/**
2418c2ecf20Sopenharmony_ci * v4l2_m2m_mark_stopped() - set current encoding/decoding state as stopped
2428c2ecf20Sopenharmony_ci *
2438c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
2448c2ecf20Sopenharmony_ci */
2458c2ecf20Sopenharmony_cistatic inline void
2468c2ecf20Sopenharmony_civ4l2_m2m_mark_stopped(struct v4l2_m2m_ctx *m2m_ctx)
2478c2ecf20Sopenharmony_ci{
2488c2ecf20Sopenharmony_ci	m2m_ctx->next_buf_last = false;
2498c2ecf20Sopenharmony_ci	m2m_ctx->is_draining = false;
2508c2ecf20Sopenharmony_ci	m2m_ctx->has_stopped = true;
2518c2ecf20Sopenharmony_ci}
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci/**
2548c2ecf20Sopenharmony_ci * v4l2_m2m_dst_buf_is_last() - return the current encoding/decoding session
2558c2ecf20Sopenharmony_ci * draining management state of next queued capture buffer
2568c2ecf20Sopenharmony_ci *
2578c2ecf20Sopenharmony_ci * This last capture buffer should be tagged with V4L2_BUF_FLAG_LAST to notify
2588c2ecf20Sopenharmony_ci * the end of the capture session.
2598c2ecf20Sopenharmony_ci *
2608c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
2618c2ecf20Sopenharmony_ci */
2628c2ecf20Sopenharmony_cistatic inline bool
2638c2ecf20Sopenharmony_civ4l2_m2m_dst_buf_is_last(struct v4l2_m2m_ctx *m2m_ctx)
2648c2ecf20Sopenharmony_ci{
2658c2ecf20Sopenharmony_ci	return m2m_ctx->is_draining && m2m_ctx->next_buf_last;
2668c2ecf20Sopenharmony_ci}
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci/**
2698c2ecf20Sopenharmony_ci * v4l2_m2m_has_stopped() - return the current encoding/decoding session
2708c2ecf20Sopenharmony_ci * stopped state
2718c2ecf20Sopenharmony_ci *
2728c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
2738c2ecf20Sopenharmony_ci */
2748c2ecf20Sopenharmony_cistatic inline bool
2758c2ecf20Sopenharmony_civ4l2_m2m_has_stopped(struct v4l2_m2m_ctx *m2m_ctx)
2768c2ecf20Sopenharmony_ci{
2778c2ecf20Sopenharmony_ci	return m2m_ctx->has_stopped;
2788c2ecf20Sopenharmony_ci}
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci/**
2818c2ecf20Sopenharmony_ci * v4l2_m2m_is_last_draining_src_buf() - return the output buffer draining
2828c2ecf20Sopenharmony_ci * state in the current encoding/decoding session
2838c2ecf20Sopenharmony_ci *
2848c2ecf20Sopenharmony_ci * This will identify the last output buffer queued before a session stop
2858c2ecf20Sopenharmony_ci * was required, leading to an actual encoding/decoding session stop state
2868c2ecf20Sopenharmony_ci * in the encoding/decoding process after being processed.
2878c2ecf20Sopenharmony_ci *
2888c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
2898c2ecf20Sopenharmony_ci * @vbuf: pointer to struct &v4l2_buffer
2908c2ecf20Sopenharmony_ci */
2918c2ecf20Sopenharmony_cistatic inline bool
2928c2ecf20Sopenharmony_civ4l2_m2m_is_last_draining_src_buf(struct v4l2_m2m_ctx *m2m_ctx,
2938c2ecf20Sopenharmony_ci				  struct vb2_v4l2_buffer *vbuf)
2948c2ecf20Sopenharmony_ci{
2958c2ecf20Sopenharmony_ci	return m2m_ctx->is_draining && vbuf == m2m_ctx->last_src_buf;
2968c2ecf20Sopenharmony_ci}
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci/**
2998c2ecf20Sopenharmony_ci * v4l2_m2m_last_buffer_done() - marks the buffer with LAST flag and DONE
3008c2ecf20Sopenharmony_ci *
3018c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
3028c2ecf20Sopenharmony_ci * @vbuf: pointer to struct &v4l2_buffer
3038c2ecf20Sopenharmony_ci */
3048c2ecf20Sopenharmony_civoid v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx,
3058c2ecf20Sopenharmony_ci			       struct vb2_v4l2_buffer *vbuf);
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci/**
3088c2ecf20Sopenharmony_ci * v4l2_m2m_suspend() - stop new jobs from being run and wait for current job
3098c2ecf20Sopenharmony_ci * to finish
3108c2ecf20Sopenharmony_ci *
3118c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context
3128c2ecf20Sopenharmony_ci *
3138c2ecf20Sopenharmony_ci * Called by a driver in the suspend hook. Stop new jobs from being run, and
3148c2ecf20Sopenharmony_ci * wait for current running job to finish.
3158c2ecf20Sopenharmony_ci */
3168c2ecf20Sopenharmony_civoid v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci/**
3198c2ecf20Sopenharmony_ci * v4l2_m2m_resume() - resume job running and try to run a queued job
3208c2ecf20Sopenharmony_ci *
3218c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context
3228c2ecf20Sopenharmony_ci *
3238c2ecf20Sopenharmony_ci * Called by a driver in the resume hook. This reverts the operation of
3248c2ecf20Sopenharmony_ci * v4l2_m2m_suspend() and allows job to be run. Also try to run a queued job if
3258c2ecf20Sopenharmony_ci * there is any.
3268c2ecf20Sopenharmony_ci */
3278c2ecf20Sopenharmony_civoid v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev);
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci/**
3308c2ecf20Sopenharmony_ci * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer
3318c2ecf20Sopenharmony_ci *
3328c2ecf20Sopenharmony_ci * @file: pointer to struct &file
3338c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
3348c2ecf20Sopenharmony_ci * @reqbufs: pointer to struct &v4l2_requestbuffers
3358c2ecf20Sopenharmony_ci */
3368c2ecf20Sopenharmony_ciint v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
3378c2ecf20Sopenharmony_ci		     struct v4l2_requestbuffers *reqbufs);
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci/**
3408c2ecf20Sopenharmony_ci * v4l2_m2m_querybuf() - multi-queue-aware QUERYBUF multiplexer
3418c2ecf20Sopenharmony_ci *
3428c2ecf20Sopenharmony_ci * @file: pointer to struct &file
3438c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
3448c2ecf20Sopenharmony_ci * @buf: pointer to struct &v4l2_buffer
3458c2ecf20Sopenharmony_ci *
3468c2ecf20Sopenharmony_ci * See v4l2_m2m_mmap() documentation for details.
3478c2ecf20Sopenharmony_ci */
3488c2ecf20Sopenharmony_ciint v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
3498c2ecf20Sopenharmony_ci		      struct v4l2_buffer *buf);
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci/**
3528c2ecf20Sopenharmony_ci * v4l2_m2m_qbuf() - enqueue a source or destination buffer, depending on
3538c2ecf20Sopenharmony_ci * the type
3548c2ecf20Sopenharmony_ci *
3558c2ecf20Sopenharmony_ci * @file: pointer to struct &file
3568c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
3578c2ecf20Sopenharmony_ci * @buf: pointer to struct &v4l2_buffer
3588c2ecf20Sopenharmony_ci */
3598c2ecf20Sopenharmony_ciint v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
3608c2ecf20Sopenharmony_ci		  struct v4l2_buffer *buf);
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci/**
3638c2ecf20Sopenharmony_ci * v4l2_m2m_dqbuf() - dequeue a source or destination buffer, depending on
3648c2ecf20Sopenharmony_ci * the type
3658c2ecf20Sopenharmony_ci *
3668c2ecf20Sopenharmony_ci * @file: pointer to struct &file
3678c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
3688c2ecf20Sopenharmony_ci * @buf: pointer to struct &v4l2_buffer
3698c2ecf20Sopenharmony_ci */
3708c2ecf20Sopenharmony_ciint v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
3718c2ecf20Sopenharmony_ci		   struct v4l2_buffer *buf);
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci/**
3748c2ecf20Sopenharmony_ci * v4l2_m2m_prepare_buf() - prepare a source or destination buffer, depending on
3758c2ecf20Sopenharmony_ci * the type
3768c2ecf20Sopenharmony_ci *
3778c2ecf20Sopenharmony_ci * @file: pointer to struct &file
3788c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
3798c2ecf20Sopenharmony_ci * @buf: pointer to struct &v4l2_buffer
3808c2ecf20Sopenharmony_ci */
3818c2ecf20Sopenharmony_ciint v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
3828c2ecf20Sopenharmony_ci			 struct v4l2_buffer *buf);
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci/**
3858c2ecf20Sopenharmony_ci * v4l2_m2m_create_bufs() - create a source or destination buffer, depending
3868c2ecf20Sopenharmony_ci * on the type
3878c2ecf20Sopenharmony_ci *
3888c2ecf20Sopenharmony_ci * @file: pointer to struct &file
3898c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
3908c2ecf20Sopenharmony_ci * @create: pointer to struct &v4l2_create_buffers
3918c2ecf20Sopenharmony_ci */
3928c2ecf20Sopenharmony_ciint v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
3938c2ecf20Sopenharmony_ci			 struct v4l2_create_buffers *create);
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci/**
3968c2ecf20Sopenharmony_ci * v4l2_m2m_expbuf() - export a source or destination buffer, depending on
3978c2ecf20Sopenharmony_ci * the type
3988c2ecf20Sopenharmony_ci *
3998c2ecf20Sopenharmony_ci * @file: pointer to struct &file
4008c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
4018c2ecf20Sopenharmony_ci * @eb: pointer to struct &v4l2_exportbuffer
4028c2ecf20Sopenharmony_ci */
4038c2ecf20Sopenharmony_ciint v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
4048c2ecf20Sopenharmony_ci		   struct v4l2_exportbuffer *eb);
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci/**
4078c2ecf20Sopenharmony_ci * v4l2_m2m_streamon() - turn on streaming for a video queue
4088c2ecf20Sopenharmony_ci *
4098c2ecf20Sopenharmony_ci * @file: pointer to struct &file
4108c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
4118c2ecf20Sopenharmony_ci * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type
4128c2ecf20Sopenharmony_ci */
4138c2ecf20Sopenharmony_ciint v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
4148c2ecf20Sopenharmony_ci		      enum v4l2_buf_type type);
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci/**
4178c2ecf20Sopenharmony_ci * v4l2_m2m_streamoff() - turn off streaming for a video queue
4188c2ecf20Sopenharmony_ci *
4198c2ecf20Sopenharmony_ci * @file: pointer to struct &file
4208c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
4218c2ecf20Sopenharmony_ci * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type
4228c2ecf20Sopenharmony_ci */
4238c2ecf20Sopenharmony_ciint v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
4248c2ecf20Sopenharmony_ci		       enum v4l2_buf_type type);
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci/**
4278c2ecf20Sopenharmony_ci * v4l2_m2m_update_start_streaming_state() - update the encoding/decoding
4288c2ecf20Sopenharmony_ci * session state when a start of streaming of a video queue is requested
4298c2ecf20Sopenharmony_ci *
4308c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
4318c2ecf20Sopenharmony_ci * @q: queue
4328c2ecf20Sopenharmony_ci */
4338c2ecf20Sopenharmony_civoid v4l2_m2m_update_start_streaming_state(struct v4l2_m2m_ctx *m2m_ctx,
4348c2ecf20Sopenharmony_ci					   struct vb2_queue *q);
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci/**
4378c2ecf20Sopenharmony_ci * v4l2_m2m_update_stop_streaming_state() -  update the encoding/decoding
4388c2ecf20Sopenharmony_ci * session state when a stop of streaming of a video queue is requested
4398c2ecf20Sopenharmony_ci *
4408c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
4418c2ecf20Sopenharmony_ci * @q: queue
4428c2ecf20Sopenharmony_ci */
4438c2ecf20Sopenharmony_civoid v4l2_m2m_update_stop_streaming_state(struct v4l2_m2m_ctx *m2m_ctx,
4448c2ecf20Sopenharmony_ci					  struct vb2_queue *q);
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_ci/**
4478c2ecf20Sopenharmony_ci * v4l2_m2m_encoder_cmd() - execute an encoder command
4488c2ecf20Sopenharmony_ci *
4498c2ecf20Sopenharmony_ci * @file: pointer to struct &file
4508c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
4518c2ecf20Sopenharmony_ci * @ec: pointer to the encoder command
4528c2ecf20Sopenharmony_ci */
4538c2ecf20Sopenharmony_ciint v4l2_m2m_encoder_cmd(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
4548c2ecf20Sopenharmony_ci			 struct v4l2_encoder_cmd *ec);
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci/**
4578c2ecf20Sopenharmony_ci * v4l2_m2m_decoder_cmd() - execute a decoder command
4588c2ecf20Sopenharmony_ci *
4598c2ecf20Sopenharmony_ci * @file: pointer to struct &file
4608c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
4618c2ecf20Sopenharmony_ci * @dc: pointer to the decoder command
4628c2ecf20Sopenharmony_ci */
4638c2ecf20Sopenharmony_ciint v4l2_m2m_decoder_cmd(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
4648c2ecf20Sopenharmony_ci			 struct v4l2_decoder_cmd *dc);
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci/**
4678c2ecf20Sopenharmony_ci * v4l2_m2m_poll() - poll replacement, for destination buffers only
4688c2ecf20Sopenharmony_ci *
4698c2ecf20Sopenharmony_ci * @file: pointer to struct &file
4708c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
4718c2ecf20Sopenharmony_ci * @wait: pointer to struct &poll_table_struct
4728c2ecf20Sopenharmony_ci *
4738c2ecf20Sopenharmony_ci * Call from the driver's poll() function. Will poll both queues. If a buffer
4748c2ecf20Sopenharmony_ci * is available to dequeue (with dqbuf) from the source queue, this will
4758c2ecf20Sopenharmony_ci * indicate that a non-blocking write can be performed, while read will be
4768c2ecf20Sopenharmony_ci * returned in case of the destination queue.
4778c2ecf20Sopenharmony_ci */
4788c2ecf20Sopenharmony_ci__poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
4798c2ecf20Sopenharmony_ci			   struct poll_table_struct *wait);
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci/**
4828c2ecf20Sopenharmony_ci * v4l2_m2m_mmap() - source and destination queues-aware mmap multiplexer
4838c2ecf20Sopenharmony_ci *
4848c2ecf20Sopenharmony_ci * @file: pointer to struct &file
4858c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
4868c2ecf20Sopenharmony_ci * @vma: pointer to struct &vm_area_struct
4878c2ecf20Sopenharmony_ci *
4888c2ecf20Sopenharmony_ci * Call from driver's mmap() function. Will handle mmap() for both queues
4898c2ecf20Sopenharmony_ci * seamlessly for videobuffer, which will receive normal per-queue offsets and
4908c2ecf20Sopenharmony_ci * proper videobuf queue pointers. The differentiation is made outside videobuf
4918c2ecf20Sopenharmony_ci * by adding a predefined offset to buffers from one of the queues and
4928c2ecf20Sopenharmony_ci * subtracting it before passing it back to videobuf. Only drivers (and
4938c2ecf20Sopenharmony_ci * thus applications) receive modified offsets.
4948c2ecf20Sopenharmony_ci */
4958c2ecf20Sopenharmony_ciint v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
4968c2ecf20Sopenharmony_ci		  struct vm_area_struct *vma);
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci/**
4998c2ecf20Sopenharmony_ci * v4l2_m2m_init() - initialize per-driver m2m data
5008c2ecf20Sopenharmony_ci *
5018c2ecf20Sopenharmony_ci * @m2m_ops: pointer to struct v4l2_m2m_ops
5028c2ecf20Sopenharmony_ci *
5038c2ecf20Sopenharmony_ci * Usually called from driver's ``probe()`` function.
5048c2ecf20Sopenharmony_ci *
5058c2ecf20Sopenharmony_ci * Return: returns an opaque pointer to the internal data to handle M2M context
5068c2ecf20Sopenharmony_ci */
5078c2ecf20Sopenharmony_cistruct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops);
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ci#if defined(CONFIG_MEDIA_CONTROLLER)
5108c2ecf20Sopenharmony_civoid v4l2_m2m_unregister_media_controller(struct v4l2_m2m_dev *m2m_dev);
5118c2ecf20Sopenharmony_ciint v4l2_m2m_register_media_controller(struct v4l2_m2m_dev *m2m_dev,
5128c2ecf20Sopenharmony_ci			struct video_device *vdev, int function);
5138c2ecf20Sopenharmony_ci#else
5148c2ecf20Sopenharmony_cistatic inline void
5158c2ecf20Sopenharmony_civ4l2_m2m_unregister_media_controller(struct v4l2_m2m_dev *m2m_dev)
5168c2ecf20Sopenharmony_ci{
5178c2ecf20Sopenharmony_ci}
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_cistatic inline int
5208c2ecf20Sopenharmony_civ4l2_m2m_register_media_controller(struct v4l2_m2m_dev *m2m_dev,
5218c2ecf20Sopenharmony_ci		struct video_device *vdev, int function)
5228c2ecf20Sopenharmony_ci{
5238c2ecf20Sopenharmony_ci	return 0;
5248c2ecf20Sopenharmony_ci}
5258c2ecf20Sopenharmony_ci#endif
5268c2ecf20Sopenharmony_ci
5278c2ecf20Sopenharmony_ci/**
5288c2ecf20Sopenharmony_ci * v4l2_m2m_release() - cleans up and frees a m2m_dev structure
5298c2ecf20Sopenharmony_ci *
5308c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context
5318c2ecf20Sopenharmony_ci *
5328c2ecf20Sopenharmony_ci * Usually called from driver's ``remove()`` function.
5338c2ecf20Sopenharmony_ci */
5348c2ecf20Sopenharmony_civoid v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev);
5358c2ecf20Sopenharmony_ci
5368c2ecf20Sopenharmony_ci/**
5378c2ecf20Sopenharmony_ci * v4l2_m2m_ctx_init() - allocate and initialize a m2m context
5388c2ecf20Sopenharmony_ci *
5398c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context
5408c2ecf20Sopenharmony_ci * @drv_priv: driver's instance private data
5418c2ecf20Sopenharmony_ci * @queue_init: a callback for queue type-specific initialization function
5428c2ecf20Sopenharmony_ci *	to be used for initializing videobuf_queues
5438c2ecf20Sopenharmony_ci *
5448c2ecf20Sopenharmony_ci * Usually called from driver's ``open()`` function.
5458c2ecf20Sopenharmony_ci */
5468c2ecf20Sopenharmony_cistruct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
5478c2ecf20Sopenharmony_ci		void *drv_priv,
5488c2ecf20Sopenharmony_ci		int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq));
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_cistatic inline void v4l2_m2m_set_src_buffered(struct v4l2_m2m_ctx *m2m_ctx,
5518c2ecf20Sopenharmony_ci					     bool buffered)
5528c2ecf20Sopenharmony_ci{
5538c2ecf20Sopenharmony_ci	m2m_ctx->out_q_ctx.buffered = buffered;
5548c2ecf20Sopenharmony_ci}
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_cistatic inline void v4l2_m2m_set_dst_buffered(struct v4l2_m2m_ctx *m2m_ctx,
5578c2ecf20Sopenharmony_ci					     bool buffered)
5588c2ecf20Sopenharmony_ci{
5598c2ecf20Sopenharmony_ci	m2m_ctx->cap_q_ctx.buffered = buffered;
5608c2ecf20Sopenharmony_ci}
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_ci/**
5638c2ecf20Sopenharmony_ci * v4l2_m2m_ctx_release() - release m2m context
5648c2ecf20Sopenharmony_ci *
5658c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
5668c2ecf20Sopenharmony_ci *
5678c2ecf20Sopenharmony_ci * Usually called from driver's release() function.
5688c2ecf20Sopenharmony_ci */
5698c2ecf20Sopenharmony_civoid v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx);
5708c2ecf20Sopenharmony_ci
5718c2ecf20Sopenharmony_ci/**
5728c2ecf20Sopenharmony_ci * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list.
5738c2ecf20Sopenharmony_ci *
5748c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
5758c2ecf20Sopenharmony_ci * @vbuf: pointer to struct &vb2_v4l2_buffer
5768c2ecf20Sopenharmony_ci *
5778c2ecf20Sopenharmony_ci * Call from videobuf_queue_ops->ops->buf_queue, videobuf_queue_ops callback.
5788c2ecf20Sopenharmony_ci */
5798c2ecf20Sopenharmony_civoid v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx,
5808c2ecf20Sopenharmony_ci			struct vb2_v4l2_buffer *vbuf);
5818c2ecf20Sopenharmony_ci
5828c2ecf20Sopenharmony_ci/**
5838c2ecf20Sopenharmony_ci * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for
5848c2ecf20Sopenharmony_ci * use
5858c2ecf20Sopenharmony_ci *
5868c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
5878c2ecf20Sopenharmony_ci */
5888c2ecf20Sopenharmony_cistatic inline
5898c2ecf20Sopenharmony_ciunsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
5908c2ecf20Sopenharmony_ci{
5918c2ecf20Sopenharmony_ci	unsigned int num_buf_rdy;
5928c2ecf20Sopenharmony_ci	unsigned long flags;
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_ci	spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
5958c2ecf20Sopenharmony_ci	num_buf_rdy = m2m_ctx->out_q_ctx.num_rdy;
5968c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
5978c2ecf20Sopenharmony_ci
5988c2ecf20Sopenharmony_ci	return num_buf_rdy;
5998c2ecf20Sopenharmony_ci}
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_ci/**
6028c2ecf20Sopenharmony_ci * v4l2_m2m_num_dst_bufs_ready() - return the number of destination buffers
6038c2ecf20Sopenharmony_ci * ready for use
6048c2ecf20Sopenharmony_ci *
6058c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
6068c2ecf20Sopenharmony_ci */
6078c2ecf20Sopenharmony_cistatic inline
6088c2ecf20Sopenharmony_ciunsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
6098c2ecf20Sopenharmony_ci{
6108c2ecf20Sopenharmony_ci	unsigned int num_buf_rdy;
6118c2ecf20Sopenharmony_ci	unsigned long flags;
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_ci	spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
6148c2ecf20Sopenharmony_ci	num_buf_rdy = m2m_ctx->cap_q_ctx.num_rdy;
6158c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_ci	return num_buf_rdy;
6188c2ecf20Sopenharmony_ci}
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_ci/**
6218c2ecf20Sopenharmony_ci * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers
6228c2ecf20Sopenharmony_ci *
6238c2ecf20Sopenharmony_ci * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
6248c2ecf20Sopenharmony_ci */
6258c2ecf20Sopenharmony_cistruct vb2_v4l2_buffer *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx);
6268c2ecf20Sopenharmony_ci
6278c2ecf20Sopenharmony_ci/**
6288c2ecf20Sopenharmony_ci * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready
6298c2ecf20Sopenharmony_ci * buffers
6308c2ecf20Sopenharmony_ci *
6318c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
6328c2ecf20Sopenharmony_ci */
6338c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer *
6348c2ecf20Sopenharmony_civ4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx)
6358c2ecf20Sopenharmony_ci{
6368c2ecf20Sopenharmony_ci	return v4l2_m2m_next_buf(&m2m_ctx->out_q_ctx);
6378c2ecf20Sopenharmony_ci}
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_ci/**
6408c2ecf20Sopenharmony_ci * v4l2_m2m_next_dst_buf() - return next destination buffer from the list of
6418c2ecf20Sopenharmony_ci * ready buffers
6428c2ecf20Sopenharmony_ci *
6438c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
6448c2ecf20Sopenharmony_ci */
6458c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer *
6468c2ecf20Sopenharmony_civ4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
6478c2ecf20Sopenharmony_ci{
6488c2ecf20Sopenharmony_ci	return v4l2_m2m_next_buf(&m2m_ctx->cap_q_ctx);
6498c2ecf20Sopenharmony_ci}
6508c2ecf20Sopenharmony_ci
6518c2ecf20Sopenharmony_ci/**
6528c2ecf20Sopenharmony_ci * v4l2_m2m_last_buf() - return last buffer from the list of ready buffers
6538c2ecf20Sopenharmony_ci *
6548c2ecf20Sopenharmony_ci * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
6558c2ecf20Sopenharmony_ci */
6568c2ecf20Sopenharmony_cistruct vb2_v4l2_buffer *v4l2_m2m_last_buf(struct v4l2_m2m_queue_ctx *q_ctx);
6578c2ecf20Sopenharmony_ci
6588c2ecf20Sopenharmony_ci/**
6598c2ecf20Sopenharmony_ci * v4l2_m2m_last_src_buf() - return last destination buffer from the list of
6608c2ecf20Sopenharmony_ci * ready buffers
6618c2ecf20Sopenharmony_ci *
6628c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
6638c2ecf20Sopenharmony_ci */
6648c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer *
6658c2ecf20Sopenharmony_civ4l2_m2m_last_src_buf(struct v4l2_m2m_ctx *m2m_ctx)
6668c2ecf20Sopenharmony_ci{
6678c2ecf20Sopenharmony_ci	return v4l2_m2m_last_buf(&m2m_ctx->out_q_ctx);
6688c2ecf20Sopenharmony_ci}
6698c2ecf20Sopenharmony_ci
6708c2ecf20Sopenharmony_ci/**
6718c2ecf20Sopenharmony_ci * v4l2_m2m_last_dst_buf() - return last destination buffer from the list of
6728c2ecf20Sopenharmony_ci * ready buffers
6738c2ecf20Sopenharmony_ci *
6748c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
6758c2ecf20Sopenharmony_ci */
6768c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer *
6778c2ecf20Sopenharmony_civ4l2_m2m_last_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
6788c2ecf20Sopenharmony_ci{
6798c2ecf20Sopenharmony_ci	return v4l2_m2m_last_buf(&m2m_ctx->cap_q_ctx);
6808c2ecf20Sopenharmony_ci}
6818c2ecf20Sopenharmony_ci
6828c2ecf20Sopenharmony_ci/**
6838c2ecf20Sopenharmony_ci * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
6848c2ecf20Sopenharmony_ci * buffers
6858c2ecf20Sopenharmony_ci *
6868c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
6878c2ecf20Sopenharmony_ci * @b: current buffer of type struct v4l2_m2m_buffer
6888c2ecf20Sopenharmony_ci */
6898c2ecf20Sopenharmony_ci#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)	\
6908c2ecf20Sopenharmony_ci	list_for_each_entry(b, &m2m_ctx->cap_q_ctx.rdy_queue, list)
6918c2ecf20Sopenharmony_ci
6928c2ecf20Sopenharmony_ci/**
6938c2ecf20Sopenharmony_ci * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
6948c2ecf20Sopenharmony_ci *
6958c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
6968c2ecf20Sopenharmony_ci * @b: current buffer of type struct v4l2_m2m_buffer
6978c2ecf20Sopenharmony_ci */
6988c2ecf20Sopenharmony_ci#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)	\
6998c2ecf20Sopenharmony_ci	list_for_each_entry(b, &m2m_ctx->out_q_ctx.rdy_queue, list)
7008c2ecf20Sopenharmony_ci
7018c2ecf20Sopenharmony_ci/**
7028c2ecf20Sopenharmony_ci * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
7038c2ecf20Sopenharmony_ci * buffers safely
7048c2ecf20Sopenharmony_ci *
7058c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
7068c2ecf20Sopenharmony_ci * @b: current buffer of type struct v4l2_m2m_buffer
7078c2ecf20Sopenharmony_ci * @n: used as temporary storage
7088c2ecf20Sopenharmony_ci */
7098c2ecf20Sopenharmony_ci#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)	\
7108c2ecf20Sopenharmony_ci	list_for_each_entry_safe(b, n, &m2m_ctx->cap_q_ctx.rdy_queue, list)
7118c2ecf20Sopenharmony_ci
7128c2ecf20Sopenharmony_ci/**
7138c2ecf20Sopenharmony_ci * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
7148c2ecf20Sopenharmony_ci * buffers safely
7158c2ecf20Sopenharmony_ci *
7168c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
7178c2ecf20Sopenharmony_ci * @b: current buffer of type struct v4l2_m2m_buffer
7188c2ecf20Sopenharmony_ci * @n: used as temporary storage
7198c2ecf20Sopenharmony_ci */
7208c2ecf20Sopenharmony_ci#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)	\
7218c2ecf20Sopenharmony_ci	list_for_each_entry_safe(b, n, &m2m_ctx->out_q_ctx.rdy_queue, list)
7228c2ecf20Sopenharmony_ci
7238c2ecf20Sopenharmony_ci/**
7248c2ecf20Sopenharmony_ci * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
7258c2ecf20Sopenharmony_ci *
7268c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
7278c2ecf20Sopenharmony_ci */
7288c2ecf20Sopenharmony_cistatic inline
7298c2ecf20Sopenharmony_cistruct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx)
7308c2ecf20Sopenharmony_ci{
7318c2ecf20Sopenharmony_ci	return &m2m_ctx->out_q_ctx.q;
7328c2ecf20Sopenharmony_ci}
7338c2ecf20Sopenharmony_ci
7348c2ecf20Sopenharmony_ci/**
7358c2ecf20Sopenharmony_ci * v4l2_m2m_get_dst_vq() - return vb2_queue for destination buffers
7368c2ecf20Sopenharmony_ci *
7378c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
7388c2ecf20Sopenharmony_ci */
7398c2ecf20Sopenharmony_cistatic inline
7408c2ecf20Sopenharmony_cistruct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx)
7418c2ecf20Sopenharmony_ci{
7428c2ecf20Sopenharmony_ci	return &m2m_ctx->cap_q_ctx.q;
7438c2ecf20Sopenharmony_ci}
7448c2ecf20Sopenharmony_ci
7458c2ecf20Sopenharmony_ci/**
7468c2ecf20Sopenharmony_ci * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and
7478c2ecf20Sopenharmony_ci * return it
7488c2ecf20Sopenharmony_ci *
7498c2ecf20Sopenharmony_ci * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
7508c2ecf20Sopenharmony_ci */
7518c2ecf20Sopenharmony_cistruct vb2_v4l2_buffer *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx);
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_ci/**
7548c2ecf20Sopenharmony_ci * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready
7558c2ecf20Sopenharmony_ci * buffers and return it
7568c2ecf20Sopenharmony_ci *
7578c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
7588c2ecf20Sopenharmony_ci */
7598c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer *
7608c2ecf20Sopenharmony_civ4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
7618c2ecf20Sopenharmony_ci{
7628c2ecf20Sopenharmony_ci	return v4l2_m2m_buf_remove(&m2m_ctx->out_q_ctx);
7638c2ecf20Sopenharmony_ci}
7648c2ecf20Sopenharmony_ci
7658c2ecf20Sopenharmony_ci/**
7668c2ecf20Sopenharmony_ci * v4l2_m2m_dst_buf_remove() - take off a destination buffer from the list of
7678c2ecf20Sopenharmony_ci * ready buffers and return it
7688c2ecf20Sopenharmony_ci *
7698c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
7708c2ecf20Sopenharmony_ci */
7718c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer *
7728c2ecf20Sopenharmony_civ4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
7738c2ecf20Sopenharmony_ci{
7748c2ecf20Sopenharmony_ci	return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
7758c2ecf20Sopenharmony_ci}
7768c2ecf20Sopenharmony_ci
7778c2ecf20Sopenharmony_ci/**
7788c2ecf20Sopenharmony_ci * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of ready
7798c2ecf20Sopenharmony_ci * buffers
7808c2ecf20Sopenharmony_ci *
7818c2ecf20Sopenharmony_ci * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
7828c2ecf20Sopenharmony_ci * @vbuf: the buffer to be removed
7838c2ecf20Sopenharmony_ci */
7848c2ecf20Sopenharmony_civoid v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
7858c2ecf20Sopenharmony_ci				struct vb2_v4l2_buffer *vbuf);
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_ci/**
7888c2ecf20Sopenharmony_ci * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the list
7898c2ecf20Sopenharmony_ci * of ready buffers
7908c2ecf20Sopenharmony_ci *
7918c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
7928c2ecf20Sopenharmony_ci * @vbuf: the buffer to be removed
7938c2ecf20Sopenharmony_ci */
7948c2ecf20Sopenharmony_cistatic inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
7958c2ecf20Sopenharmony_ci						  struct vb2_v4l2_buffer *vbuf)
7968c2ecf20Sopenharmony_ci{
7978c2ecf20Sopenharmony_ci	v4l2_m2m_buf_remove_by_buf(&m2m_ctx->out_q_ctx, vbuf);
7988c2ecf20Sopenharmony_ci}
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_ci/**
8018c2ecf20Sopenharmony_ci * v4l2_m2m_dst_buf_remove_by_buf() - take off exact destination buffer from the
8028c2ecf20Sopenharmony_ci * list of ready buffers
8038c2ecf20Sopenharmony_ci *
8048c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
8058c2ecf20Sopenharmony_ci * @vbuf: the buffer to be removed
8068c2ecf20Sopenharmony_ci */
8078c2ecf20Sopenharmony_cistatic inline void v4l2_m2m_dst_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
8088c2ecf20Sopenharmony_ci						  struct vb2_v4l2_buffer *vbuf)
8098c2ecf20Sopenharmony_ci{
8108c2ecf20Sopenharmony_ci	v4l2_m2m_buf_remove_by_buf(&m2m_ctx->cap_q_ctx, vbuf);
8118c2ecf20Sopenharmony_ci}
8128c2ecf20Sopenharmony_ci
8138c2ecf20Sopenharmony_cistruct vb2_v4l2_buffer *
8148c2ecf20Sopenharmony_civ4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx);
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer *
8178c2ecf20Sopenharmony_civ4l2_m2m_src_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
8188c2ecf20Sopenharmony_ci{
8198c2ecf20Sopenharmony_ci	return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->out_q_ctx, idx);
8208c2ecf20Sopenharmony_ci}
8218c2ecf20Sopenharmony_ci
8228c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer *
8238c2ecf20Sopenharmony_civ4l2_m2m_dst_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
8248c2ecf20Sopenharmony_ci{
8258c2ecf20Sopenharmony_ci	return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->cap_q_ctx, idx);
8268c2ecf20Sopenharmony_ci}
8278c2ecf20Sopenharmony_ci
8288c2ecf20Sopenharmony_ci/**
8298c2ecf20Sopenharmony_ci * v4l2_m2m_buf_copy_metadata() - copy buffer metadata from
8308c2ecf20Sopenharmony_ci * the output buffer to the capture buffer
8318c2ecf20Sopenharmony_ci *
8328c2ecf20Sopenharmony_ci * @out_vb: the output buffer that is the source of the metadata.
8338c2ecf20Sopenharmony_ci * @cap_vb: the capture buffer that will receive the metadata.
8348c2ecf20Sopenharmony_ci * @copy_frame_flags: copy the KEY/B/PFRAME flags as well.
8358c2ecf20Sopenharmony_ci *
8368c2ecf20Sopenharmony_ci * This helper function copies the timestamp, timecode (if the TIMECODE
8378c2ecf20Sopenharmony_ci * buffer flag was set), field and the TIMECODE, KEYFRAME, BFRAME, PFRAME
8388c2ecf20Sopenharmony_ci * and TSTAMP_SRC_MASK flags from @out_vb to @cap_vb.
8398c2ecf20Sopenharmony_ci *
8408c2ecf20Sopenharmony_ci * If @copy_frame_flags is false, then the KEYFRAME, BFRAME and PFRAME
8418c2ecf20Sopenharmony_ci * flags are not copied. This is typically needed for encoders that
8428c2ecf20Sopenharmony_ci * set this bits explicitly.
8438c2ecf20Sopenharmony_ci */
8448c2ecf20Sopenharmony_civoid v4l2_m2m_buf_copy_metadata(const struct vb2_v4l2_buffer *out_vb,
8458c2ecf20Sopenharmony_ci				struct vb2_v4l2_buffer *cap_vb,
8468c2ecf20Sopenharmony_ci				bool copy_frame_flags);
8478c2ecf20Sopenharmony_ci
8488c2ecf20Sopenharmony_ci/* v4l2 request helper */
8498c2ecf20Sopenharmony_ci
8508c2ecf20Sopenharmony_civoid v4l2_m2m_request_queue(struct media_request *req);
8518c2ecf20Sopenharmony_ci
8528c2ecf20Sopenharmony_ci/* v4l2 ioctl helpers */
8538c2ecf20Sopenharmony_ci
8548c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
8558c2ecf20Sopenharmony_ci				struct v4l2_requestbuffers *rb);
8568c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_create_bufs(struct file *file, void *fh,
8578c2ecf20Sopenharmony_ci				struct v4l2_create_buffers *create);
8588c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_querybuf(struct file *file, void *fh,
8598c2ecf20Sopenharmony_ci				struct v4l2_buffer *buf);
8608c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_expbuf(struct file *file, void *fh,
8618c2ecf20Sopenharmony_ci				struct v4l2_exportbuffer *eb);
8628c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_qbuf(struct file *file, void *fh,
8638c2ecf20Sopenharmony_ci				struct v4l2_buffer *buf);
8648c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_dqbuf(struct file *file, void *fh,
8658c2ecf20Sopenharmony_ci				struct v4l2_buffer *buf);
8668c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_prepare_buf(struct file *file, void *fh,
8678c2ecf20Sopenharmony_ci			       struct v4l2_buffer *buf);
8688c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_streamon(struct file *file, void *fh,
8698c2ecf20Sopenharmony_ci				enum v4l2_buf_type type);
8708c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_streamoff(struct file *file, void *fh,
8718c2ecf20Sopenharmony_ci				enum v4l2_buf_type type);
8728c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_encoder_cmd(struct file *file, void *fh,
8738c2ecf20Sopenharmony_ci			       struct v4l2_encoder_cmd *ec);
8748c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_decoder_cmd(struct file *file, void *fh,
8758c2ecf20Sopenharmony_ci			       struct v4l2_decoder_cmd *dc);
8768c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_try_encoder_cmd(struct file *file, void *fh,
8778c2ecf20Sopenharmony_ci				   struct v4l2_encoder_cmd *ec);
8788c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_try_decoder_cmd(struct file *file, void *fh,
8798c2ecf20Sopenharmony_ci				   struct v4l2_decoder_cmd *dc);
8808c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *fh,
8818c2ecf20Sopenharmony_ci					     struct v4l2_decoder_cmd *dc);
8828c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_stateless_decoder_cmd(struct file *file, void *priv,
8838c2ecf20Sopenharmony_ci					 struct v4l2_decoder_cmd *dc);
8848c2ecf20Sopenharmony_ciint v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma);
8858c2ecf20Sopenharmony_ci__poll_t v4l2_m2m_fop_poll(struct file *file, poll_table *wait);
8868c2ecf20Sopenharmony_ci
8878c2ecf20Sopenharmony_ci#endif /* _MEDIA_V4L2_MEM2MEM_H */
8888c2ecf20Sopenharmony_ci
889