1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Rockchip Video Decoder driver
4 *
5 * Copyright (C) 2019 Collabora, Ltd.
6 *
7 * Based on rkvdec driver by Google LLC. (Tomasz Figa <tfiga@chromium.org>)
8 * Based on s5p-mfc driver by Samsung Electronics Co., Ltd.
9 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
10 */
11#ifndef RKVDEC_H_
12#define RKVDEC_H_
13
14#include <linux/platform_device.h>
15#include <linux/videodev2.h>
16#include <linux/wait.h>
17#include <linux/clk.h>
18
19#include <media/v4l2-ctrls.h>
20#include <media/v4l2-device.h>
21#include <media/v4l2-ioctl.h>
22#include <media/videobuf2-core.h>
23#include <media/videobuf2-dma-contig.h>
24
25struct rkvdec_ctx;
26
27struct rkvdec_ctrl_desc {
28	struct v4l2_ctrl_config cfg;
29};
30
31struct rkvdec_ctrls {
32	const struct rkvdec_ctrl_desc *ctrls;
33	unsigned int num_ctrls;
34};
35
36struct rkvdec_run {
37	struct {
38		struct vb2_v4l2_buffer *src;
39		struct vb2_v4l2_buffer *dst;
40	} bufs;
41};
42
43struct rkvdec_vp9_decoded_buffer_info {
44	/* Info needed when the decoded frame serves as a reference frame. */
45	unsigned short width;
46	unsigned short height;
47	unsigned int bit_depth : 4;
48};
49
50struct rkvdec_decoded_buffer {
51	/* Must be the first field in this struct. */
52	struct v4l2_m2m_buffer base;
53
54	union {
55		struct rkvdec_vp9_decoded_buffer_info vp9;
56	};
57};
58
59static inline struct rkvdec_decoded_buffer *
60vb2_to_rkvdec_decoded_buf(struct vb2_buffer *buf)
61{
62	return container_of(buf, struct rkvdec_decoded_buffer,
63			    base.vb.vb2_buf);
64}
65
66struct rkvdec_coded_fmt_ops {
67	int (*adjust_fmt)(struct rkvdec_ctx *ctx,
68			  struct v4l2_format *f);
69	int (*start)(struct rkvdec_ctx *ctx);
70	void (*stop)(struct rkvdec_ctx *ctx);
71	int (*run)(struct rkvdec_ctx *ctx);
72	void (*done)(struct rkvdec_ctx *ctx, struct vb2_v4l2_buffer *src_buf,
73		     struct vb2_v4l2_buffer *dst_buf,
74		     enum vb2_buffer_state result);
75	int (*try_ctrl)(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl);
76};
77
78struct rkvdec_coded_fmt_desc {
79	u32 fourcc;
80	struct v4l2_frmsize_stepwise frmsize;
81	const struct rkvdec_ctrls *ctrls;
82	const struct rkvdec_coded_fmt_ops *ops;
83	unsigned int num_decoded_fmts;
84	const u32 *decoded_fmts;
85	u32 subsystem_flags;
86};
87
88struct rkvdec_dev {
89	struct v4l2_device v4l2_dev;
90	struct media_device mdev;
91	struct video_device vdev;
92	struct v4l2_m2m_dev *m2m_dev;
93	struct device *dev;
94	struct clk_bulk_data *clocks;
95	void __iomem *regs;
96	struct mutex vdev_lock; /* serializes ioctls */
97	struct delayed_work watchdog_work;
98};
99
100struct rkvdec_ctx {
101	struct v4l2_fh fh;
102	struct v4l2_format coded_fmt;
103	struct v4l2_format decoded_fmt;
104	const struct rkvdec_coded_fmt_desc *coded_fmt_desc;
105	struct v4l2_ctrl_handler ctrl_hdl;
106	struct rkvdec_dev *dev;
107	void *priv;
108};
109
110static inline struct rkvdec_ctx *fh_to_rkvdec_ctx(struct v4l2_fh *fh)
111{
112	return container_of(fh, struct rkvdec_ctx, fh);
113}
114
115struct rkvdec_aux_buf {
116	void *cpu;
117	dma_addr_t dma;
118	size_t size;
119};
120
121void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run);
122void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run);
123
124extern const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops;
125extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops;
126
127#endif /* RKVDEC_H_ */
128