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