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