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