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 
31 #define CEDRUS_QUIRK_NO_DMA_OFFSET	BIT(0)
32 
33 enum cedrus_codec {
34 	CEDRUS_CODEC_MPEG2,
35 	CEDRUS_CODEC_H264,
36 	CEDRUS_CODEC_LAST,
37 };
38 
39 enum cedrus_irq_status {
40 	CEDRUS_IRQ_NONE,
41 	CEDRUS_IRQ_ERROR,
42 	CEDRUS_IRQ_OK,
43 };
44 
45 enum cedrus_h264_pic_type {
46 	CEDRUS_H264_PIC_TYPE_FRAME	= 0,
47 	CEDRUS_H264_PIC_TYPE_FIELD,
48 	CEDRUS_H264_PIC_TYPE_MBAFF,
49 };
50 
51 struct cedrus_control {
52 	struct v4l2_ctrl_config cfg;
53 	enum cedrus_codec	codec;
54 	unsigned char		required:1;
55 };
56 
57 struct cedrus_h264_run {
58 	const struct v4l2_ctrl_h264_decode_params	*decode_params;
59 	const struct v4l2_ctrl_h264_pps			*pps;
60 	const struct v4l2_ctrl_h264_scaling_matrix	*scaling_matrix;
61 	const struct v4l2_ctrl_h264_slice_params	*slice_params;
62 	const struct v4l2_ctrl_h264_sps			*sps;
63 };
64 
65 struct cedrus_mpeg2_run {
66 	const struct v4l2_ctrl_mpeg2_slice_params	*slice_params;
67 	const struct v4l2_ctrl_mpeg2_quantization	*quantization;
68 };
69 
70 struct cedrus_run {
71 	struct vb2_v4l2_buffer	*src;
72 	struct vb2_v4l2_buffer	*dst;
73 
74 	union {
75 		struct cedrus_h264_run	h264;
76 		struct cedrus_mpeg2_run	mpeg2;
77 	};
78 };
79 
80 struct cedrus_buffer {
81 	struct v4l2_m2m_buffer          m2m_buf;
82 
83 	union {
84 		struct {
85 			unsigned int			position;
86 			enum cedrus_h264_pic_type	pic_type;
87 		} h264;
88 	} codec;
89 };
90 
91 struct cedrus_ctx {
92 	struct v4l2_fh			fh;
93 	struct cedrus_dev		*dev;
94 
95 	struct v4l2_pix_format		src_fmt;
96 	struct v4l2_pix_format		dst_fmt;
97 	enum cedrus_codec		current_codec;
98 
99 	struct v4l2_ctrl_handler	hdl;
100 	struct v4l2_ctrl		**ctrls;
101 
102 	union {
103 		struct {
104 			void		*mv_col_buf;
105 			dma_addr_t	mv_col_buf_dma;
106 			ssize_t		mv_col_buf_field_size;
107 			ssize_t		mv_col_buf_size;
108 			void		*pic_info_buf;
109 			dma_addr_t	pic_info_buf_dma;
110 			void		*neighbor_info_buf;
111 			dma_addr_t	neighbor_info_buf_dma;
112 		} h264;
113 	} codec;
114 };
115 
116 struct cedrus_dec_ops {
117 	void (*irq_clear)(struct cedrus_ctx *ctx);
118 	void (*irq_disable)(struct cedrus_ctx *ctx);
119 	enum cedrus_irq_status (*irq_status)(struct cedrus_ctx *ctx);
120 	void (*setup)(struct cedrus_ctx *ctx, struct cedrus_run *run);
121 	int (*start)(struct cedrus_ctx *ctx);
122 	void (*stop)(struct cedrus_ctx *ctx);
123 	void (*trigger)(struct cedrus_ctx *ctx);
124 };
125 
126 struct cedrus_variant {
127 	unsigned int	capabilities;
128 	unsigned int	quirks;
129 	unsigned int	mod_rate;
130 };
131 
132 struct cedrus_dev {
133 	struct v4l2_device	v4l2_dev;
134 	struct video_device	vfd;
135 	struct media_device	mdev;
136 	struct media_pad	pad[2];
137 	struct platform_device	*pdev;
138 	struct device		*dev;
139 	struct v4l2_m2m_dev	*m2m_dev;
140 	struct cedrus_dec_ops	*dec_ops[CEDRUS_CODEC_LAST];
141 
142 	/* Device file mutex */
143 	struct mutex		dev_mutex;
144 
145 	void __iomem		*base;
146 
147 	struct clk		*mod_clk;
148 	struct clk		*ahb_clk;
149 	struct clk		*ram_clk;
150 
151 	struct reset_control	*rstc;
152 
153 	unsigned int		capabilities;
154 };
155 
156 extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
157 extern struct cedrus_dec_ops cedrus_dec_ops_h264;
158 
159 static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
160 {
161 	writel(val, dev->base + reg);
162 }
163 
164 static inline u32 cedrus_read(struct cedrus_dev *dev, u32 reg)
165 {
166 	return readl(dev->base + reg);
167 }
168 
169 static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf,
170 					 struct v4l2_pix_format *pix_fmt,
171 					 unsigned int plane)
172 {
173 	dma_addr_t addr = vb2_dma_contig_plane_dma_addr(buf, 0);
174 
175 	return addr + (pix_fmt ? (dma_addr_t)pix_fmt->bytesperline *
176 	       pix_fmt->height * plane : 0);
177 }
178 
179 static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
180 					     int index, unsigned int plane)
181 {
182 	struct vb2_buffer *buf;
183 
184 	if (index < 0)
185 		return 0;
186 
187 	buf = ctx->fh.m2m_ctx->cap_q_ctx.q.bufs[index];
188 	return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
189 }
190 
191 static inline struct cedrus_buffer *
192 vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer *p)
193 {
194 	return container_of(p, struct cedrus_buffer, m2m_buf.vb);
195 }
196 
197 static inline struct cedrus_buffer *
198 vb2_to_cedrus_buffer(const struct vb2_buffer *p)
199 {
200 	return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
201 }
202 
203 void *cedrus_find_control_data(struct cedrus_ctx *ctx, u32 id);
204 
205 #endif
206