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