FILE
wave5-vpu-enc.c
File preview with syntax highlighting.
linux-6.19.14/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2/* 3 * Wave5 series multi-standard codec IP - encoder interface 4 * 5 * Copyright (C) 2021-2023 CHIPS&MEDIA INC 6 */ 7 8#include <linux/pm_runtime.h> 9#include "wave5-helper.h" 10 11#define VPU_ENC_DEV_NAME "C&M Wave5 VPU encoder" 12#define VPU_ENC_DRV_NAME "wave5-enc" 13 14static const struct v4l2_frmsize_stepwise enc_frmsize[FMT_TYPES] = { 15 [VPU_FMT_TYPE_CODEC] = { 16 .min_width = W5_MIN_ENC_PIC_WIDTH, 17 .max_width = W5_MAX_ENC_PIC_WIDTH, 18 .step_width = W5_ENC_CODEC_STEP_WIDTH, 19 .min_height = W5_MIN_ENC_PIC_HEIGHT, 20 .max_height = W5_MAX_ENC_PIC_HEIGHT, 21 .step_height = W5_ENC_CODEC_STEP_HEIGHT, 22 }, 23 [VPU_FMT_TYPE_RAW] = { 24 .min_width = W5_MIN_ENC_PIC_WIDTH, 25 .max_width = W5_MAX_ENC_PIC_WIDTH, 26 .step_width = W5_ENC_RAW_STEP_WIDTH, 27 .min_height = W5_MIN_ENC_PIC_HEIGHT, 28 .max_height = W5_MAX_ENC_PIC_HEIGHT, 29 .step_height = W5_ENC_RAW_STEP_HEIGHT, 30 }, 31}; 32 33static const struct vpu_format enc_fmt_list[FMT_TYPES][MAX_FMTS] = { 34 [VPU_FMT_TYPE_CODEC] = { 35 { 36 .v4l2_pix_fmt = V4L2_PIX_FMT_HEVC, 37 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_CODEC], 38 }, 39 { 40 .v4l2_pix_fmt = V4L2_PIX_FMT_H264, 41 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_CODEC], 42 }, 43 }, 44 [VPU_FMT_TYPE_RAW] = { 45 { 46 .v4l2_pix_fmt = V4L2_PIX_FMT_YUV420, 47 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 48 }, 49 { 50 .v4l2_pix_fmt = V4L2_PIX_FMT_NV12, 51 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 52 }, 53 { 54 .v4l2_pix_fmt = V4L2_PIX_FMT_NV21, 55 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 56 }, 57 { 58 .v4l2_pix_fmt = V4L2_PIX_FMT_YUV420M, 59 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 60 }, 61 { 62 .v4l2_pix_fmt = V4L2_PIX_FMT_NV12M, 63 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 64 }, 65 { 66 .v4l2_pix_fmt = V4L2_PIX_FMT_NV21M, 67 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 68 }, 69 { 70 .v4l2_pix_fmt = V4L2_PIX_FMT_YUV422P, 71 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 72 }, 73 { 74 .v4l2_pix_fmt = V4L2_PIX_FMT_NV16, 75 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 76 }, 77 { 78 .v4l2_pix_fmt = V4L2_PIX_FMT_NV61, 79 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 80 }, 81 { 82 .v4l2_pix_fmt = V4L2_PIX_FMT_YUV422M, 83 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 84 }, 85 { 86 .v4l2_pix_fmt = V4L2_PIX_FMT_NV16M, 87 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 88 }, 89 { 90 .v4l2_pix_fmt = V4L2_PIX_FMT_NV61M, 91 .v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW], 92 }, 93 } 94}; 95 96static int switch_state(struct vpu_instance *inst, enum vpu_instance_state state) 97{ 98 switch (state) { 99 case VPU_INST_STATE_NONE: 100 goto invalid_state_switch; 101 case VPU_INST_STATE_OPEN: 102 if (inst->state != VPU_INST_STATE_NONE) 103 goto invalid_state_switch; 104 break; 105 case VPU_INST_STATE_INIT_SEQ: 106 if (inst->state != VPU_INST_STATE_OPEN && inst->state != VPU_INST_STATE_STOP) 107 goto invalid_state_switch; 108 break; 109 case VPU_INST_STATE_PIC_RUN: 110 if (inst->state != VPU_INST_STATE_INIT_SEQ) 111 goto invalid_state_switch; 112 break; 113 case VPU_INST_STATE_STOP: 114 break; 115 } 116 117 dev_dbg(inst->dev->dev, "Switch state from %s to %s.\n", 118 state_to_str(inst->state), state_to_str(state)); 119 inst->state = state; 120 return 0; 121 122invalid_state_switch: 123 WARN(1, "Invalid state switch from %s to %s.\n", 124 state_to_str(inst->state), state_to_str(state)); 125 return -EINVAL; 126} 127 128static int start_encode(struct vpu_instance *inst, u32 *fail_res) 129{ 130 struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx; 131 int ret; 132 struct vb2_v4l2_buffer *src_buf; 133 struct vb2_v4l2_buffer *dst_buf; 134 struct frame_buffer frame_buf; 135 struct enc_param pic_param; 136 const struct v4l2_format_info *info; 137 u32 stride = inst->src_fmt.plane_fmt[0].bytesperline; 138 u32 luma_size = 0; 139 u32 chroma_size = 0; 140 141 memset(&pic_param, 0, sizeof(struct enc_param)); 142 memset(&frame_buf, 0, sizeof(struct frame_buffer)); 143 144 info = v4l2_format_info(inst->src_fmt.pixelformat); 145 if (!info) 146 return -EINVAL; 147 148 if (info->mem_planes == 1) { 149 luma_size = stride * inst->dst_fmt.height; 150 chroma_size = luma_size / (info->hdiv * info->vdiv); 151 } else { 152 luma_size = inst->src_fmt.plane_fmt[0].sizeimage; 153 chroma_size = inst->src_fmt.plane_fmt[1].sizeimage; 154 } 155 156 dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx); 157 if (!dst_buf) { 158 dev_dbg(inst->dev->dev, "%s: No destination buffer found\n", __func__); 159 return -EAGAIN; 160 } 161 162 pic_param.pic_stream_buffer_addr = 163 vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); 164 pic_param.pic_stream_buffer_size = 165 vb2_plane_size(&dst_buf->vb2_buf, 0); 166 167 src_buf = v4l2_m2m_next_src_buf(m2m_ctx); 168 if (!src_buf) { 169 dev_dbg(inst->dev->dev, "%s: No source buffer found\n", __func__); 170 if (m2m_ctx->is_draining) 171 pic_param.src_end_flag = 1; 172 else 173 return -EAGAIN; 174 } else { 175 if (inst->src_fmt.num_planes == 1) { 176 frame_buf.buf_y = 177 vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); 178 frame_buf.buf_cb = frame_buf.buf_y + luma_size; 179 frame_buf.buf_cr = frame_buf.buf_cb + chroma_size; 180 } else if (inst->src_fmt.num_planes == 2) { 181 frame_buf.buf_y = 182 vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); 183 frame_buf.buf_cb = 184 vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 1); 185 frame_buf.buf_cr = frame_buf.buf_cb + chroma_size; 186 } else if (inst->src_fmt.num_planes == 3) { 187 frame_buf.buf_y = 188 vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); 189 frame_buf.buf_cb = 190 vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 1); 191 frame_buf.buf_cr = 192 vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 2); 193 } 194 frame_buf.stride = stride; 195 pic_param.src_idx = src_buf->vb2_buf.index; 196 } 197 198 pic_param.source_frame = &frame_buf; 199 pic_param.code_option.implicit_header_encode = 1; 200 pic_param.code_option.encode_aud = inst->encode_aud; 201 ret = wave5_vpu_enc_start_one_frame(inst, &pic_param, fail_res); 202 if (ret) { 203 if (*fail_res == WAVE5_SYSERR_QUEUEING_FAIL) 204 return -EINVAL; 205 206 dev_dbg(inst->dev->dev, "%s: wave5_vpu_enc_start_one_frame fail: %d\n", 207 __func__, ret); 208 src_buf = v4l2_m2m_src_buf_remove(m2m_ctx); 209 if (!src_buf) { 210 dev_dbg(inst->dev->dev, 211 "%s: Removing src buf failed, the queue is empty\n", 212 __func__); 213 return -EINVAL; 214 } 215 dst_buf = v4l2_m2m_dst_buf_remove(m2m_ctx); 216 if (!dst_buf) { 217 dev_dbg(inst->dev->dev, 218 "%s: Removing dst buf failed, the queue is empty\n", 219 __func__); 220 return -EINVAL; 221 } 222 switch_state(inst, VPU_INST_STATE_STOP); 223 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; 224 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); 225 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); 226 } else { 227 dev_dbg(inst->dev->dev, "%s: wave5_vpu_enc_start_one_frame success\n", 228 __func__); 229 /* 230 * Remove the source buffer from the ready-queue now and finish 231 * it in the videobuf2 framework once the index is returned by the 232 * firmware in finish_encode 233 */ 234 if (src_buf) 235 v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, src_buf->vb2_buf.index); 236 } 237 238 return 0; 239} 240 241static void wave5_vpu_enc_finish_encode(struct vpu_instance *inst) 242{ 243 struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx; 244 int ret; 245 struct enc_output_info enc_output_info; 246 struct vb2_v4l2_buffer *src_buf = NULL; 247 struct vb2_v4l2_buffer *dst_buf = NULL; 248 249 ret = wave5_vpu_enc_get_output_info(inst, &enc_output_info); 250 if (ret) { 251 dev_dbg(inst->dev->dev, 252 "%s: vpu_enc_get_output_info fail: %d reason: %u | info: %u\n", 253 __func__, ret, enc_output_info.error_reason, enc_output_info.warn_info); 254 return; 255 } 256 257 dev_dbg(inst->dev->dev, 258 "%s: pic_type %i recon_idx %i src_idx %i pic_byte %u pts %llu\n", 259 __func__, enc_output_info.pic_type, enc_output_info.recon_frame_index, 260 enc_output_info.enc_src_idx, enc_output_info.enc_pic_byte, enc_output_info.pts); 261 262 /* 263 * The source buffer will not be found in the ready-queue as it has been 264 * dropped after sending of the encode firmware command, locate it in 265 * the videobuf2 queue directly 266 */ 267 if (enc_output_info.enc_src_idx >= 0) { 268 struct vb2_buffer *vb = vb2_get_buffer(v4l2_m2m_get_src_vq(m2m_ctx), 269 enc_output_info.enc_src_idx); 270 if (vb->state != VB2_BUF_STATE_ACTIVE) 271 dev_warn(inst->dev->dev, 272 "%s: encoded buffer (%d) was not in ready queue %i.", 273 __func__, enc_output_info.enc_src_idx, vb->state); 274 else 275 src_buf = to_vb2_v4l2_buffer(vb); 276 277 if (src_buf) { 278 inst->timestamp = src_buf->vb2_buf.timestamp; 279 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); 280 } else { 281 dev_warn(inst->dev->dev, "%s: no source buffer with index: %d found\n", 282 __func__, enc_output_info.enc_src_idx); 283 } 284 } 285 286 dst_buf = v4l2_m2m_dst_buf_remove(m2m_ctx); 287 if (enc_output_info.recon_frame_index == RECON_IDX_FLAG_ENC_END) { 288 static const struct v4l2_event vpu_event_eos = { 289 .type = V4L2_EVENT_EOS 290 }; 291 292 if (!WARN_ON(!dst_buf)) { 293 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0); 294 dst_buf->field = V4L2_FIELD_NONE; 295 v4l2_m2m_last_buffer_done(m2m_ctx, dst_buf); 296 } 297 298 v4l2_event_queue_fh(&inst->v4l2_fh, &vpu_event_eos); 299 300 v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx); 301 } else { 302 if (!dst_buf) { 303 dev_warn(inst->dev->dev, "No bitstream buffer."); 304 v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx); 305 return; 306 } 307 308 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_output_info.bitstream_size); 309 310 dst_buf->vb2_buf.timestamp = inst->timestamp; 311 dst_buf->field = V4L2_FIELD_NONE; 312 if (enc_output_info.pic_type == PIC_TYPE_I) { 313 if (enc_output_info.enc_vcl_nut == 19 || 314 enc_output_info.enc_vcl_nut == 20) 315 dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME; 316 else 317 dst_buf->flags |= V4L2_BUF_FLAG_PFRAME; 318 } else if (enc_output_info.pic_type == PIC_TYPE_P) { 319 dst_buf->flags |= V4L2_BUF_FLAG_PFRAME; 320 } else if (enc_output_info.pic_type == PIC_TYPE_B) { 321 dst_buf->flags |= V4L2_BUF_FLAG_BFRAME; 322 } 323 324 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); 325 326 dev_dbg(inst->dev->dev, "%s: frame_cycle %8u\n", 327 __func__, enc_output_info.frame_cycle); 328 329 v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx); 330 } 331} 332 333static int wave5_vpu_enc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 334{ 335 strscpy(cap->driver, VPU_ENC_DRV_NAME, sizeof(cap->driver)); 336 strscpy(cap->card, VPU_ENC_DRV_NAME, sizeof(cap->card)); 337 338 return 0; 339} 340 341static int wave5_vpu_enc_enum_framesizes(struct file *f, void *fh, struct v4l2_frmsizeenum *fsize) 342{ 343 const struct vpu_format *vpu_fmt; 344 345 if (fsize->index) 346 return -EINVAL; 347 348 vpu_fmt = wave5_find_vpu_fmt(fsize->pixel_format, enc_fmt_list[VPU_FMT_TYPE_CODEC]); 349 if (!vpu_fmt) { 350 vpu_fmt = wave5_find_vpu_fmt(fsize->pixel_format, enc_fmt_list[VPU_FMT_TYPE_RAW]); 351 if (!vpu_fmt) 352 return -EINVAL; 353 } 354 355 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 356 fsize->stepwise = enc_frmsize[VPU_FMT_TYPE_CODEC]; 357 358 return 0; 359} 360 361static int wave5_vpu_enc_enum_fmt_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) 362{ 363 struct vpu_instance *inst = file_to_vpu_inst(file); 364 const struct vpu_format *vpu_fmt; 365 366 dev_dbg(inst->dev->dev, "%s: index: %u\n", __func__, f->index); 367 368 vpu_fmt = wave5_find_vpu_fmt_by_idx(f->index, enc_fmt_list[VPU_FMT_TYPE_CODEC]); 369 if (!vpu_fmt) 370 return -EINVAL; 371 372 f->pixelformat = vpu_fmt->v4l2_pix_fmt; 373 f->flags = 0; 374 375 return 0; 376} 377 378static int wave5_vpu_enc_try_fmt_cap(struct file *file, void *fh, struct v4l2_format *f) 379{ 380 struct vpu_instance *inst = file_to_vpu_inst(file); 381 const struct v4l2_frmsize_stepwise *frmsize; 382 const struct vpu_format *vpu_fmt; 383 int width, height; 384 385 dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n", 386 __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height, 387 f->fmt.pix_mp.num_planes, f->fmt.pix_mp.field); 388 389 vpu_fmt = wave5_find_vpu_fmt(f->fmt.pix_mp.pixelformat, enc_fmt_list[VPU_FMT_TYPE_CODEC]); 390 if (!vpu_fmt) { 391 width = inst->dst_fmt.width; 392 height = inst->dst_fmt.height; 393 f->fmt.pix_mp.pixelformat = inst->dst_fmt.pixelformat; 394 frmsize = &enc_frmsize[VPU_FMT_TYPE_CODEC]; 395 } else { 396 width = f->fmt.pix_mp.width; 397 height = f->fmt.pix_mp.height; 398 f->fmt.pix_mp.pixelformat = vpu_fmt->v4l2_pix_fmt; 399 frmsize = vpu_fmt->v4l2_frmsize; 400 } 401 402 wave5_update_pix_fmt(&f->fmt.pix_mp, VPU_FMT_TYPE_CODEC, 403 width, height, frmsize); 404 f->fmt.pix_mp.colorspace = inst->colorspace; 405 f->fmt.pix_mp.ycbcr_enc = inst->ycbcr_enc; 406 f->fmt.pix_mp.quantization = inst->quantization; 407 f->fmt.pix_mp.xfer_func = inst->xfer_func; 408 409 return 0; 410} 411 412static int wave5_vpu_enc_s_fmt_cap(struct file *file, void *fh, struct v4l2_format *f) 413{ 414 struct vpu_instance *inst = file_to_vpu_inst(file); 415 int i, ret; 416 417 dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n", 418 __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height, 419 f->fmt.pix_mp.num_planes, f->fmt.pix_mp.field); 420 421 ret = wave5_vpu_enc_try_fmt_cap(file, fh, f); 422 if (ret) 423 return ret; 424 425 inst->std = wave5_to_vpu_std(f->fmt.pix_mp.pixelformat, inst->type); 426 if (inst->std == STD_UNKNOWN) { 427 dev_warn(inst->dev->dev, "unsupported pixelformat: %.4s\n", 428 (char *)&f->fmt.pix_mp.pixelformat); 429 return -EINVAL; 430 } 431 432 inst->dst_fmt.width = f->fmt.pix_mp.width; 433 inst->dst_fmt.height = f->fmt.pix_mp.height; 434 inst->dst_fmt.pixelformat = f->fmt.pix_mp.pixelformat; 435 inst->dst_fmt.field = f->fmt.pix_mp.field; 436 inst->dst_fmt.flags = f->fmt.pix_mp.flags; 437 inst->dst_fmt.num_planes = f->fmt.pix_mp.num_planes; 438 for (i = 0; i < inst->dst_fmt.num_planes; i++) { 439 inst->dst_fmt.plane_fmt[i].bytesperline = f->fmt.pix_mp.plane_fmt[i].bytesperline; 440 inst->dst_fmt.plane_fmt[i].sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage; 441 } 442 443 return 0; 444} 445 446static int wave5_vpu_enc_g_fmt_cap(struct file *file, void *fh, struct v4l2_format *f) 447{ 448 struct vpu_instance *inst = file_to_vpu_inst(file); 449 int i; 450 451 f->fmt.pix_mp.width = inst->dst_fmt.width; 452 f->fmt.pix_mp.height = inst->dst_fmt.height; 453 f->fmt.pix_mp.pixelformat = inst->dst_fmt.pixelformat; 454 f->fmt.pix_mp.field = inst->dst_fmt.field; 455 f->fmt.pix_mp.flags = inst->dst_fmt.flags; 456 f->fmt.pix_mp.num_planes = inst->dst_fmt.num_planes; 457 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { 458 f->fmt.pix_mp.plane_fmt[i].bytesperline = inst->dst_fmt.plane_fmt[i].bytesperline; 459 f->fmt.pix_mp.plane_fmt[i].sizeimage = inst->dst_fmt.plane_fmt[i].sizeimage; 460 } 461 462 f->fmt.pix_mp.colorspace = inst->colorspace; 463 f->fmt.pix_mp.ycbcr_enc = inst->ycbcr_enc; 464 f->fmt.pix_mp.quantization = inst->quantization; 465 f->fmt.pix_mp.xfer_func = inst->xfer_func; 466 467 return 0; 468} 469 470static int wave5_vpu_enc_enum_fmt_out(struct file *file, void *fh, struct v4l2_fmtdesc *f) 471{ 472 struct vpu_instance *inst = file_to_vpu_inst(file); 473 const struct vpu_format *vpu_fmt; 474 475 dev_dbg(inst->dev->dev, "%s: index: %u\n", __func__, f->index); 476 477 vpu_fmt = wave5_find_vpu_fmt_by_idx(f->index, enc_fmt_list[VPU_FMT_TYPE_RAW]); 478 if (!vpu_fmt) 479 return -EINVAL; 480 481 f->pixelformat = vpu_fmt->v4l2_pix_fmt; 482 f->flags = 0; 483 484 return 0; 485} 486 487static int wave5_vpu_enc_try_fmt_out(struct file *file, void *fh, struct v4l2_format *f) 488{ 489 struct vpu_instance *inst = file_to_vpu_inst(file); 490 const struct v4l2_frmsize_stepwise *frmsize; 491 const struct vpu_format *vpu_fmt; 492 int width, height; 493 494 dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n", 495 __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height, 496 f->fmt.pix_mp.num_planes, f->fmt.pix_mp.field); 497 498 vpu_fmt = wave5_find_vpu_fmt(f->fmt.pix_mp.pixelformat, enc_fmt_list[VPU_FMT_TYPE_RAW]); 499 if (!vpu_fmt) { 500 width = inst->src_fmt.width; 501 height = inst->src_fmt.height; 502 f->fmt.pix_mp.pixelformat = inst->src_fmt.pixelformat; 503 frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW]; 504 } else { 505 width = f->fmt.pix_mp.width; 506 height = f->fmt.pix_mp.height; 507 f->fmt.pix_mp.pixelformat = vpu_fmt->v4l2_pix_fmt; 508 frmsize = vpu_fmt->v4l2_frmsize; 509 } 510 511 wave5_update_pix_fmt(&f->fmt.pix_mp, VPU_FMT_TYPE_RAW, 512 width, height, frmsize); 513 return 0; 514} 515 516static int wave5_vpu_enc_s_fmt_out(struct file *file, void *fh, struct v4l2_format *f) 517{ 518 struct vpu_instance *inst = file_to_vpu_inst(file); 519 const struct vpu_format *vpu_fmt; 520 const struct v4l2_format_info *info; 521 int i, ret; 522 523 dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n", 524 __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height, 525 f->fmt.pix_mp.num_planes, f->fmt.pix_mp.field); 526 527 ret = wave5_vpu_enc_try_fmt_out(file, fh, f); 528 if (ret) 529 return ret; 530 531 inst->src_fmt.width = f->fmt.pix_mp.width; 532 inst->src_fmt.height = f->fmt.pix_mp.height; 533 inst->src_fmt.pixelformat = f->fmt.pix_mp.pixelformat; 534 inst->src_fmt.field = f->fmt.pix_mp.field; 535 inst->src_fmt.flags = f->fmt.pix_mp.flags; 536 inst->src_fmt.num_planes = f->fmt.pix_mp.num_planes; 537 for (i = 0; i < inst->src_fmt.num_planes; i++) { 538 inst->src_fmt.plane_fmt[i].bytesperline = f->fmt.pix_mp.plane_fmt[i].bytesperline; 539 inst->src_fmt.plane_fmt[i].sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage; 540 } 541 542 info = v4l2_format_info(inst->src_fmt.pixelformat); 543 if (!info) 544 return -EINVAL; 545 546 inst->cbcr_interleave = info->comp_planes == 2; 547 548 switch (inst->src_fmt.pixelformat) { 549 case V4L2_PIX_FMT_NV21: 550 case V4L2_PIX_FMT_NV21M: 551 case V4L2_PIX_FMT_NV61: 552 case V4L2_PIX_FMT_NV61M: 553 inst->nv21 = true; 554 break; 555 default: 556 inst->nv21 = false; 557 } 558 559 inst->colorspace = f->fmt.pix_mp.colorspace; 560 inst->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 561 inst->quantization = f->fmt.pix_mp.quantization; 562 inst->xfer_func = f->fmt.pix_mp.xfer_func; 563 564 vpu_fmt = wave5_find_vpu_fmt(inst->dst_fmt.pixelformat, enc_fmt_list[VPU_FMT_TYPE_CODEC]); 565 if (!vpu_fmt) 566 return -EINVAL; 567 568 wave5_update_pix_fmt(&inst->dst_fmt, VPU_FMT_TYPE_CODEC, 569 f->fmt.pix_mp.width, f->fmt.pix_mp.height, 570 vpu_fmt->v4l2_frmsize); 571 inst->conf_win.width = inst->dst_fmt.width; 572 inst->conf_win.height = inst->dst_fmt.height; 573 574 return 0; 575} 576 577static int wave5_vpu_enc_g_selection(struct file *file, void *fh, struct v4l2_selection *s) 578{ 579 struct vpu_instance *inst = file_to_vpu_inst(file); 580 581 dev_dbg(inst->dev->dev, "%s: type: %u | target: %u\n", __func__, s->type, s->target); 582 583 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 584 return -EINVAL; 585 switch (s->target) { 586 case V4L2_SEL_TGT_CROP_DEFAULT: 587 case V4L2_SEL_TGT_CROP_BOUNDS: 588 s->r.left = 0; 589 s->r.top = 0; 590 s->r.width = inst->dst_fmt.width; 591 s->r.height = inst->dst_fmt.height; 592 break; 593 case V4L2_SEL_TGT_CROP: 594 s->r.left = 0; 595 s->r.top = 0; 596 s->r.width = inst->conf_win.width; 597 s->r.height = inst->conf_win.height; 598 break; 599 default: 600 return -EINVAL; 601 } 602 603 return 0; 604} 605 606static int wave5_vpu_enc_s_selection(struct file *file, void *fh, struct v4l2_selection *s) 607{ 608 struct vpu_instance *inst = file_to_vpu_inst(file); 609 610 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 611 return -EINVAL; 612 613 if (s->target != V4L2_SEL_TGT_CROP) 614 return -EINVAL; 615 616 dev_dbg(inst->dev->dev, "%s: V4L2_SEL_TGT_CROP width: %u | height: %u\n", 617 __func__, s->r.width, s->r.height); 618 619 s->r.left = 0; 620 s->r.top = 0; 621 s->r.width = min(s->r.width, inst->dst_fmt.width); 622 s->r.height = min(s->r.height, inst->dst_fmt.height); 623 624 inst->conf_win = s->r; 625 626 return 0; 627} 628 629static int wave5_vpu_enc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *ec) 630{ 631 struct vpu_instance *inst = file_to_vpu_inst(file); 632 struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx; 633 int ret; 634 635 ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, ec); 636 if (ret) 637 return ret; 638 639 if (!wave5_vpu_both_queues_are_streaming(inst)) 640 return 0; 641 642 switch (ec->cmd) { 643 case V4L2_ENC_CMD_STOP: 644 if (m2m_ctx->is_draining) 645 return -EBUSY; 646 647 if (m2m_ctx->has_stopped) 648 return 0; 649 650 m2m_ctx->last_src_buf = v4l2_m2m_last_src_buf(m2m_ctx); 651 m2m_ctx->is_draining = true; 652 653 v4l2_m2m_try_schedule(m2m_ctx); 654 break; 655 case V4L2_ENC_CMD_START: 656 break; 657 default: 658 return -EINVAL; 659 } 660 661 return 0; 662} 663 664static int wave5_vpu_enc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 665{ 666 struct vpu_instance *inst = file_to_vpu_inst(file); 667 668 dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, a->type); 669 670 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 671 return -EINVAL; 672 673 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 674 a->parm.output.timeperframe.numerator = 1; 675 a->parm.output.timeperframe.denominator = inst->frame_rate; 676 677 dev_dbg(inst->dev->dev, "%s: numerator: %u | denominator: %u\n", 678 __func__, a->parm.output.timeperframe.numerator, 679 a->parm.output.timeperframe.denominator); 680 681 return 0; 682} 683 684static int wave5_vpu_enc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 685{ 686 struct vpu_instance *inst = file_to_vpu_inst(file); 687 688 dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, a->type); 689 690 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 691 return -EINVAL; 692 693 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 694 if (a->parm.output.timeperframe.denominator && a->parm.output.timeperframe.numerator) { 695 inst->frame_rate = a->parm.output.timeperframe.denominator / 696 a->parm.output.timeperframe.numerator; 697 } else { 698 a->parm.output.timeperframe.numerator = 1; 699 a->parm.output.timeperframe.denominator = inst->frame_rate; 700 } 701 702 dev_dbg(inst->dev->dev, "%s: numerator: %u | denominator: %u\n", 703 __func__, a->parm.output.timeperframe.numerator, 704 a->parm.output.timeperframe.denominator); 705 706 return 0; 707} 708 709static const struct v4l2_ioctl_ops wave5_vpu_enc_ioctl_ops = { 710 .vidioc_querycap = wave5_vpu_enc_querycap, 711 .vidioc_enum_framesizes = wave5_vpu_enc_enum_framesizes, 712 713 .vidioc_enum_fmt_vid_cap = wave5_vpu_enc_enum_fmt_cap, 714 .vidioc_s_fmt_vid_cap_mplane = wave5_vpu_enc_s_fmt_cap, 715 .vidioc_g_fmt_vid_cap_mplane = wave5_vpu_enc_g_fmt_cap, 716 .vidioc_try_fmt_vid_cap_mplane = wave5_vpu_enc_try_fmt_cap, 717 718 .vidioc_enum_fmt_vid_out = wave5_vpu_enc_enum_fmt_out, 719 .vidioc_s_fmt_vid_out_mplane = wave5_vpu_enc_s_fmt_out, 720 .vidioc_g_fmt_vid_out_mplane = wave5_vpu_g_fmt_out, 721 .vidioc_try_fmt_vid_out_mplane = wave5_vpu_enc_try_fmt_out, 722 723 .vidioc_g_selection = wave5_vpu_enc_g_selection, 724 .vidioc_s_selection = wave5_vpu_enc_s_selection, 725 726 .vidioc_g_parm = wave5_vpu_enc_g_parm, 727 .vidioc_s_parm = wave5_vpu_enc_s_parm, 728 729 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 730 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 731 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 732 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 733 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 734 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 735 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 736 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 737 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 738 739 .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, 740 .vidioc_encoder_cmd = wave5_vpu_enc_encoder_cmd, 741 742 .vidioc_subscribe_event = wave5_vpu_subscribe_event, 743 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 744}; 745 746static int wave5_vpu_enc_s_ctrl(struct v4l2_ctrl *ctrl) 747{ 748 struct vpu_instance *inst = wave5_ctrl_to_vpu_inst(ctrl); 749 750 dev_dbg(inst->dev->dev, "%s: name: %s | value: %d\n", __func__, ctrl->name, ctrl->val); 751 752 switch (ctrl->id) { 753 case V4L2_CID_MPEG_VIDEO_AU_DELIMITER: 754 inst->encode_aud = ctrl->val; 755 break; 756 case V4L2_CID_HFLIP: 757 inst->mirror_direction |= (ctrl->val << 1); 758 break; 759 case V4L2_CID_VFLIP: 760 inst->mirror_direction |= ctrl->val; 761 break; 762 case V4L2_CID_ROTATE: 763 inst->rot_angle = ctrl->val; 764 break; 765 case V4L2_CID_MPEG_VIDEO_VBV_SIZE: 766 inst->vbv_buf_size = ctrl->val; 767 break; 768 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: 769 switch (ctrl->val) { 770 case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR: 771 inst->rc_mode = 0; 772 break; 773 case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR: 774 inst->rc_mode = 1; 775 break; 776 default: 777 return -EINVAL; 778 } 779 break; 780 case V4L2_CID_MPEG_VIDEO_BITRATE: 781 inst->bit_rate = ctrl->val; 782 break; 783 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 784 inst->enc_param.avc_idr_period = ctrl->val; 785 break; 786 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: 787 inst->enc_param.independ_slice_mode = ctrl->val; 788 inst->enc_param.avc_slice_mode = ctrl->val; 789 break; 790 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: 791 inst->enc_param.independ_slice_mode_arg = ctrl->val; 792 inst->enc_param.avc_slice_arg = ctrl->val; 793 break; 794 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: 795 inst->rc_enable = ctrl->val; 796 break; 797 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: 798 inst->enc_param.mb_level_rc_enable = ctrl->val; 799 inst->enc_param.cu_level_rc_enable = ctrl->val; 800 inst->enc_param.hvs_qp_enable = ctrl->val; 801 break; 802 case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: 803 switch (ctrl->val) { 804 case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN: 805 inst->enc_param.profile = HEVC_PROFILE_MAIN; 806 inst->bit_depth = 8; 807 break; 808 case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE: 809 inst->enc_param.profile = HEVC_PROFILE_STILLPICTURE; 810 inst->enc_param.en_still_picture = 1; 811 inst->bit_depth = 8; 812 break; 813 case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10: 814 inst->enc_param.profile = HEVC_PROFILE_MAIN10; 815 inst->bit_depth = 10; 816 break; 817 default: 818 return -EINVAL; 819 } 820 break; 821 case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: 822 switch (ctrl->val) { 823 case V4L2_MPEG_VIDEO_HEVC_LEVEL_1: 824 inst->enc_param.level = 10 * 3; 825 break; 826 case V4L2_MPEG_VIDEO_HEVC_LEVEL_2: 827 inst->enc_param.level = 20 * 3; 828 break; 829 case V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1: 830 inst->enc_param.level = 21 * 3; 831 break; 832 case V4L2_MPEG_VIDEO_HEVC_LEVEL_3: 833 inst->enc_param.level = 30 * 3; 834 break; 835 case V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1: 836 inst->enc_param.level = 31 * 3; 837 break; 838 case V4L2_MPEG_VIDEO_HEVC_LEVEL_4: 839 inst->enc_param.level = 40 * 3; 840 break; 841 case V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1: 842 inst->enc_param.level = 41 * 3; 843 break; 844 case V4L2_MPEG_VIDEO_HEVC_LEVEL_5: 845 inst->enc_param.level = 50 * 3; 846 break; 847 case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1: 848 inst->enc_param.level = 51 * 3; 849 break; 850 case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2: 851 inst->enc_param.level = 52 * 3; 852 break; 853 default: 854 return -EINVAL; 855 } 856 break; 857 case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: 858 inst->enc_param.min_qp_i = ctrl->val; 859 inst->enc_param.min_qp_p = ctrl->val; 860 inst->enc_param.min_qp_b = ctrl->val; 861 break; 862 case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: 863 inst->enc_param.max_qp_i = ctrl->val; 864 inst->enc_param.max_qp_p = ctrl->val; 865 inst->enc_param.max_qp_b = ctrl->val; 866 break; 867 case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: 868 inst->enc_param.intra_qp = ctrl->val; 869 break; 870 case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: 871 switch (ctrl->val) { 872 case V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED: 873 inst->enc_param.disable_deblk = 1; 874 inst->enc_param.sao_enable = 0; 875 inst->enc_param.lf_cross_slice_boundary_enable = 0; 876 break; 877 case V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_ENABLED: 878 inst->enc_param.disable_deblk = 0; 879 inst->enc_param.sao_enable = 1; 880 inst->enc_param.lf_cross_slice_boundary_enable = 1; 881 break; 882 case V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY: 883 inst->enc_param.disable_deblk = 0; 884 inst->enc_param.sao_enable = 1; 885 inst->enc_param.lf_cross_slice_boundary_enable = 0; 886 break; 887 default: 888 return -EINVAL; 889 } 890 break; 891 case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2: 892 inst->enc_param.beta_offset_div2 = ctrl->val; 893 break; 894 case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2: 895 inst->enc_param.tc_offset_div2 = ctrl->val; 896 break; 897 case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: 898 switch (ctrl->val) { 899 case V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE: 900 inst->enc_param.decoding_refresh_type = 0; 901 break; 902 case V4L2_MPEG_VIDEO_HEVC_REFRESH_CRA: 903 inst->enc_param.decoding_refresh_type = 1; 904 break; 905 case V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR: 906 inst->enc_param.decoding_refresh_type = 2; 907 break; 908 default: 909 return -EINVAL; 910 } 911 break; 912 case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD: 913 inst->enc_param.intra_period = ctrl->val; 914 break; 915 case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU: 916 inst->enc_param.lossless_enable = ctrl->val; 917 break; 918 case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: 919 inst->enc_param.const_intra_pred_flag = ctrl->val; 920 break; 921 case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT: 922 inst->enc_param.wpp_enable = ctrl->val; 923 break; 924 case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING: 925 inst->enc_param.strong_intra_smooth_enable = ctrl->val; 926 break; 927 case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1: 928 inst->enc_param.max_num_merge = ctrl->val; 929 break; 930 case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION: 931 inst->enc_param.tmvp_enable = ctrl->val; 932 break; 933 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: 934 switch (ctrl->val) { 935 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 936 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: 937 inst->enc_param.profile = H264_PROFILE_BP; 938 inst->bit_depth = 8; 939 break; 940 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 941 inst->enc_param.profile = H264_PROFILE_MP; 942 inst->bit_depth = 8; 943 break; 944 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 945 inst->enc_param.profile = H264_PROFILE_EXTENDED; 946 inst->bit_depth = 8; 947 break; 948 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 949 inst->enc_param.profile = H264_PROFILE_HP; 950 inst->bit_depth = 8; 951 break; 952 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: 953 inst->enc_param.profile = H264_PROFILE_HIGH10; 954 inst->bit_depth = 10; 955 break; 956 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: 957 inst->enc_param.profile = H264_PROFILE_HIGH422; 958 inst->bit_depth = 10; 959 break; 960 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: 961 inst->enc_param.profile = H264_PROFILE_HIGH444; 962 inst->bit_depth = 10; 963 break; 964 default: 965 return -EINVAL; 966 } 967 break; 968 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: 969 switch (ctrl->val) { 970 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: 971 inst->enc_param.level = 10; 972 break; 973 case V4L2_MPEG_VIDEO_H264_LEVEL_1B: 974 inst->enc_param.level = 9; 975 break; 976 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: 977 inst->enc_param.level = 11; 978 break; 979 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: 980 inst->enc_param.level = 12; 981 break; 982 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: 983 inst->enc_param.level = 13; 984 break; 985 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: 986 inst->enc_param.level = 20; 987 break; 988 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: 989 inst->enc_param.level = 21; 990 break; 991 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: 992 inst->enc_param.level = 22; 993 break; 994 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: 995 inst->enc_param.level = 30; 996 break; 997 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: 998 inst->enc_param.level = 31; 999 break; 1000 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: 1001 inst->enc_param.level = 32; 1002 break; 1003 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: 1004 inst->enc_param.level = 40; 1005 break; 1006 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: 1007 inst->enc_param.level = 41; 1008 break; 1009 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: 1010 inst->enc_param.level = 42; 1011 break; 1012 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: 1013 inst->enc_param.level = 50; 1014 break; 1015 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: 1016 inst->enc_param.level = 51; 1017 break; 1018 default: 1019 return -EINVAL; 1020 } 1021 break; 1022 case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: 1023 inst->enc_param.min_qp_i = ctrl->val; 1024 inst->enc_param.min_qp_p = ctrl->val; 1025 inst->enc_param.min_qp_b = ctrl->val; 1026 break; 1027 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: 1028 inst->enc_param.max_qp_i = ctrl->val; 1029 inst->enc_param.max_qp_p = ctrl->val; 1030 inst->enc_param.max_qp_b = ctrl->val; 1031 break; 1032 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: 1033 inst->enc_param.intra_qp = ctrl->val; 1034 break; 1035 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: 1036 switch (ctrl->val) { 1037 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED: 1038 inst->enc_param.disable_deblk = 1; 1039 inst->enc_param.lf_cross_slice_boundary_enable = 1; 1040 break; 1041 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED: 1042 inst->enc_param.disable_deblk = 0; 1043 inst->enc_param.lf_cross_slice_boundary_enable = 1; 1044 break; 1045 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY: 1046 inst->enc_param.disable_deblk = 0; 1047 inst->enc_param.lf_cross_slice_boundary_enable = 0; 1048 break; 1049 default: 1050 return -EINVAL; 1051 } 1052 break; 1053 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: 1054 inst->enc_param.beta_offset_div2 = ctrl->val; 1055 break; 1056 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: 1057 inst->enc_param.tc_offset_div2 = ctrl->val; 1058 break; 1059 case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: 1060 inst->enc_param.transform8x8_enable = ctrl->val; 1061 break; 1062 case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION: 1063 inst->enc_param.const_intra_pred_flag = ctrl->val; 1064 break; 1065 case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: 1066 inst->enc_param.chroma_cb_qp_offset = ctrl->val; 1067 inst->enc_param.chroma_cr_qp_offset = ctrl->val; 1068 break; 1069 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: 1070 inst->enc_param.intra_period = ctrl->val; 1071 break; 1072 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: 1073 inst->enc_param.entropy_coding_mode = ctrl->val; 1074 break; 1075 case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: 1076 inst->enc_param.forced_idr_header_enable = ctrl->val; 1077 break; 1078 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: 1079 break; 1080 default: 1081 return -EINVAL; 1082 } 1083 1084 return 0; 1085} 1086 1087static const struct v4l2_ctrl_ops wave5_vpu_enc_ctrl_ops = { 1088 .s_ctrl = wave5_vpu_enc_s_ctrl, 1089}; 1090 1091static int wave5_vpu_enc_queue_setup(struct vb2_queue *q, unsigned int *num_buffers, 1092 unsigned int *num_planes, unsigned int sizes[], 1093 struct device *alloc_devs[]) 1094{ 1095 struct vpu_instance *inst = vb2_get_drv_priv(q); 1096 struct v4l2_pix_format_mplane inst_format = 1097 (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? inst->src_fmt : inst->dst_fmt; 1098 unsigned int i; 1099 1100 dev_dbg(inst->dev->dev, "%s: num_buffers: %u | num_planes: %u | type: %u\n", __func__, 1101 *num_buffers, *num_planes, q->type); 1102 1103 if (*num_planes) { 1104 if (inst_format.num_planes != *num_planes) 1105 return -EINVAL; 1106 1107 for (i = 0; i < *num_planes; i++) { 1108 if (sizes[i] < inst_format.plane_fmt[i].sizeimage) 1109 return -EINVAL; 1110 } 1111 } else { 1112 *num_planes = inst_format.num_planes; 1113 for (i = 0; i < *num_planes; i++) { 1114 sizes[i] = inst_format.plane_fmt[i].sizeimage; 1115 dev_dbg(inst->dev->dev, "%s: size[%u]: %u\n", __func__, i, sizes[i]); 1116 } 1117 } 1118 1119 dev_dbg(inst->dev->dev, "%s: size: %u\n", __func__, sizes[0]); 1120 1121 return 0; 1122} 1123 1124static void wave5_vpu_enc_buf_queue(struct vb2_buffer *vb) 1125{ 1126 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1127 struct vpu_instance *inst = vb2_get_drv_priv(vb->vb2_queue); 1128 struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx; 1129 1130 dev_dbg(inst->dev->dev, "%s: type: %4u index: %4u size: ([0]=%4lu, [1]=%4lu, [2]=%4lu)\n", 1131 __func__, vb->type, vb->index, vb2_plane_size(&vbuf->vb2_buf, 0), 1132 vb2_plane_size(&vbuf->vb2_buf, 1), vb2_plane_size(&vbuf->vb2_buf, 2)); 1133 1134 if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1135 vbuf->sequence = inst->queued_src_buf_num++; 1136 else 1137 vbuf->sequence = inst->queued_dst_buf_num++; 1138 1139 v4l2_m2m_buf_queue(m2m_ctx, vbuf); 1140} 1141 1142static int wave5_set_enc_openparam(struct enc_open_param *open_param, 1143 struct vpu_instance *inst) 1144{ 1145 struct enc_wave_param input = inst->enc_param; 1146 const struct v4l2_format_info *info; 1147 u32 num_ctu_row = ALIGN(inst->dst_fmt.height, 64) / 64; 1148 u32 num_mb_row = ALIGN(inst->dst_fmt.height, 16) / 16; 1149 1150 info = v4l2_format_info(inst->src_fmt.pixelformat); 1151 if (!info) 1152 return -EINVAL; 1153 1154 if (info->hdiv == 2 && info->vdiv == 1) 1155 open_param->src_format = FORMAT_422; 1156 else 1157 open_param->src_format = FORMAT_420; 1158 1159 open_param->wave_param.gop_preset_idx = PRESET_IDX_IPP_SINGLE; 1160 open_param->wave_param.hvs_qp_scale = 2; 1161 open_param->wave_param.hvs_max_delta_qp = 10; 1162 open_param->wave_param.skip_intra_trans = 1; 1163 open_param->wave_param.intra_nx_n_enable = 1; 1164 open_param->wave_param.nr_intra_weight_y = 7; 1165 open_param->wave_param.nr_intra_weight_cb = 7; 1166 open_param->wave_param.nr_intra_weight_cr = 7; 1167 open_param->wave_param.nr_inter_weight_y = 4; 1168 open_param->wave_param.nr_inter_weight_cb = 4; 1169 open_param->wave_param.nr_inter_weight_cr = 4; 1170 open_param->wave_param.rdo_skip = 1; 1171 open_param->wave_param.lambda_scaling_enable = 1; 1172 1173 open_param->line_buf_int_en = true; 1174 open_param->pic_width = inst->conf_win.width; 1175 open_param->pic_height = inst->conf_win.height; 1176 open_param->frame_rate_info = inst->frame_rate; 1177 open_param->rc_enable = inst->rc_enable; 1178 if (inst->rc_enable) { 1179 open_param->wave_param.initial_rc_qp = -1; 1180 open_param->wave_param.rc_weight_param = 16; 1181 open_param->wave_param.rc_weight_buf = 128; 1182 } 1183 open_param->wave_param.mb_level_rc_enable = input.mb_level_rc_enable; 1184 open_param->wave_param.cu_level_rc_enable = input.cu_level_rc_enable; 1185 open_param->wave_param.hvs_qp_enable = input.hvs_qp_enable; 1186 open_param->bit_rate = inst->bit_rate; 1187 open_param->vbv_buffer_size = inst->vbv_buf_size; 1188 if (inst->rc_mode == 0) 1189 open_param->vbv_buffer_size = 3000; 1190 open_param->wave_param.profile = input.profile; 1191 open_param->wave_param.en_still_picture = input.en_still_picture; 1192 open_param->wave_param.level = input.level; 1193 open_param->wave_param.internal_bit_depth = inst->bit_depth; 1194 open_param->wave_param.intra_qp = input.intra_qp; 1195 open_param->wave_param.min_qp_i = input.min_qp_i; 1196 open_param->wave_param.max_qp_i = input.max_qp_i; 1197 open_param->wave_param.min_qp_p = input.min_qp_p; 1198 open_param->wave_param.max_qp_p = input.max_qp_p; 1199 open_param->wave_param.min_qp_b = input.min_qp_b; 1200 open_param->wave_param.max_qp_b = input.max_qp_b; 1201 open_param->wave_param.disable_deblk = input.disable_deblk; 1202 open_param->wave_param.lf_cross_slice_boundary_enable = 1203 input.lf_cross_slice_boundary_enable; 1204 open_param->wave_param.tc_offset_div2 = input.tc_offset_div2; 1205 open_param->wave_param.beta_offset_div2 = input.beta_offset_div2; 1206 open_param->wave_param.decoding_refresh_type = input.decoding_refresh_type; 1207 open_param->wave_param.intra_period = input.intra_period; 1208 if (inst->std == W_HEVC_ENC) { 1209 if (input.intra_period == 0) { 1210 open_param->wave_param.decoding_refresh_type = DEC_REFRESH_TYPE_IDR; 1211 open_param->wave_param.intra_period = input.avc_idr_period; 1212 } 1213 } else { 1214 open_param->wave_param.avc_idr_period = input.avc_idr_period; 1215 } 1216 open_param->wave_param.entropy_coding_mode = input.entropy_coding_mode; 1217 open_param->wave_param.lossless_enable = input.lossless_enable; 1218 open_param->wave_param.const_intra_pred_flag = input.const_intra_pred_flag; 1219 open_param->wave_param.wpp_enable = input.wpp_enable; 1220 open_param->wave_param.strong_intra_smooth_enable = input.strong_intra_smooth_enable; 1221 open_param->wave_param.max_num_merge = input.max_num_merge; 1222 open_param->wave_param.tmvp_enable = input.tmvp_enable; 1223 open_param->wave_param.transform8x8_enable = input.transform8x8_enable; 1224 open_param->wave_param.chroma_cb_qp_offset = input.chroma_cb_qp_offset; 1225 open_param->wave_param.chroma_cr_qp_offset = input.chroma_cr_qp_offset; 1226 open_param->wave_param.independ_slice_mode = input.independ_slice_mode; 1227 open_param->wave_param.independ_slice_mode_arg = input.independ_slice_mode_arg; 1228 open_param->wave_param.avc_slice_mode = input.avc_slice_mode; 1229 open_param->wave_param.avc_slice_arg = input.avc_slice_arg; 1230 open_param->wave_param.intra_mb_refresh_mode = input.intra_mb_refresh_mode; 1231 if (input.intra_mb_refresh_mode != REFRESH_MB_MODE_NONE) { 1232 if (num_mb_row >= input.intra_mb_refresh_arg) 1233 open_param->wave_param.intra_mb_refresh_arg = 1234 num_mb_row / input.intra_mb_refresh_arg; 1235 else 1236 open_param->wave_param.intra_mb_refresh_arg = num_mb_row; 1237 } 1238 open_param->wave_param.intra_refresh_mode = input.intra_refresh_mode; 1239 if (input.intra_refresh_mode != 0) { 1240 if (num_ctu_row >= input.intra_refresh_arg) 1241 open_param->wave_param.intra_refresh_arg = 1242 num_ctu_row / input.intra_refresh_arg; 1243 else 1244 open_param->wave_param.intra_refresh_arg = num_ctu_row; 1245 } 1246 open_param->wave_param.forced_idr_header_enable = input.forced_idr_header_enable; 1247 1248 return 0; 1249} 1250 1251static int initialize_sequence(struct vpu_instance *inst) 1252{ 1253 struct enc_initial_info initial_info; 1254 struct v4l2_ctrl *ctrl; 1255 int ret; 1256 1257 ret = wave5_vpu_enc_issue_seq_init(inst); 1258 if (ret) { 1259 dev_err(inst->dev->dev, "%s: wave5_vpu_enc_issue_seq_init, fail: %d\n", 1260 __func__, ret); 1261 return ret; 1262 } 1263 1264 if (wave5_vpu_wait_interrupt(inst, VPU_ENC_TIMEOUT) < 0) { 1265 dev_err(inst->dev->dev, "%s: wave5_vpu_wait_interrupt failed\n", __func__); 1266 return -EINVAL; 1267 } 1268 1269 ret = wave5_vpu_enc_complete_seq_init(inst, &initial_info); 1270 if (ret) 1271 return ret; 1272 1273 dev_dbg(inst->dev->dev, "%s: min_frame_buffer: %u | min_source_buffer: %u\n", 1274 __func__, initial_info.min_frame_buffer_count, 1275 initial_info.min_src_frame_count); 1276 inst->min_src_buf_count = initial_info.min_src_frame_count + 1277 WAVE521_COMMAND_QUEUE_DEPTH; 1278 1279 ctrl = v4l2_ctrl_find(&inst->v4l2_ctrl_hdl, 1280 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT); 1281 if (ctrl) 1282 v4l2_ctrl_s_ctrl(ctrl, inst->min_src_buf_count); 1283 1284 inst->fbc_buf_count = initial_info.min_frame_buffer_count; 1285 1286 return 0; 1287} 1288 1289static int prepare_fb(struct vpu_instance *inst) 1290{ 1291 u32 fb_stride = ALIGN(inst->dst_fmt.width, 32); 1292 u32 fb_height = ALIGN(inst->dst_fmt.height, 32); 1293 int i, ret = 0; 1294 1295 for (i = 0; i < inst->fbc_buf_count; i++) { 1296 u32 luma_size = fb_stride * fb_height; 1297 u32 chroma_size = ALIGN(fb_stride / 2, 16) * fb_height; 1298 1299 inst->frame_vbuf[i].size = luma_size + chroma_size; 1300 ret = wave5_vdi_allocate_dma_memory(inst->dev, &inst->frame_vbuf[i]); 1301 if (ret < 0) { 1302 dev_err(inst->dev->dev, "%s: failed to allocate FBC buffer %zu\n", 1303 __func__, inst->frame_vbuf[i].size); 1304 goto free_buffers; 1305 } 1306 1307 inst->frame_buf[i].buf_y = inst->frame_vbuf[i].daddr; 1308 inst->frame_buf[i].buf_cb = (dma_addr_t)-1; 1309 inst->frame_buf[i].buf_cr = (dma_addr_t)-1; 1310 inst->frame_buf[i].update_fb_info = true; 1311 inst->frame_buf[i].size = inst->frame_vbuf[i].size; 1312 } 1313 1314 ret = wave5_vpu_enc_register_frame_buffer(inst, inst->fbc_buf_count, fb_stride, 1315 fb_height, COMPRESSED_FRAME_MAP); 1316 if (ret) { 1317 dev_err(inst->dev->dev, 1318 "%s: wave5_vpu_enc_register_frame_buffer, fail: %d\n", 1319 __func__, ret); 1320 goto free_buffers; 1321 } 1322 1323 return 0; 1324free_buffers: 1325 for (i = 0; i < inst->fbc_buf_count; i++) 1326 wave5_vpu_dec_reset_framebuffer(inst, i); 1327 return ret; 1328} 1329 1330static int wave5_vpu_enc_start_streaming(struct vb2_queue *q, unsigned int count) 1331{ 1332 struct vpu_instance *inst = vb2_get_drv_priv(q); 1333 struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx; 1334 int ret = 0; 1335 1336 pm_runtime_resume_and_get(inst->dev->dev); 1337 v4l2_m2m_update_start_streaming_state(m2m_ctx, q); 1338 1339 if (inst->state == VPU_INST_STATE_NONE && q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 1340 struct enc_open_param open_param; 1341 1342 memset(&open_param, 0, sizeof(struct enc_open_param)); 1343 1344 ret = wave5_set_enc_openparam(&open_param, inst); 1345 if (ret) { 1346 dev_dbg(inst->dev->dev, "%s: wave5_set_enc_openparam, fail: %d\n", 1347 __func__, ret); 1348 goto return_buffers; 1349 } 1350 1351 ret = wave5_vpu_enc_open(inst, &open_param); 1352 if (ret) { 1353 dev_dbg(inst->dev->dev, "%s: wave5_vpu_enc_open, fail: %d\n", 1354 __func__, ret); 1355 goto return_buffers; 1356 } 1357 1358 if (inst->mirror_direction) { 1359 wave5_vpu_enc_give_command(inst, ENABLE_MIRRORING, NULL); 1360 wave5_vpu_enc_give_command(inst, SET_MIRROR_DIRECTION, 1361 &inst->mirror_direction); 1362 } 1363 if (inst->rot_angle) { 1364 wave5_vpu_enc_give_command(inst, ENABLE_ROTATION, NULL); 1365 wave5_vpu_enc_give_command(inst, SET_ROTATION_ANGLE, &inst->rot_angle); 1366 } 1367 1368 ret = switch_state(inst, VPU_INST_STATE_OPEN); 1369 if (ret) 1370 goto return_buffers; 1371 } 1372 if (inst->state == VPU_INST_STATE_OPEN && 1373 (m2m_ctx->cap_q_ctx.q.streaming || q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) { 1374 ret = initialize_sequence(inst); 1375 if (ret) { 1376 dev_warn(inst->dev->dev, "Sequence not found: %d\n", ret); 1377 goto return_buffers; 1378 } 1379 ret = switch_state(inst, VPU_INST_STATE_INIT_SEQ); 1380 if (ret) 1381 goto return_buffers; 1382 /* 1383 * The sequence must be analyzed first to calculate the proper 1384 * size of the auxiliary buffers. 1385 */ 1386 ret = prepare_fb(inst); 1387 if (ret) { 1388 dev_warn(inst->dev->dev, "Framebuffer preparation, fail: %d\n", ret); 1389 goto return_buffers; 1390 } 1391 1392 ret = switch_state(inst, VPU_INST_STATE_PIC_RUN); 1393 } 1394 if (ret) 1395 goto return_buffers; 1396 1397 pm_runtime_put_autosuspend(inst->dev->dev); 1398 return 0; 1399return_buffers: 1400 wave5_return_bufs(q, VB2_BUF_STATE_QUEUED); 1401 pm_runtime_put_autosuspend(inst->dev->dev); 1402 return ret; 1403} 1404 1405static void streamoff_output(struct vpu_instance *inst, struct vb2_queue *q) 1406{ 1407 struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx; 1408 struct vb2_v4l2_buffer *buf; 1409 1410 while ((buf = v4l2_m2m_src_buf_remove(m2m_ctx))) { 1411 dev_dbg(inst->dev->dev, "%s: buf type %4u | index %4u\n", 1412 __func__, buf->vb2_buf.type, buf->vb2_buf.index); 1413 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); 1414 } 1415} 1416 1417static void streamoff_capture(struct vpu_instance *inst, struct vb2_queue *q) 1418{ 1419 struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx; 1420 struct vb2_v4l2_buffer *buf; 1421 1422 while ((buf = v4l2_m2m_dst_buf_remove(m2m_ctx))) { 1423 dev_dbg(inst->dev->dev, "%s: buf type %4u | index %4u\n", 1424 __func__, buf->vb2_buf.type, buf->vb2_buf.index); 1425 vb2_set_plane_payload(&buf->vb2_buf, 0, 0); 1426 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); 1427 } 1428 1429 v4l2_m2m_clear_state(m2m_ctx); 1430} 1431 1432static void wave5_vpu_enc_stop_streaming(struct vb2_queue *q) 1433{ 1434 struct vpu_instance *inst = vb2_get_drv_priv(q); 1435 bool check_cmd = true; 1436 1437 /* 1438 * Note that we don't need m2m_ctx->next_buf_last for this driver, so we 1439 * don't call v4l2_m2m_update_stop_streaming_state(). 1440 */ 1441 1442 dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type); 1443 pm_runtime_resume_and_get(inst->dev->dev); 1444 1445 if (wave5_vpu_both_queues_are_streaming(inst)) 1446 switch_state(inst, VPU_INST_STATE_STOP); 1447 1448 while (check_cmd) { 1449 struct queue_status_info q_status; 1450 struct enc_output_info enc_output_info; 1451 1452 wave5_vpu_enc_give_command(inst, ENC_GET_QUEUE_STATUS, &q_status); 1453 1454 if (q_status.report_queue_count == 0) 1455 break; 1456 1457 if (wave5_vpu_wait_interrupt(inst, VPU_ENC_TIMEOUT) < 0) 1458 break; 1459 1460 if (wave5_vpu_enc_get_output_info(inst, &enc_output_info)) 1461 dev_dbg(inst->dev->dev, "Getting encoding results from fw, fail\n"); 1462 } 1463 1464 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1465 streamoff_output(inst, q); 1466 else 1467 streamoff_capture(inst, q); 1468 1469 pm_runtime_put_autosuspend(inst->dev->dev); 1470} 1471 1472static const struct vb2_ops wave5_vpu_enc_vb2_ops = { 1473 .queue_setup = wave5_vpu_enc_queue_setup, 1474 .buf_queue = wave5_vpu_enc_buf_queue, 1475 .start_streaming = wave5_vpu_enc_start_streaming, 1476 .stop_streaming = wave5_vpu_enc_stop_streaming, 1477}; 1478 1479static void wave5_set_default_format(struct v4l2_pix_format_mplane *src_fmt, 1480 struct v4l2_pix_format_mplane *dst_fmt) 1481{ 1482 src_fmt->pixelformat = enc_fmt_list[VPU_FMT_TYPE_RAW][0].v4l2_pix_fmt; 1483 wave5_update_pix_fmt(src_fmt, VPU_FMT_TYPE_RAW, 1484 W5_DEF_ENC_PIC_WIDTH, W5_DEF_ENC_PIC_HEIGHT, 1485 &enc_frmsize[VPU_FMT_TYPE_RAW]); 1486 1487 dst_fmt->pixelformat = enc_fmt_list[VPU_FMT_TYPE_CODEC][0].v4l2_pix_fmt; 1488 wave5_update_pix_fmt(dst_fmt, VPU_FMT_TYPE_CODEC, 1489 W5_DEF_ENC_PIC_WIDTH, W5_DEF_ENC_PIC_HEIGHT, 1490 &enc_frmsize[VPU_FMT_TYPE_CODEC]); 1491} 1492 1493static int wave5_vpu_enc_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) 1494{ 1495 return wave5_vpu_queue_init(priv, src_vq, dst_vq, &wave5_vpu_enc_vb2_ops); 1496} 1497 1498static const struct vpu_instance_ops wave5_vpu_enc_inst_ops = { 1499 .finish_process = wave5_vpu_enc_finish_encode, 1500}; 1501 1502static void wave5_vpu_enc_device_run(void *priv) 1503{ 1504 struct vpu_instance *inst = priv; 1505 struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx; 1506 u32 fail_res = 0; 1507 int ret = 0; 1508 1509 pm_runtime_resume_and_get(inst->dev->dev); 1510 switch (inst->state) { 1511 case VPU_INST_STATE_PIC_RUN: 1512 ret = start_encode(inst, &fail_res); 1513 if (ret) { 1514 if (ret == -EINVAL) 1515 dev_err(inst->dev->dev, 1516 "Frame encoding on m2m context (%p), fail: %d (res: %d)\n", 1517 m2m_ctx, ret, fail_res); 1518 else if (ret == -EAGAIN) 1519 dev_dbg(inst->dev->dev, "Missing buffers for encode, try again\n"); 1520 break; 1521 } 1522 dev_dbg(inst->dev->dev, "%s: leave with active job", __func__); 1523 pm_runtime_put_autosuspend(inst->dev->dev); 1524 return; 1525 default: 1526 WARN(1, "Execution of a job in state %s is invalid.\n", 1527 state_to_str(inst->state)); 1528 break; 1529 } 1530 dev_dbg(inst->dev->dev, "%s: leave and finish job", __func__); 1531 pm_runtime_put_autosuspend(inst->dev->dev); 1532 v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx); 1533} 1534 1535static int wave5_vpu_enc_job_ready(void *priv) 1536{ 1537 struct vpu_instance *inst = priv; 1538 struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx; 1539 1540 switch (inst->state) { 1541 case VPU_INST_STATE_NONE: 1542 dev_dbg(inst->dev->dev, "Encoder must be open to start queueing M2M jobs!\n"); 1543 return false; 1544 case VPU_INST_STATE_PIC_RUN: 1545 if (m2m_ctx->is_draining || v4l2_m2m_num_src_bufs_ready(m2m_ctx)) { 1546 dev_dbg(inst->dev->dev, "Encoder ready for a job, state: %s\n", 1547 state_to_str(inst->state)); 1548 return true; 1549 } 1550 fallthrough; 1551 default: 1552 dev_dbg(inst->dev->dev, 1553 "Encoder not ready for a job, state: %s, %s draining, %d src bufs ready\n", 1554 state_to_str(inst->state), m2m_ctx->is_draining ? "is" : "is not", 1555 v4l2_m2m_num_src_bufs_ready(m2m_ctx)); 1556 break; 1557 } 1558 return false; 1559} 1560 1561static const struct v4l2_m2m_ops wave5_vpu_enc_m2m_ops = { 1562 .device_run = wave5_vpu_enc_device_run, 1563 .job_ready = wave5_vpu_enc_job_ready, 1564}; 1565 1566static int wave5_vpu_open_enc(struct file *filp) 1567{ 1568 struct video_device *vdev = video_devdata(filp); 1569 struct vpu_device *dev = video_drvdata(filp); 1570 struct vpu_instance *inst = NULL; 1571 struct v4l2_ctrl_handler *v4l2_ctrl_hdl; 1572 int ret = 0; 1573 1574 inst = kzalloc(sizeof(*inst), GFP_KERNEL); 1575 if (!inst) 1576 return -ENOMEM; 1577 v4l2_ctrl_hdl = &inst->v4l2_ctrl_hdl; 1578 1579 inst->dev = dev; 1580 inst->type = VPU_INST_TYPE_ENC; 1581 inst->ops = &wave5_vpu_enc_inst_ops; 1582 1583 inst->codec_info = kzalloc(sizeof(*inst->codec_info), GFP_KERNEL); 1584 if (!inst->codec_info) { 1585 kfree(inst); 1586 return -ENOMEM; 1587 } 1588 1589 v4l2_fh_init(&inst->v4l2_fh, vdev); 1590 v4l2_fh_add(&inst->v4l2_fh, filp); 1591 1592 INIT_LIST_HEAD(&inst->list); 1593 1594 inst->v4l2_m2m_dev = inst->dev->v4l2_m2m_enc_dev; 1595 inst->v4l2_fh.m2m_ctx = 1596 v4l2_m2m_ctx_init(inst->v4l2_m2m_dev, inst, wave5_vpu_enc_queue_init); 1597 if (IS_ERR(inst->v4l2_fh.m2m_ctx)) { 1598 ret = PTR_ERR(inst->v4l2_fh.m2m_ctx); 1599 goto cleanup_inst; 1600 } 1601 v4l2_m2m_set_src_buffered(inst->v4l2_fh.m2m_ctx, true); 1602 1603 v4l2_ctrl_handler_init(v4l2_ctrl_hdl, 50); 1604 v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1605 V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, 1606 V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10, 0, 1607 V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN); 1608 v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1609 V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, 1610 V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 0, 1611 V4L2_MPEG_VIDEO_HEVC_LEVEL_1); 1612 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1613 V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, 1614 0, 63, 1, 8); 1615 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1616 V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP, 1617 0, 63, 1, 51); 1618 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1619 V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP, 1620 0, 63, 1, 30); 1621 v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1622 V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE, 1623 V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY, 0, 1624 V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_ENABLED); 1625 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1626 V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2, 1627 -6, 6, 1, 0); 1628 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1629 V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2, 1630 -6, 6, 1, 0); 1631 v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1632 V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE, 1633 V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR, 0, 1634 V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR); 1635 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1636 V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD, 1637 0, 2047, 1, 0); 1638 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1639 V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU, 1640 0, 1, 1, 0); 1641 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1642 V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED, 1643 0, 1, 1, 0); 1644 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1645 V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT, 1646 0, 1, 1, 0); 1647 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1648 V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING, 1649 0, 1, 1, 1); 1650 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1651 V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1, 1652 1, 2, 1, 2); 1653 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1654 V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION, 1655 0, 1, 1, 1); 1656 1657 v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1658 V4L2_CID_MPEG_VIDEO_H264_PROFILE, 1659 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE, 0, 1660 V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE); 1661 v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1662 V4L2_CID_MPEG_VIDEO_H264_LEVEL, 1663 V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 0, 1664 V4L2_MPEG_VIDEO_H264_LEVEL_1_0); 1665 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1666 V4L2_CID_MPEG_VIDEO_H264_MIN_QP, 1667 0, 63, 1, 8); 1668 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1669 V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 1670 0, 63, 1, 51); 1671 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1672 V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1673 0, 63, 1, 30); 1674 v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1675 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, 1676 V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY, 0, 1677 V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED); 1678 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1679 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, 1680 -6, 6, 1, 0); 1681 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1682 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, 1683 -6, 6, 1, 0); 1684 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1685 V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM, 1686 0, 1, 1, 1); 1687 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1688 V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION, 1689 0, 1, 1, 0); 1690 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1691 V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET, 1692 -12, 12, 1, 0); 1693 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1694 V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, 1695 0, 2047, 1, 0); 1696 v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1697 V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, 1698 V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, 0, 1699 V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC); 1700 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1701 V4L2_CID_MPEG_VIDEO_AU_DELIMITER, 1702 0, 1, 1, 1); 1703 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1704 V4L2_CID_HFLIP, 1705 0, 1, 1, 0); 1706 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1707 V4L2_CID_VFLIP, 1708 0, 1, 1, 0); 1709 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1710 V4L2_CID_ROTATE, 1711 0, 270, 90, 0); 1712 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1713 V4L2_CID_MPEG_VIDEO_VBV_SIZE, 1714 10, 3000, 1, 1000); 1715 v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1716 V4L2_CID_MPEG_VIDEO_BITRATE_MODE, 1717 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0, 1718 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR); 1719 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1720 V4L2_CID_MPEG_VIDEO_BITRATE, 1721 0, 700000000, 1, 0); 1722 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1723 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1724 0, 2047, 1, 0); 1725 v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1726 V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, 1727 V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB, 0, 1728 V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE); 1729 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1730 V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, 1731 0, 0xFFFF, 1, 0); 1732 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1733 V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 1734 0, 1, 1, 0); 1735 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1736 V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE, 1737 0, 1, 1, 0); 1738 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1739 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 1); 1740 v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops, 1741 V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR, 1742 0, 1, 1, 0); 1743 1744 if (v4l2_ctrl_hdl->error) { 1745 ret = -ENODEV; 1746 goto cleanup_inst; 1747 } 1748 1749 inst->v4l2_fh.ctrl_handler = v4l2_ctrl_hdl; 1750 v4l2_ctrl_handler_setup(v4l2_ctrl_hdl); 1751 1752 wave5_set_default_format(&inst->src_fmt, &inst->dst_fmt); 1753 inst->conf_win.width = inst->dst_fmt.width; 1754 inst->conf_win.height = inst->dst_fmt.height; 1755 inst->colorspace = V4L2_COLORSPACE_REC709; 1756 inst->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 1757 inst->quantization = V4L2_QUANTIZATION_DEFAULT; 1758 inst->xfer_func = V4L2_XFER_FUNC_DEFAULT; 1759 inst->frame_rate = 30; 1760 1761 init_completion(&inst->irq_done); 1762 ret = wave5_kfifo_alloc(inst); 1763 if (ret) { 1764 dev_err(inst->dev->dev, "failed to allocate fifo\n"); 1765 goto cleanup_inst; 1766 } 1767 1768 inst->id = ida_alloc(&inst->dev->inst_ida, GFP_KERNEL); 1769 if (inst->id < 0) { 1770 dev_warn(inst->dev->dev, "Allocating instance ID, fail: %d\n", inst->id); 1771 ret = inst->id; 1772 goto cleanup_inst; 1773 } 1774 1775 wave5_vdi_allocate_sram(inst->dev); 1776 1777 ret = mutex_lock_interruptible(&dev->dev_lock); 1778 if (ret) 1779 goto cleanup_inst; 1780 1781 list_add_tail(&inst->list, &dev->instances); 1782 1783 mutex_unlock(&dev->dev_lock); 1784 1785 return 0; 1786 1787cleanup_inst: 1788 wave5_cleanup_instance(inst, filp); 1789 return ret; 1790} 1791 1792static int wave5_vpu_enc_release(struct file *filp) 1793{ 1794 return wave5_vpu_release_device(filp, wave5_vpu_enc_close, "encoder"); 1795} 1796 1797static const struct v4l2_file_operations wave5_vpu_enc_fops = { 1798 .owner = THIS_MODULE, 1799 .open = wave5_vpu_open_enc, 1800 .release = wave5_vpu_enc_release, 1801 .unlocked_ioctl = video_ioctl2, 1802 .poll = v4l2_m2m_fop_poll, 1803 .mmap = v4l2_m2m_fop_mmap, 1804}; 1805 1806int wave5_vpu_enc_register_device(struct vpu_device *dev) 1807{ 1808 struct video_device *vdev_enc; 1809 int ret; 1810 1811 vdev_enc = devm_kzalloc(dev->v4l2_dev.dev, sizeof(*vdev_enc), GFP_KERNEL); 1812 if (!vdev_enc) 1813 return -ENOMEM; 1814 1815 dev->v4l2_m2m_enc_dev = v4l2_m2m_init(&wave5_vpu_enc_m2m_ops); 1816 if (IS_ERR(dev->v4l2_m2m_enc_dev)) { 1817 ret = PTR_ERR(dev->v4l2_m2m_enc_dev); 1818 dev_err(dev->dev, "v4l2_m2m_init, fail: %d\n", ret); 1819 return -EINVAL; 1820 } 1821 1822 dev->video_dev_enc = vdev_enc; 1823 1824 strscpy(vdev_enc->name, VPU_ENC_DEV_NAME, sizeof(vdev_enc->name)); 1825 vdev_enc->fops = &wave5_vpu_enc_fops; 1826 vdev_enc->ioctl_ops = &wave5_vpu_enc_ioctl_ops; 1827 vdev_enc->release = video_device_release_empty; 1828 vdev_enc->v4l2_dev = &dev->v4l2_dev; 1829 vdev_enc->vfl_dir = VFL_DIR_M2M; 1830 vdev_enc->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 1831 vdev_enc->lock = &dev->dev_lock; 1832 1833 ret = video_register_device(vdev_enc, VFL_TYPE_VIDEO, -1); 1834 if (ret) 1835 return ret; 1836 1837 video_set_drvdata(vdev_enc, dev); 1838 1839 return 0; 1840} 1841 1842void wave5_vpu_enc_unregister_device(struct vpu_device *dev) 1843{ 1844 video_unregister_device(dev->video_dev_enc); 1845 if (dev->v4l2_m2m_enc_dev) 1846 v4l2_m2m_release(dev->v4l2_m2m_enc_dev); 1847}
~/
Read-only file preview.