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/iopoll.h>
26  #include <linux/platform_device.h>
27  #include <linux/workqueue.h>
28  
29  #define CEDRUS_NAME			"cedrus"
30  
31  #define CEDRUS_CAPABILITY_UNTILED	BIT(0)
32  #define CEDRUS_CAPABILITY_H265_DEC	BIT(1)
33  #define CEDRUS_CAPABILITY_H264_DEC	BIT(2)
34  #define CEDRUS_CAPABILITY_MPEG2_DEC	BIT(3)
35  #define CEDRUS_CAPABILITY_VP8_DEC	BIT(4)
36  #define CEDRUS_CAPABILITY_H265_10_DEC	BIT(5)
37  
38  enum cedrus_irq_status {
39  	CEDRUS_IRQ_NONE,
40  	CEDRUS_IRQ_ERROR,
41  	CEDRUS_IRQ_OK,
42  };
43  
44  enum cedrus_h264_pic_type {
45  	CEDRUS_H264_PIC_TYPE_FRAME	= 0,
46  	CEDRUS_H264_PIC_TYPE_FIELD,
47  	CEDRUS_H264_PIC_TYPE_MBAFF,
48  };
49  
50  struct cedrus_control {
51  	struct v4l2_ctrl_config cfg;
52  	unsigned int		capabilities;
53  };
54  
55  struct cedrus_h264_run {
56  	const struct v4l2_ctrl_h264_decode_params	*decode_params;
57  	const struct v4l2_ctrl_h264_pps			*pps;
58  	const struct v4l2_ctrl_h264_scaling_matrix	*scaling_matrix;
59  	const struct v4l2_ctrl_h264_slice_params	*slice_params;
60  	const struct v4l2_ctrl_h264_sps			*sps;
61  	const struct v4l2_ctrl_h264_pred_weights	*pred_weights;
62  };
63  
64  struct cedrus_mpeg2_run {
65  	const struct v4l2_ctrl_mpeg2_sequence		*sequence;
66  	const struct v4l2_ctrl_mpeg2_picture		*picture;
67  	const struct v4l2_ctrl_mpeg2_quantisation	*quantisation;
68  };
69  
70  struct cedrus_h265_run {
71  	const struct v4l2_ctrl_hevc_sps			*sps;
72  	const struct v4l2_ctrl_hevc_pps			*pps;
73  	const struct v4l2_ctrl_hevc_slice_params	*slice_params;
74  	const struct v4l2_ctrl_hevc_decode_params	*decode_params;
75  	const struct v4l2_ctrl_hevc_scaling_matrix	*scaling_matrix;
76  	const u32					*entry_points;
77  	u32						entry_points_count;
78  };
79  
80  struct cedrus_vp8_run {
81  	const struct v4l2_ctrl_vp8_frame		*frame_params;
82  };
83  
84  struct cedrus_run {
85  	struct vb2_v4l2_buffer	*src;
86  	struct vb2_v4l2_buffer	*dst;
87  
88  	union {
89  		struct cedrus_h264_run	h264;
90  		struct cedrus_mpeg2_run	mpeg2;
91  		struct cedrus_h265_run	h265;
92  		struct cedrus_vp8_run	vp8;
93  	};
94  };
95  
96  struct cedrus_buffer {
97  	struct v4l2_m2m_buffer          m2m_buf;
98  
99  	union {
100  		struct {
101  			unsigned int			position;
102  			enum cedrus_h264_pic_type	pic_type;
103  			void				*mv_col_buf;
104  			dma_addr_t			mv_col_buf_dma;
105  			ssize_t				mv_col_buf_size;
106  		} h264;
107  		struct {
108  			void		*mv_col_buf;
109  			dma_addr_t	mv_col_buf_dma;
110  			ssize_t		mv_col_buf_size;
111  		} h265;
112  	} codec;
113  };
114  
115  struct cedrus_ctx {
116  	struct v4l2_fh			fh;
117  	struct cedrus_dev		*dev;
118  
119  	struct v4l2_pix_format		src_fmt;
120  	struct v4l2_pix_format		dst_fmt;
121  	struct cedrus_dec_ops		*current_codec;
122  	unsigned int			bit_depth;
123  
124  	struct v4l2_ctrl_handler	hdl;
125  	struct v4l2_ctrl		**ctrls;
126  
127  	union {
128  		struct {
129  			void		*pic_info_buf;
130  			dma_addr_t	pic_info_buf_dma;
131  			ssize_t		pic_info_buf_size;
132  			void		*neighbor_info_buf;
133  			dma_addr_t	neighbor_info_buf_dma;
134  			void		*deblk_buf;
135  			dma_addr_t	deblk_buf_dma;
136  			ssize_t		deblk_buf_size;
137  			void		*intra_pred_buf;
138  			dma_addr_t	intra_pred_buf_dma;
139  			ssize_t		intra_pred_buf_size;
140  		} h264;
141  		struct {
142  			void		*neighbor_info_buf;
143  			dma_addr_t	neighbor_info_buf_addr;
144  			void		*entry_points_buf;
145  			dma_addr_t	entry_points_buf_addr;
146  		} h265;
147  		struct {
148  			unsigned int	last_frame_p_type;
149  			unsigned int	last_filter_type;
150  			unsigned int	last_sharpness_level;
151  
152  			u8		*entropy_probs_buf;
153  			dma_addr_t	entropy_probs_buf_dma;
154  		} vp8;
155  	} codec;
156  };
157  
158  struct cedrus_dec_ops {
159  	void (*irq_clear)(struct cedrus_ctx *ctx);
160  	void (*irq_disable)(struct cedrus_ctx *ctx);
161  	enum cedrus_irq_status (*irq_status)(struct cedrus_ctx *ctx);
162  	int (*setup)(struct cedrus_ctx *ctx, struct cedrus_run *run);
163  	int (*start)(struct cedrus_ctx *ctx);
164  	void (*stop)(struct cedrus_ctx *ctx);
165  	void (*trigger)(struct cedrus_ctx *ctx);
166  	unsigned int (*extra_cap_size)(struct cedrus_ctx *ctx,
167  				       struct v4l2_pix_format *pix_fmt);
168  };
169  
170  struct cedrus_variant {
171  	unsigned int	capabilities;
172  	unsigned int	mod_rate;
173  };
174  
175  struct cedrus_dev {
176  	struct v4l2_device	v4l2_dev;
177  	struct video_device	vfd;
178  	struct media_device	mdev;
179  	struct media_pad	pad[2];
180  	struct platform_device	*pdev;
181  	struct device		*dev;
182  	struct v4l2_m2m_dev	*m2m_dev;
183  
184  	/* Device file mutex */
185  	struct mutex		dev_mutex;
186  
187  	void __iomem		*base;
188  
189  	struct clk		*mod_clk;
190  	struct clk		*ahb_clk;
191  	struct clk		*ram_clk;
192  
193  	struct reset_control	*rstc;
194  
195  	unsigned int		capabilities;
196  
197  	struct delayed_work	watchdog_work;
198  };
199  
200  extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
201  extern struct cedrus_dec_ops cedrus_dec_ops_h264;
202  extern struct cedrus_dec_ops cedrus_dec_ops_h265;
203  extern struct cedrus_dec_ops cedrus_dec_ops_vp8;
204  
cedrus_write(struct cedrus_dev * dev,u32 reg,u32 val)205  static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
206  {
207  	writel(val, dev->base + reg);
208  }
209  
cedrus_read(struct cedrus_dev * dev,u32 reg)210  static inline u32 cedrus_read(struct cedrus_dev *dev, u32 reg)
211  {
212  	return readl(dev->base + reg);
213  }
214  
cedrus_wait_for(struct cedrus_dev * dev,u32 reg,u32 flag)215  static inline u32 cedrus_wait_for(struct cedrus_dev *dev, u32 reg, u32 flag)
216  {
217  	u32 value;
218  
219  	return readl_poll_timeout_atomic(dev->base + reg, value,
220  			(value & flag) == 0, 10, 1000);
221  }
222  
cedrus_buf_addr(struct vb2_buffer * buf,struct v4l2_pix_format * pix_fmt,unsigned int plane)223  static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf,
224  					 struct v4l2_pix_format *pix_fmt,
225  					 unsigned int plane)
226  {
227  	dma_addr_t addr = vb2_dma_contig_plane_dma_addr(buf, 0);
228  
229  	return addr + (pix_fmt ? (dma_addr_t)pix_fmt->bytesperline *
230  	       pix_fmt->height * plane : 0);
231  }
232  
cedrus_dst_buf_addr(struct cedrus_ctx * ctx,struct vb2_buffer * buf,unsigned int plane)233  static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
234  					     struct vb2_buffer *buf,
235  					     unsigned int plane)
236  {
237  	return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
238  }
239  
cedrus_write_ref_buf_addr(struct cedrus_ctx * ctx,struct vb2_queue * q,u64 timestamp,u32 luma_reg,u32 chroma_reg)240  static inline void cedrus_write_ref_buf_addr(struct cedrus_ctx *ctx,
241  					     struct vb2_queue *q,
242  					     u64 timestamp,
243  					     u32 luma_reg,
244  					     u32 chroma_reg)
245  {
246  	struct cedrus_dev *dev = ctx->dev;
247  	struct vb2_buffer *buf = vb2_find_buffer(q, timestamp);
248  
249  	cedrus_write(dev, luma_reg, cedrus_dst_buf_addr(ctx, buf, 0));
250  	cedrus_write(dev, chroma_reg, cedrus_dst_buf_addr(ctx, buf, 1));
251  }
252  
253  static inline struct cedrus_buffer *
vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer * p)254  vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer *p)
255  {
256  	return container_of(p, struct cedrus_buffer, m2m_buf.vb);
257  }
258  
259  static inline struct cedrus_buffer *
vb2_to_cedrus_buffer(const struct vb2_buffer * p)260  vb2_to_cedrus_buffer(const struct vb2_buffer *p)
261  {
262  	return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
263  }
264  
265  static inline bool
cedrus_is_capable(struct cedrus_ctx * ctx,unsigned int capabilities)266  cedrus_is_capable(struct cedrus_ctx *ctx, unsigned int capabilities)
267  {
268  	return (ctx->dev->capabilities & capabilities) == capabilities;
269  }
270  
271  void *cedrus_find_control_data(struct cedrus_ctx *ctx, u32 id);
272  u32 cedrus_get_num_of_controls(struct cedrus_ctx *ctx, u32 id);
273  
274  #endif
275