2760 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * linux/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c4 *5 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.6 * http://www.samsung.com/7 *8 * Jeongtae Park <jtp.park@samsung.com>9 * Kamil Debski <k.debski@samsung.com>10 */11 12#include <linux/clk.h>13#include <linux/interrupt.h>14#include <linux/io.h>15#include <linux/module.h>16#include <linux/platform_device.h>17#include <linux/sched.h>18#include <linux/videodev2.h>19#include <media/v4l2-event.h>20#include <linux/workqueue.h>21#include <media/v4l2-ctrls.h>22#include <media/videobuf2-v4l2.h>23#include "s5p_mfc_common.h"24#include "s5p_mfc_ctrl.h"25#include "s5p_mfc_debug.h"26#include "s5p_mfc_enc.h"27#include "s5p_mfc_intr.h"28#include "s5p_mfc_opr.h"29 30#define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12M31#define DEF_DST_FMT_ENC V4L2_PIX_FMT_H26432 33static const struct s5p_mfc_fmt formats[] = {34 {35 .fourcc = V4L2_PIX_FMT_NV12MT_16X16,36 .codec_mode = S5P_MFC_CODEC_NONE,37 .type = MFC_FMT_RAW,38 .num_planes = 2,39 .versions = MFC_V6_BIT | MFC_V7_BIT,40 },41 {42 .fourcc = V4L2_PIX_FMT_NV12MT,43 .codec_mode = S5P_MFC_CODEC_NONE,44 .type = MFC_FMT_RAW,45 .num_planes = 2,46 .versions = MFC_V5_BIT,47 },48 {49 .fourcc = V4L2_PIX_FMT_NV12M,50 .codec_mode = S5P_MFC_CODEC_NONE,51 .type = MFC_FMT_RAW,52 .num_planes = 2,53 .versions = MFC_V5PLUS_BITS,54 },55 {56 .fourcc = V4L2_PIX_FMT_NV21M,57 .codec_mode = S5P_MFC_CODEC_NONE,58 .type = MFC_FMT_RAW,59 .num_planes = 2,60 .versions = MFC_V6PLUS_BITS,61 },62 {63 .fourcc = V4L2_PIX_FMT_YUV420M,64 .codec_mode = S5P_MFC_CODEC_NONE,65 .type = MFC_FMT_RAW,66 .num_planes = 3,67 .versions = MFC_V12_BIT,68 },69 {70 .fourcc = V4L2_PIX_FMT_YVU420M,71 .codec_mode = S5P_MFC_CODEC_NONE,72 .type = MFC_FMT_RAW,73 .num_planes = 3,74 .versions = MFC_V12_BIT,75 },76 {77 .fourcc = V4L2_PIX_FMT_H264,78 .codec_mode = S5P_MFC_CODEC_H264_ENC,79 .type = MFC_FMT_ENC,80 .num_planes = 1,81 .versions = MFC_V5PLUS_BITS,82 },83 {84 .fourcc = V4L2_PIX_FMT_MPEG4,85 .codec_mode = S5P_MFC_CODEC_MPEG4_ENC,86 .type = MFC_FMT_ENC,87 .num_planes = 1,88 .versions = MFC_V5PLUS_BITS,89 },90 {91 .fourcc = V4L2_PIX_FMT_H263,92 .codec_mode = S5P_MFC_CODEC_H263_ENC,93 .type = MFC_FMT_ENC,94 .num_planes = 1,95 .versions = MFC_V5PLUS_BITS,96 },97 {98 .fourcc = V4L2_PIX_FMT_VP8,99 .codec_mode = S5P_MFC_CODEC_VP8_ENC,100 .type = MFC_FMT_ENC,101 .num_planes = 1,102 .versions = MFC_V7PLUS_BITS,103 },104 {105 .fourcc = V4L2_PIX_FMT_HEVC,106 .codec_mode = S5P_FIMV_CODEC_HEVC_ENC,107 .type = MFC_FMT_ENC,108 .num_planes = 1,109 .versions = MFC_V10PLUS_BITS,110 },111};112 113#define NUM_FORMATS ARRAY_SIZE(formats)114static const struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t)115{116 unsigned int i;117 118 for (i = 0; i < NUM_FORMATS; i++) {119 if (formats[i].fourcc == f->fmt.pix_mp.pixelformat &&120 formats[i].type == t)121 return &formats[i];122 }123 return NULL;124}125 126static struct mfc_control controls[] = {127 {128 .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,129 .type = V4L2_CTRL_TYPE_INTEGER,130 .minimum = 0,131 .maximum = (1 << 16) - 1,132 .step = 1,133 .default_value = 12,134 },135 {136 .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,137 .type = V4L2_CTRL_TYPE_MENU,138 .minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,139 .maximum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES,140 .default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,141 .menu_skip_mask = 0,142 },143 {144 .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,145 .type = V4L2_CTRL_TYPE_INTEGER,146 .minimum = 1,147 .maximum = (1 << 16) - 1,148 .step = 1,149 .default_value = 1,150 },151 {152 .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,153 .type = V4L2_CTRL_TYPE_INTEGER,154 .minimum = 1900,155 .maximum = (1 << 30) - 1,156 .step = 1,157 .default_value = 1900,158 },159 {160 .id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,161 .type = V4L2_CTRL_TYPE_INTEGER,162 .minimum = 0,163 .maximum = (1 << 16) - 1,164 .step = 1,165 .default_value = 0,166 },167 {168 .id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING,169 .type = V4L2_CTRL_TYPE_BOOLEAN,170 .name = "Padding Control Enable",171 .minimum = 0,172 .maximum = 1,173 .step = 1,174 .default_value = 0,175 },176 {177 .id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV,178 .type = V4L2_CTRL_TYPE_INTEGER,179 .name = "Padding Color YUV Value",180 .minimum = 0,181 .maximum = (1 << 25) - 1,182 .step = 1,183 .default_value = 0,184 },185 {186 .id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,187 .type = V4L2_CTRL_TYPE_BOOLEAN,188 .minimum = 0,189 .maximum = 1,190 .step = 1,191 .default_value = 0,192 },193 {194 .id = V4L2_CID_MPEG_VIDEO_BITRATE,195 .type = V4L2_CTRL_TYPE_INTEGER,196 .minimum = 1,197 .maximum = (1 << 30) - 1,198 .step = 1,199 .default_value = 1,200 },201 {202 .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF,203 .type = V4L2_CTRL_TYPE_INTEGER,204 .name = "Rate Control Reaction Coeff.",205 .minimum = 1,206 .maximum = (1 << 16) - 1,207 .step = 1,208 .default_value = 1,209 },210 {211 .id = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE,212 .type = V4L2_CTRL_TYPE_MENU,213 .name = "Force frame type",214 .minimum = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED,215 .maximum = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED,216 .default_value = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED,217 .menu_skip_mask = 0,218 },219 {220 .id = V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME,221 .type = V4L2_CTRL_TYPE_BUTTON,222 .minimum = 0,223 .maximum = 0,224 .step = 0,225 .default_value = 0,226 },227 {228 .id = V4L2_CID_MPEG_VIDEO_VBV_SIZE,229 .type = V4L2_CTRL_TYPE_INTEGER,230 .minimum = 0,231 .maximum = (1 << 16) - 1,232 .step = 1,233 .default_value = 0,234 },235 {236 .id = V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE,237 .type = V4L2_CTRL_TYPE_INTEGER,238 .name = "Horizontal MV Search Range",239 .minimum = 16,240 .maximum = 128,241 .step = 16,242 .default_value = 32,243 },244 {245 .id = V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE,246 .type = V4L2_CTRL_TYPE_INTEGER,247 .name = "Vertical MV Search Range",248 .minimum = 16,249 .maximum = 128,250 .step = 16,251 .default_value = 32,252 },253 {254 .id = V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE,255 .type = V4L2_CTRL_TYPE_INTEGER,256 .minimum = 0,257 .maximum = (1 << 16) - 1,258 .step = 1,259 .default_value = 0,260 },261 {262 .id = V4L2_CID_MPEG_VIDEO_HEADER_MODE,263 .type = V4L2_CTRL_TYPE_MENU,264 .minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,265 .maximum = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,266 .default_value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,267 .menu_skip_mask = 0,268 },269 {270 .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE,271 .type = V4L2_CTRL_TYPE_MENU,272 .name = "Frame Skip Enable",273 .minimum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED,274 .maximum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,275 .menu_skip_mask = 0,276 .default_value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED,277 },278 {279 .id = V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE,280 .type = V4L2_CTRL_TYPE_MENU,281 .maximum = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,282 .default_value = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,283 },284 {285 .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT,286 .type = V4L2_CTRL_TYPE_BOOLEAN,287 .name = "Fixed Target Bit Enable",288 .minimum = 0,289 .maximum = 1,290 .default_value = 0,291 .step = 1,292 .menu_skip_mask = 0,293 },294 {295 .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,296 .type = V4L2_CTRL_TYPE_INTEGER,297 .minimum = 0,298 .maximum = 2,299 .step = 1,300 .default_value = 0,301 },302 {303 .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,304 .type = V4L2_CTRL_TYPE_MENU,305 .minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,306 .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,307 .default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,308 .menu_skip_mask = ~(309 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |310 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |311 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)312 ),313 },314 {315 .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,316 .type = V4L2_CTRL_TYPE_MENU,317 .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,318 .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_0,319 .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,320 },321 {322 .id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,323 .type = V4L2_CTRL_TYPE_MENU,324 .minimum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,325 .maximum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,326 .default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,327 .menu_skip_mask = 0,328 },329 {330 .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,331 .type = V4L2_CTRL_TYPE_MENU,332 .minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,333 .maximum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY,334 .default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,335 .menu_skip_mask = 0,336 },337 {338 .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,339 .type = V4L2_CTRL_TYPE_INTEGER,340 .minimum = -6,341 .maximum = 6,342 .step = 1,343 .default_value = 0,344 },345 {346 .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,347 .type = V4L2_CTRL_TYPE_INTEGER,348 .minimum = -6,349 .maximum = 6,350 .step = 1,351 .default_value = 0,352 },353 {354 .id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,355 .type = V4L2_CTRL_TYPE_MENU,356 .minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,357 .maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,358 .default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,359 .menu_skip_mask = 0,360 },361 {362 .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P,363 .type = V4L2_CTRL_TYPE_INTEGER,364 .name = "The Number of Ref. Pic for P",365 .minimum = 1,366 .maximum = 2,367 .step = 1,368 .default_value = 1,369 },370 {371 .id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,372 .type = V4L2_CTRL_TYPE_BOOLEAN,373 .minimum = 0,374 .maximum = 1,375 .step = 1,376 .default_value = 0,377 },378 {379 .id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE,380 .type = V4L2_CTRL_TYPE_BOOLEAN,381 .minimum = 0,382 .maximum = 1,383 .step = 1,384 .default_value = 0,385 },386 {387 .id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,388 .type = V4L2_CTRL_TYPE_INTEGER,389 .minimum = 0,390 .maximum = 51,391 .step = 1,392 .default_value = 1,393 },394 {395 .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,396 .type = V4L2_CTRL_TYPE_INTEGER,397 .minimum = 0,398 .maximum = 51,399 .step = 1,400 .default_value = 1,401 },402 {403 .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,404 .type = V4L2_CTRL_TYPE_INTEGER,405 .minimum = 0,406 .maximum = 51,407 .step = 1,408 .default_value = 51,409 },410 {411 .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,412 .type = V4L2_CTRL_TYPE_INTEGER,413 .minimum = 0,414 .maximum = 51,415 .step = 1,416 .default_value = 1,417 },418 {419 .id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,420 .type = V4L2_CTRL_TYPE_INTEGER,421 .minimum = 0,422 .maximum = 51,423 .step = 1,424 .default_value = 1,425 },426 {427 .id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP,428 .type = V4L2_CTRL_TYPE_INTEGER,429 .name = "H263 I-Frame QP value",430 .minimum = 1,431 .maximum = 31,432 .step = 1,433 .default_value = 1,434 },435 {436 .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,437 .type = V4L2_CTRL_TYPE_INTEGER,438 .name = "H263 Minimum QP value",439 .minimum = 1,440 .maximum = 31,441 .step = 1,442 .default_value = 1,443 },444 {445 .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,446 .type = V4L2_CTRL_TYPE_INTEGER,447 .name = "H263 Maximum QP value",448 .minimum = 1,449 .maximum = 31,450 .step = 1,451 .default_value = 31,452 },453 {454 .id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP,455 .type = V4L2_CTRL_TYPE_INTEGER,456 .name = "H263 P frame QP value",457 .minimum = 1,458 .maximum = 31,459 .step = 1,460 .default_value = 1,461 },462 {463 .id = V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP,464 .type = V4L2_CTRL_TYPE_INTEGER,465 .name = "H263 B frame QP value",466 .minimum = 1,467 .maximum = 31,468 .step = 1,469 .default_value = 1,470 },471 {472 .id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP,473 .type = V4L2_CTRL_TYPE_INTEGER,474 .name = "MPEG4 I-Frame QP value",475 .minimum = 1,476 .maximum = 31,477 .step = 1,478 .default_value = 1,479 },480 {481 .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,482 .type = V4L2_CTRL_TYPE_INTEGER,483 .name = "MPEG4 Minimum QP value",484 .minimum = 1,485 .maximum = 31,486 .step = 1,487 .default_value = 1,488 },489 {490 .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,491 .type = V4L2_CTRL_TYPE_INTEGER,492 .name = "MPEG4 Maximum QP value",493 .minimum = 0,494 .maximum = 51,495 .step = 1,496 .default_value = 51,497 },498 {499 .id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP,500 .type = V4L2_CTRL_TYPE_INTEGER,501 .name = "MPEG4 P frame QP value",502 .minimum = 1,503 .maximum = 31,504 .step = 1,505 .default_value = 1,506 },507 {508 .id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP,509 .type = V4L2_CTRL_TYPE_INTEGER,510 .name = "MPEG4 B frame QP value",511 .minimum = 1,512 .maximum = 31,513 .step = 1,514 .default_value = 1,515 },516 {517 .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK,518 .type = V4L2_CTRL_TYPE_BOOLEAN,519 .name = "H264 Dark Reg Adaptive RC",520 .minimum = 0,521 .maximum = 1,522 .step = 1,523 .default_value = 0,524 },525 {526 .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH,527 .type = V4L2_CTRL_TYPE_BOOLEAN,528 .name = "H264 Smooth Reg Adaptive RC",529 .minimum = 0,530 .maximum = 1,531 .step = 1,532 .default_value = 0,533 },534 {535 .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC,536 .type = V4L2_CTRL_TYPE_BOOLEAN,537 .name = "H264 Static Reg Adaptive RC",538 .minimum = 0,539 .maximum = 1,540 .step = 1,541 .default_value = 0,542 },543 {544 .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY,545 .type = V4L2_CTRL_TYPE_BOOLEAN,546 .name = "H264 Activity Reg Adaptive RC",547 .minimum = 0,548 .maximum = 1,549 .step = 1,550 .default_value = 0,551 },552 {553 .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE,554 .type = V4L2_CTRL_TYPE_BOOLEAN,555 .minimum = 0,556 .maximum = 1,557 .step = 1,558 .default_value = 0,559 },560 {561 .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,562 .type = V4L2_CTRL_TYPE_MENU,563 .minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,564 .maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,565 .default_value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,566 .menu_skip_mask = 0,567 },568 {569 .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,570 .type = V4L2_CTRL_TYPE_INTEGER,571 .minimum = 0,572 .maximum = (1 << 16) - 1,573 .step = 1,574 .default_value = 0,575 },576 {577 .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,578 .type = V4L2_CTRL_TYPE_INTEGER,579 .minimum = 0,580 .maximum = (1 << 16) - 1,581 .step = 1,582 .default_value = 0,583 },584 {585 .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,586 .type = V4L2_CTRL_TYPE_BOOLEAN,587 .minimum = 0,588 .maximum = 1,589 .step = 1,590 .default_value = 1,591 },592 {593 .id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,594 .type = V4L2_CTRL_TYPE_INTEGER,595 .minimum = 0,596 .maximum = (1 << 16) - 1,597 .step = 1,598 .default_value = 0,599 },600 {601 .id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,602 .type = V4L2_CTRL_TYPE_MENU,603 .minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,604 .maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE,605 .default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,606 .menu_skip_mask = 0,607 },608 {609 .id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL,610 .type = V4L2_CTRL_TYPE_BOOLEAN,611 .minimum = 0,612 .maximum = 1,613 .step = 1,614 .default_value = 0,615 },616 {617 .id = V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS,618 .type = V4L2_CTRL_TYPE_INTEGER_MENU,619 .maximum = V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS,620 .default_value = V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION,621 .menu_skip_mask = 0,622 },623 {624 .id = V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4,625 .type = V4L2_CTRL_TYPE_BOOLEAN,626 .minimum = 0,627 .maximum = 1,628 .step = 1,629 .default_value = 0,630 },631 {632 .id = V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES,633 .type = V4L2_CTRL_TYPE_INTEGER_MENU,634 .maximum = V4L2_CID_MPEG_VIDEO_VPX_2_REF_FRAME,635 .default_value = V4L2_CID_MPEG_VIDEO_VPX_1_REF_FRAME,636 .menu_skip_mask = 0,637 },638 {639 .id = V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL,640 .type = V4L2_CTRL_TYPE_INTEGER,641 .minimum = 0,642 .maximum = 63,643 .step = 1,644 .default_value = 0,645 },646 {647 .id = V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS,648 .type = V4L2_CTRL_TYPE_INTEGER,649 .minimum = 0,650 .maximum = 7,651 .step = 1,652 .default_value = 0,653 },654 {655 .id = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD,656 .type = V4L2_CTRL_TYPE_INTEGER,657 .minimum = 0,658 .maximum = (1 << 16) - 1,659 .step = 1,660 .default_value = 0,661 },662 {663 .id = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL,664 .type = V4L2_CTRL_TYPE_MENU,665 .minimum = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV,666 .maximum = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD,667 .default_value = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV,668 .menu_skip_mask = 0,669 },670 {671 .id = V4L2_CID_MPEG_VIDEO_VPX_MAX_QP,672 .type = V4L2_CTRL_TYPE_INTEGER,673 .minimum = 0,674 .maximum = 127,675 .step = 1,676 .default_value = 127,677 },678 {679 .id = V4L2_CID_MPEG_VIDEO_VPX_MIN_QP,680 .type = V4L2_CTRL_TYPE_INTEGER,681 .minimum = 0,682 .maximum = 11,683 .step = 1,684 .default_value = 0,685 },686 {687 .id = V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP,688 .type = V4L2_CTRL_TYPE_INTEGER,689 .minimum = 0,690 .maximum = 127,691 .step = 1,692 .default_value = 10,693 },694 {695 .id = V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP,696 .type = V4L2_CTRL_TYPE_INTEGER,697 .minimum = 0,698 .maximum = 127,699 .step = 1,700 .default_value = 10,701 },702 {703 .id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE,704 .type = V4L2_CTRL_TYPE_MENU,705 .minimum = V4L2_MPEG_VIDEO_VP8_PROFILE_0,706 .maximum = V4L2_MPEG_VIDEO_VP8_PROFILE_3,707 .default_value = V4L2_MPEG_VIDEO_VP8_PROFILE_0,708 .menu_skip_mask = 0,709 },710 {711 .id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,712 .type = V4L2_CTRL_TYPE_INTEGER,713 .name = "HEVC I Frame QP Value",714 .minimum = 0,715 .maximum = 51,716 .step = 1,717 .default_value = 0,718 },719 {720 .id = V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP,721 .type = V4L2_CTRL_TYPE_INTEGER,722 .name = "HEVC P Frame QP Value",723 .minimum = 0,724 .maximum = 51,725 .step = 1,726 .default_value = 0,727 },728 {729 .id = V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP,730 .type = V4L2_CTRL_TYPE_INTEGER,731 .minimum = 0,732 .maximum = 51,733 .step = 1,734 .default_value = 0,735 },736 {737 .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,738 .type = V4L2_CTRL_TYPE_INTEGER,739 .minimum = 0,740 .maximum = 51,741 .step = 1,742 .default_value = 0,743 },744 {745 .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,746 .type = V4L2_CTRL_TYPE_INTEGER,747 .minimum = 0,748 .maximum = 51,749 .step = 1,750 .default_value = 0,751 },752 {753 .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,754 .type = V4L2_CTRL_TYPE_MENU,755 .minimum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,756 .maximum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE,757 .step = 1,758 .default_value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,759 },760 {761 .id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,762 .type = V4L2_CTRL_TYPE_MENU,763 .minimum = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,764 .maximum = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,765 .step = 1,766 .default_value = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,767 },768 {769 .id = V4L2_CID_MPEG_VIDEO_HEVC_TIER,770 .type = V4L2_CTRL_TYPE_MENU,771 .minimum = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN,772 .maximum = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,773 .step = 1,774 .default_value = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN,775 },776 {777 .id = V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION,778 .type = V4L2_CTRL_TYPE_INTEGER,779 .minimum = 1,780 .maximum = (1 << 16) - 1,781 .step = 1,782 .default_value = 1,783 },784 {785 .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH,786 .type = V4L2_CTRL_TYPE_INTEGER,787 .minimum = 0,788 .maximum = 1,789 .step = 1,790 .default_value = 0,791 },792 {793 .id = V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES,794 .type = V4L2_CTRL_TYPE_INTEGER,795 .minimum = 1,796 .maximum = 2,797 .step = 1,798 .default_value = 1,799 },800 {801 .id = V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE,802 .type = V4L2_CTRL_TYPE_MENU,803 .minimum = V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE,804 .maximum = V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR,805 .step = 1,806 .default_value = V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE,807 },808 {809 .id = V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED,810 .type = V4L2_CTRL_TYPE_BOOLEAN,811 .minimum = 0,812 .maximum = 1,813 .step = 1,814 .default_value = 0,815 },816 {817 .id = V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU,818 .type = V4L2_CTRL_TYPE_BOOLEAN,819 .minimum = 0,820 .maximum = 1,821 .step = 1,822 .default_value = 0,823 },824 {825 .id = V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT,826 .type = V4L2_CTRL_TYPE_BOOLEAN,827 .minimum = 0,828 .maximum = 1,829 .step = 1,830 .default_value = 0,831 },832 {833 .id = V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE,834 .type = V4L2_CTRL_TYPE_MENU,835 .minimum = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED,836 .maximum = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY,837 .step = 1,838 .default_value = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED,839 },840 {841 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP,842 .type = V4L2_CTRL_TYPE_BOOLEAN,843 .minimum = 0,844 .maximum = 1,845 .step = 1,846 .default_value = 0,847 },848 {849 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE,850 .type = V4L2_CTRL_TYPE_MENU,851 .minimum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,852 .maximum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,853 .step = 1,854 .default_value = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,855 },856 {857 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER,858 .type = V4L2_CTRL_TYPE_INTEGER,859 .minimum = 0,860 .maximum = 6,861 .step = 1,862 .default_value = 0,863 },864 {865 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP,866 .type = V4L2_CTRL_TYPE_INTEGER,867 .minimum = 0,868 .maximum = 51,869 .step = 1,870 .default_value = 0,871 },872 {873 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP,874 .type = V4L2_CTRL_TYPE_INTEGER,875 .minimum = 0,876 .maximum = 51,877 .step = 1,878 .default_value = 0,879 },880 {881 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP,882 .type = V4L2_CTRL_TYPE_INTEGER,883 .minimum = 0,884 .maximum = 51,885 .step = 1,886 .default_value = 0,887 },888 {889 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP,890 .type = V4L2_CTRL_TYPE_INTEGER,891 .minimum = 0,892 .maximum = 51,893 .step = 1,894 .default_value = 0,895 },896 {897 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP,898 .type = V4L2_CTRL_TYPE_INTEGER,899 .minimum = 0,900 .maximum = 51,901 .step = 1,902 .default_value = 0,903 },904 {905 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP,906 .type = V4L2_CTRL_TYPE_INTEGER,907 .minimum = 0,908 .maximum = 51,909 .step = 1,910 .default_value = 0,911 },912 {913 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP,914 .type = V4L2_CTRL_TYPE_INTEGER,915 .minimum = 0,916 .maximum = 51,917 .step = 1,918 .default_value = 0,919 },920 {921 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR,922 .type = V4L2_CTRL_TYPE_INTEGER,923 .minimum = INT_MIN,924 .maximum = INT_MAX,925 .step = 1,926 .default_value = 0,927 },928 {929 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR,930 .type = V4L2_CTRL_TYPE_INTEGER,931 .minimum = INT_MIN,932 .maximum = INT_MAX,933 .step = 1,934 .default_value = 0,935 },936 {937 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR,938 .type = V4L2_CTRL_TYPE_INTEGER,939 .minimum = INT_MIN,940 .maximum = INT_MAX,941 .step = 1,942 .default_value = 0,943 },944 {945 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR,946 .type = V4L2_CTRL_TYPE_INTEGER,947 .minimum = INT_MIN,948 .maximum = INT_MAX,949 .step = 1,950 .default_value = 0,951 },952 {953 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR,954 .type = V4L2_CTRL_TYPE_INTEGER,955 .minimum = INT_MIN,956 .maximum = INT_MAX,957 .step = 1,958 .default_value = 0,959 },960 {961 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR,962 .type = V4L2_CTRL_TYPE_INTEGER,963 .minimum = INT_MIN,964 .maximum = INT_MAX,965 .step = 1,966 .default_value = 0,967 },968 {969 .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR,970 .type = V4L2_CTRL_TYPE_INTEGER,971 .minimum = INT_MIN,972 .maximum = INT_MAX,973 .step = 1,974 .default_value = 0,975 },976 {977 .id = V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB,978 .type = V4L2_CTRL_TYPE_BOOLEAN,979 .minimum = 0,980 .maximum = 1,981 .step = 1,982 .default_value = 0,983 },984 {985 .id = V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID,986 .type = V4L2_CTRL_TYPE_BOOLEAN,987 .minimum = 0,988 .maximum = 1,989 .step = 1,990 .default_value = 0,991 },992 {993 .id = V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING,994 .type = V4L2_CTRL_TYPE_BOOLEAN,995 .minimum = 0,996 .maximum = 1,997 .step = 1,998 .default_value = 0,999 },1000 {1001 .id = V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT,1002 .type = V4L2_CTRL_TYPE_BOOLEAN,1003 .minimum = 0,1004 .maximum = 1,1005 .step = 1,1006 .default_value = 0,1007 },1008 {1009 .id = V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION,1010 .type = V4L2_CTRL_TYPE_BOOLEAN,1011 .minimum = 0,1012 .maximum = 1,1013 .step = 1,1014 .default_value = 0,1015 },1016 {1017 .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1,1018 .type = V4L2_CTRL_TYPE_INTEGER,1019 .minimum = 0,1020 .maximum = 4,1021 .step = 1,1022 .default_value = 0,1023 },1024 {1025 .id = V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE,1026 .type = V4L2_CTRL_TYPE_BOOLEAN,1027 .minimum = 0,1028 .maximum = 1,1029 .step = 1,1030 .default_value = 0,1031 },1032 {1033 .id = V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD,1034 .type = V4L2_CTRL_TYPE_INTEGER,1035 .minimum = 0,1036 .maximum = (1 << 16) - 1,1037 .step = 1,1038 .default_value = 0,1039 },1040 {1041 .id = V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2,1042 .type = V4L2_CTRL_TYPE_INTEGER,1043 .minimum = -6,1044 .maximum = 6,1045 .step = 1,1046 .default_value = 0,1047 },1048 {1049 .id = V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2,1050 .type = V4L2_CTRL_TYPE_INTEGER,1051 .minimum = -6,1052 .maximum = 6,1053 .step = 1,1054 .default_value = 0,1055 },1056 {1057 .id = V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD,1058 .type = V4L2_CTRL_TYPE_MENU,1059 .minimum = V4L2_MPEG_VIDEO_HEVC_SIZE_0,1060 .maximum = V4L2_MPEG_VIDEO_HEVC_SIZE_4,1061 .step = 1,1062 .default_value = V4L2_MPEG_VIDEO_HEVC_SIZE_0,1063 },1064 {1065 .id = V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR,1066 .type = V4L2_CTRL_TYPE_INTEGER,1067 .minimum = 0,1068 .maximum = 1,1069 .step = 1,1070 .default_value = 0,1071 },1072 {1073 .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,1074 .type = V4L2_CTRL_TYPE_INTEGER,1075 .name = "Minimum number of output bufs",1076 .minimum = 1,1077 .maximum = 32,1078 .step = 1,1079 .default_value = 1,1080 .is_volatile = 1,1081 },1082};1083 1084#define NUM_CTRLS ARRAY_SIZE(controls)1085static const char * const *mfc51_get_menu(u32 id)1086{1087 static const char * const mfc51_video_frame_skip[] = {1088 "Disabled",1089 "Level Limit",1090 "VBV/CPB Limit",1091 NULL,1092 };1093 static const char * const mfc51_video_force_frame[] = {1094 "Disabled",1095 "I Frame",1096 "Not Coded",1097 NULL,1098 };1099 switch (id) {1100 case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE:1101 return mfc51_video_frame_skip;1102 case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:1103 return mfc51_video_force_frame;1104 }1105 return NULL;1106}1107 1108static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)1109{1110 mfc_debug(2, "src=%d, dst=%d, state=%d\n",1111 ctx->src_queue_cnt, ctx->dst_queue_cnt, ctx->state);1112 /* context is ready to make header */1113 if (ctx->state == MFCINST_GOT_INST && ctx->dst_queue_cnt >= 1)1114 return 1;1115 /* context is ready to encode a frame */1116 if ((ctx->state == MFCINST_RUNNING ||1117 ctx->state == MFCINST_HEAD_PRODUCED) &&1118 ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)1119 return 1;1120 /* context is ready to encode remaining frames */1121 if (ctx->state == MFCINST_FINISHING &&1122 ctx->dst_queue_cnt >= 1)1123 return 1;1124 mfc_debug(2, "ctx is not ready\n");1125 return 0;1126}1127 1128static void cleanup_ref_queue(struct s5p_mfc_ctx *ctx)1129{1130 struct s5p_mfc_buf *mb_entry;1131 1132 /* move buffers in ref queue to src queue */1133 while (!list_empty(&ctx->ref_queue)) {1134 mb_entry = list_entry((&ctx->ref_queue)->next,1135 struct s5p_mfc_buf, list);1136 list_del(&mb_entry->list);1137 ctx->ref_queue_cnt--;1138 list_add_tail(&mb_entry->list, &ctx->src_queue);1139 ctx->src_queue_cnt++;1140 }1141 mfc_debug(2, "enc src count: %d, enc ref count: %d\n",1142 ctx->src_queue_cnt, ctx->ref_queue_cnt);1143 INIT_LIST_HEAD(&ctx->ref_queue);1144 ctx->ref_queue_cnt = 0;1145}1146 1147static int enc_pre_seq_start(struct s5p_mfc_ctx *ctx)1148{1149 struct s5p_mfc_dev *dev = ctx->dev;1150 struct s5p_mfc_buf *dst_mb;1151 unsigned long dst_addr;1152 unsigned int dst_size;1153 1154 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);1155 dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);1156 dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);1157 s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr,1158 dst_size);1159 return 0;1160}1161 1162static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)1163{1164 struct s5p_mfc_dev *dev = ctx->dev;1165 struct s5p_mfc_enc_params *p = &ctx->enc_params;1166 struct s5p_mfc_buf *dst_mb;1167 1168 if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) {1169 if (!list_empty(&ctx->dst_queue)) {1170 dst_mb = list_entry(ctx->dst_queue.next,1171 struct s5p_mfc_buf, list);1172 list_del(&dst_mb->list);1173 ctx->dst_queue_cnt--;1174 vb2_set_plane_payload(&dst_mb->b->vb2_buf, 0,1175 s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size,1176 dev));1177 vb2_buffer_done(&dst_mb->b->vb2_buf,1178 VB2_BUF_STATE_DONE);1179 }1180 }1181 1182 if (!IS_MFCV6_PLUS(dev)) {1183 ctx->state = MFCINST_RUNNING;1184 if (s5p_mfc_ctx_ready(ctx))1185 set_work_bit_irqsave(ctx);1186 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);1187 } else {1188 ctx->pb_count = s5p_mfc_hw_call(dev->mfc_ops, get_enc_dpb_count, dev);1189 if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {1190 ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops,1191 get_e_min_scratch_buf_size, dev);1192 if (!IS_MFCV12(dev))1193 ctx->bank1.size += ctx->scratch_buf_size;1194 }1195 ctx->state = MFCINST_HEAD_PRODUCED;1196 }1197 1198 return 0;1199}1200 1201static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)1202{1203 struct s5p_mfc_dev *dev = ctx->dev;1204 struct s5p_mfc_buf *dst_mb;1205 struct s5p_mfc_buf *src_mb;1206 unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;1207 unsigned int dst_size;1208 1209 src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);1210 src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);1211 src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);1212 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc ==1213 V4L2_PIX_FMT_YVU420M)1214 src_c_1_addr =1215 vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 2);1216 else1217 src_c_1_addr = 0;1218 s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,1219 src_y_addr, src_c_addr, src_c_1_addr);1220 1221 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);1222 dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);1223 dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);1224 s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr,1225 dst_size);1226 1227 return 0;1228}1229 1230static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)1231{1232 struct s5p_mfc_dev *dev = ctx->dev;1233 struct s5p_mfc_buf *mb_entry;1234 unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;1235 unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;1236 int slice_type;1237 unsigned int strm_size;1238 bool src_ready;1239 1240 slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);1241 strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);1242 mfc_debug(2, "Encoded slice type: %d\n", slice_type);1243 mfc_debug(2, "Encoded stream size: %d\n", strm_size);1244 mfc_debug(2, "Display order: %d\n",1245 mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));1246 if (slice_type >= 0) {1247 s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx,1248 &enc_y_addr, &enc_c_addr, &enc_c_1_addr);1249 list_for_each_entry(mb_entry, &ctx->src_queue, list) {1250 mb_y_addr = vb2_dma_contig_plane_dma_addr(1251 &mb_entry->b->vb2_buf, 0);1252 mb_c_addr = vb2_dma_contig_plane_dma_addr(1253 &mb_entry->b->vb2_buf, 1);1254 if (ctx->src_fmt->fourcc ==1255 V4L2_PIX_FMT_YUV420M ||1256 ctx->src_fmt->fourcc ==1257 V4L2_PIX_FMT_YVU420M)1258 mb_c_1_addr = vb2_dma_contig_plane_dma_addr1259 (&mb_entry->b->vb2_buf, 2);1260 else1261 mb_c_1_addr = 0;1262 if (enc_y_addr == mb_y_addr && enc_c_addr == mb_c_addr && enc_c_1_addr1263 == mb_c_1_addr) {1264 list_del(&mb_entry->list);1265 ctx->src_queue_cnt--;1266 vb2_buffer_done(&mb_entry->b->vb2_buf,1267 VB2_BUF_STATE_DONE);1268 break;1269 }1270 }1271 list_for_each_entry(mb_entry, &ctx->ref_queue, list) {1272 mb_y_addr = vb2_dma_contig_plane_dma_addr(1273 &mb_entry->b->vb2_buf, 0);1274 mb_c_addr = vb2_dma_contig_plane_dma_addr(1275 &mb_entry->b->vb2_buf, 1);1276 if (ctx->src_fmt->fourcc ==1277 V4L2_PIX_FMT_YUV420M ||1278 ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)1279 mb_c_1_addr = vb2_dma_contig_plane_dma_addr(&1280 mb_entry->b->vb2_buf, 2);1281 else1282 mb_c_1_addr = 0;1283 if (enc_y_addr == mb_y_addr && enc_c_addr == mb_c_addr && enc_c_1_addr1284 == mb_c_1_addr) {1285 list_del(&mb_entry->list);1286 ctx->ref_queue_cnt--;1287 vb2_buffer_done(&mb_entry->b->vb2_buf,1288 VB2_BUF_STATE_DONE);1289 break;1290 }1291 }1292 }1293 if (ctx->src_queue_cnt > 0 && (ctx->state == MFCINST_RUNNING ||1294 ctx->state == MFCINST_FINISHING)) {1295 mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,1296 list);1297 if (mb_entry->flags & MFC_BUF_FLAG_USED) {1298 list_del(&mb_entry->list);1299 ctx->src_queue_cnt--;1300 list_add_tail(&mb_entry->list, &ctx->ref_queue);1301 ctx->ref_queue_cnt++;1302 }1303 }1304 mfc_debug(2, "enc src count: %d, enc ref count: %d\n",1305 ctx->src_queue_cnt, ctx->ref_queue_cnt);1306 if ((ctx->dst_queue_cnt > 0) && (strm_size > 0)) {1307 mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf,1308 list);1309 list_del(&mb_entry->list);1310 ctx->dst_queue_cnt--;1311 switch (slice_type) {1312 case S5P_FIMV_ENC_SI_SLICE_TYPE_I:1313 mb_entry->b->flags |= V4L2_BUF_FLAG_KEYFRAME;1314 break;1315 case S5P_FIMV_ENC_SI_SLICE_TYPE_P:1316 mb_entry->b->flags |= V4L2_BUF_FLAG_PFRAME;1317 break;1318 case S5P_FIMV_ENC_SI_SLICE_TYPE_B:1319 mb_entry->b->flags |= V4L2_BUF_FLAG_BFRAME;1320 break;1321 }1322 vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, strm_size);1323 vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE);1324 }1325 1326 src_ready = true;1327 if (ctx->state == MFCINST_RUNNING && ctx->src_queue_cnt == 0)1328 src_ready = false;1329 if (ctx->state == MFCINST_FINISHING && ctx->ref_queue_cnt == 0)1330 src_ready = false;1331 if (!src_ready || ctx->dst_queue_cnt == 0)1332 clear_work_bit_irqsave(ctx);1333 1334 return 0;1335}1336 1337static const struct s5p_mfc_codec_ops encoder_codec_ops = {1338 .pre_seq_start = enc_pre_seq_start,1339 .post_seq_start = enc_post_seq_start,1340 .pre_frame_start = enc_pre_frame_start,1341 .post_frame_start = enc_post_frame_start,1342};1343 1344/* Query capabilities of the device */1345static int vidioc_querycap(struct file *file, void *priv,1346 struct v4l2_capability *cap)1347{1348 struct s5p_mfc_dev *dev = video_drvdata(file);1349 1350 strscpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver));1351 strscpy(cap->card, dev->vfd_enc->name, sizeof(cap->card));1352 return 0;1353}1354 1355static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f,1356 bool out)1357{1358 struct s5p_mfc_dev *dev = video_drvdata(file);1359 int i, j = 0;1360 1361 for (i = 0; i < ARRAY_SIZE(formats); ++i) {1362 if (out && formats[i].type != MFC_FMT_RAW)1363 continue;1364 else if (!out && formats[i].type != MFC_FMT_ENC)1365 continue;1366 else if ((dev->variant->version_bit & formats[i].versions) == 0)1367 continue;1368 1369 if (j == f->index) {1370 f->pixelformat = formats[i].fourcc;1371 return 0;1372 }1373 ++j;1374 }1375 return -EINVAL;1376}1377 1378static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv,1379 struct v4l2_fmtdesc *f)1380{1381 return vidioc_enum_fmt(file, f, false);1382}1383 1384static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,1385 struct v4l2_fmtdesc *f)1386{1387 return vidioc_enum_fmt(file, f, true);1388}1389 1390static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)1391{1392 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);1393 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;1394 1395 mfc_debug(2, "f->type = %d ctx->state = %d\n", f->type, ctx->state);1396 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {1397 /* This is run on output (encoder dest) */1398 pix_fmt_mp->width = 0;1399 pix_fmt_mp->height = 0;1400 pix_fmt_mp->field = V4L2_FIELD_NONE;1401 pix_fmt_mp->pixelformat = ctx->dst_fmt->fourcc;1402 pix_fmt_mp->num_planes = ctx->dst_fmt->num_planes;1403 1404 pix_fmt_mp->plane_fmt[0].bytesperline = ctx->enc_dst_buf_size;1405 pix_fmt_mp->plane_fmt[0].sizeimage = ctx->enc_dst_buf_size;1406 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {1407 /* This is run on capture (encoder src) */1408 pix_fmt_mp->width = ctx->img_width;1409 pix_fmt_mp->height = ctx->img_height;1410 1411 pix_fmt_mp->field = V4L2_FIELD_NONE;1412 pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;1413 pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;1414 1415 pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];1416 pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;1417 pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];1418 pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;1419 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc ==1420 V4L2_PIX_FMT_YVU420M) {1421 pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];1422 pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;1423 }1424 } else {1425 mfc_err("invalid buf type\n");1426 return -EINVAL;1427 }1428 return 0;1429}1430 1431static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)1432{1433 struct s5p_mfc_dev *dev = video_drvdata(file);1434 const struct s5p_mfc_fmt *fmt;1435 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;1436 1437 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {1438 fmt = find_format(f, MFC_FMT_ENC);1439 if (!fmt) {1440 mfc_err("failed to try output format\n");1441 return -EINVAL;1442 }1443 if ((dev->variant->version_bit & fmt->versions) == 0) {1444 mfc_err("Unsupported format by this MFC version.\n");1445 return -EINVAL;1446 }1447 1448 pix_fmt_mp->plane_fmt[0].bytesperline =1449 pix_fmt_mp->plane_fmt[0].sizeimage;1450 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {1451 fmt = find_format(f, MFC_FMT_RAW);1452 if (!fmt) {1453 mfc_err("failed to try output format\n");1454 return -EINVAL;1455 }1456 if ((dev->variant->version_bit & fmt->versions) == 0) {1457 mfc_err("Unsupported format by this MFC version.\n");1458 return -EINVAL;1459 }1460 if (IS_MFCV12(dev))1461 v4l_bound_align_image(&pix_fmt_mp->width, 8, 3840, 1, &pix_fmt_mp1462 ->height, 4, 2160, 1, 0);1463 else1464 v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1, &pix_fmt_mp1465 ->height, 4, 1080, 1, 0);1466 } else {1467 mfc_err("invalid buf type\n");1468 return -EINVAL;1469 }1470 return 0;1471}1472 1473static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)1474{1475 struct s5p_mfc_dev *dev = video_drvdata(file);1476 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);1477 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;1478 int ret = 0;1479 1480 ret = vidioc_try_fmt(file, priv, f);1481 if (ret)1482 return ret;1483 if (ctx->vq_src.streaming || ctx->vq_dst.streaming) {1484 v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);1485 ret = -EBUSY;1486 goto out;1487 }1488 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {1489 /* dst_fmt is validated by call to vidioc_try_fmt */1490 ctx->dst_fmt = find_format(f, MFC_FMT_ENC);1491 ctx->state = MFCINST_INIT;1492 ctx->codec_mode = ctx->dst_fmt->codec_mode;1493 ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage;1494 pix_fmt_mp->plane_fmt[0].bytesperline = 0;1495 ctx->dst_bufs_cnt = 0;1496 ctx->capture_state = QUEUE_FREE;1497 ret = s5p_mfc_open_mfc_inst(dev, ctx);1498 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {1499 /* src_fmt is validated by call to vidioc_try_fmt */1500 ctx->src_fmt = find_format(f, MFC_FMT_RAW);1501 ctx->img_width = pix_fmt_mp->width;1502 ctx->img_height = pix_fmt_mp->height;1503 mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode);1504 mfc_debug(2, "fmt - w: %d, h: %d, ctx - w: %d, h: %d\n",1505 pix_fmt_mp->width, pix_fmt_mp->height,1506 ctx->img_width, ctx->img_height);1507 1508 s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);1509 pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;1510 pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];1511 pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;1512 pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];1513 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc ==1514 V4L2_PIX_FMT_YVU420M) {1515 pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];1516 pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;1517 }1518 1519 ctx->src_bufs_cnt = 0;1520 ctx->output_state = QUEUE_FREE;1521 } else {1522 mfc_err("invalid buf type\n");1523 ret = -EINVAL;1524 }1525out:1526 mfc_debug_leave();1527 return ret;1528}1529 1530static int vidioc_reqbufs(struct file *file, void *priv,1531 struct v4l2_requestbuffers *reqbufs)1532{1533 struct s5p_mfc_dev *dev = video_drvdata(file);1534 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);1535 int ret = 0;1536 1537 /* if memory is not mmp or userptr or dmabuf return error */1538 if ((reqbufs->memory != V4L2_MEMORY_MMAP) &&1539 (reqbufs->memory != V4L2_MEMORY_USERPTR) &&1540 (reqbufs->memory != V4L2_MEMORY_DMABUF))1541 return -EINVAL;1542 if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {1543 if (reqbufs->count == 0) {1544 mfc_debug(2, "Freeing buffers\n");1545 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);1546 s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers,1547 ctx);1548 ctx->capture_state = QUEUE_FREE;1549 return ret;1550 }1551 if (ctx->capture_state != QUEUE_FREE) {1552 mfc_err("invalid capture state: %d\n",1553 ctx->capture_state);1554 return -EINVAL;1555 }1556 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);1557 if (ret != 0) {1558 mfc_err("error in vb2_reqbufs() for E(D)\n");1559 return ret;1560 }1561 ctx->capture_state = QUEUE_BUFS_REQUESTED;1562 1563 } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {1564 if (reqbufs->count == 0) {1565 mfc_debug(2, "Freeing buffers\n");1566 ret = vb2_reqbufs(&ctx->vq_src, reqbufs);1567 s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers,1568 ctx);1569 ctx->output_state = QUEUE_FREE;1570 return ret;1571 }1572 if (ctx->output_state != QUEUE_FREE) {1573 mfc_err("invalid output state: %d\n",1574 ctx->output_state);1575 return -EINVAL;1576 }1577 1578 if (IS_MFCV6_PLUS(dev) && (!IS_MFCV12(dev))) {1579 /* Check for min encoder buffers */1580 if (ctx->pb_count &&1581 (reqbufs->count < ctx->pb_count)) {1582 reqbufs->count = ctx->pb_count;1583 mfc_debug(2, "Minimum %d output buffers needed\n",1584 ctx->pb_count);1585 }1586 }1587 1588 ret = vb2_reqbufs(&ctx->vq_src, reqbufs);1589 if (ret != 0) {1590 mfc_err("error in vb2_reqbufs() for E(S)\n");1591 return ret;1592 }1593 ctx->output_state = QUEUE_BUFS_REQUESTED;1594 } else {1595 mfc_err("invalid buf type\n");1596 return -EINVAL;1597 }1598 return ret;1599}1600 1601static int vidioc_querybuf(struct file *file, void *priv,1602 struct v4l2_buffer *buf)1603{1604 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);1605 int ret = 0;1606 1607 /* if memory is not mmp or userptr or dmabuf return error */1608 if ((buf->memory != V4L2_MEMORY_MMAP) &&1609 (buf->memory != V4L2_MEMORY_USERPTR) &&1610 (buf->memory != V4L2_MEMORY_DMABUF))1611 return -EINVAL;1612 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {1613 if (ctx->state != MFCINST_GOT_INST) {1614 mfc_err("invalid context state: %d\n", ctx->state);1615 return -EINVAL;1616 }1617 ret = vb2_querybuf(&ctx->vq_dst, buf);1618 if (ret != 0) {1619 mfc_err("error in vb2_querybuf() for E(D)\n");1620 return ret;1621 }1622 buf->m.planes[0].m.mem_offset += DST_QUEUE_OFF_BASE;1623 } else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {1624 ret = vb2_querybuf(&ctx->vq_src, buf);1625 if (ret != 0) {1626 mfc_err("error in vb2_querybuf() for E(S)\n");1627 return ret;1628 }1629 } else {1630 mfc_err("invalid buf type\n");1631 return -EINVAL;1632 }1633 return ret;1634}1635 1636/* Queue a buffer */1637static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)1638{1639 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);1640 1641 if (ctx->state == MFCINST_ERROR) {1642 mfc_err("Call on QBUF after unrecoverable error\n");1643 return -EIO;1644 }1645 if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {1646 if (ctx->state == MFCINST_FINISHING) {1647 mfc_err("Call on QBUF after EOS command\n");1648 return -EIO;1649 }1650 return vb2_qbuf(&ctx->vq_src, NULL, buf);1651 } else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {1652 return vb2_qbuf(&ctx->vq_dst, NULL, buf);1653 }1654 return -EINVAL;1655}1656 1657/* Dequeue a buffer */1658static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)1659{1660 const struct v4l2_event ev = {1661 .type = V4L2_EVENT_EOS1662 };1663 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);1664 int ret;1665 1666 if (ctx->state == MFCINST_ERROR) {1667 mfc_err_limited("Call on DQBUF after unrecoverable error\n");1668 return -EIO;1669 }1670 if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {1671 ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);1672 } else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {1673 ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);1674 if (ret == 0 && ctx->state == MFCINST_FINISHED1675 && list_empty(&ctx->vq_dst.done_list))1676 v4l2_event_queue_fh(&ctx->fh, &ev);1677 } else {1678 ret = -EINVAL;1679 }1680 1681 return ret;1682}1683 1684/* Export DMA buffer */1685static int vidioc_expbuf(struct file *file, void *priv,1686 struct v4l2_exportbuffer *eb)1687{1688 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);1689 1690 if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)1691 return vb2_expbuf(&ctx->vq_src, eb);1692 if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)1693 return vb2_expbuf(&ctx->vq_dst, eb);1694 return -EINVAL;1695}1696 1697/* Stream on */1698static int vidioc_streamon(struct file *file, void *priv,1699 enum v4l2_buf_type type)1700{1701 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);1702 1703 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)1704 return vb2_streamon(&ctx->vq_src, type);1705 else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)1706 return vb2_streamon(&ctx->vq_dst, type);1707 return -EINVAL;1708}1709 1710/* Stream off, which equals to a pause */1711static int vidioc_streamoff(struct file *file, void *priv,1712 enum v4l2_buf_type type)1713{1714 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);1715 1716 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)1717 return vb2_streamoff(&ctx->vq_src, type);1718 else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)1719 return vb2_streamoff(&ctx->vq_dst, type);1720 return -EINVAL;1721}1722 1723static inline int h264_level(enum v4l2_mpeg_video_h264_level lvl)1724{1725 static unsigned int t[V4L2_MPEG_VIDEO_H264_LEVEL_4_0 + 1] = {1726 /* V4L2_MPEG_VIDEO_H264_LEVEL_1_0 */ 10,1727 /* V4L2_MPEG_VIDEO_H264_LEVEL_1B */ 9,1728 /* V4L2_MPEG_VIDEO_H264_LEVEL_1_1 */ 11,1729 /* V4L2_MPEG_VIDEO_H264_LEVEL_1_2 */ 12,1730 /* V4L2_MPEG_VIDEO_H264_LEVEL_1_3 */ 13,1731 /* V4L2_MPEG_VIDEO_H264_LEVEL_2_0 */ 20,1732 /* V4L2_MPEG_VIDEO_H264_LEVEL_2_1 */ 21,1733 /* V4L2_MPEG_VIDEO_H264_LEVEL_2_2 */ 22,1734 /* V4L2_MPEG_VIDEO_H264_LEVEL_3_0 */ 30,1735 /* V4L2_MPEG_VIDEO_H264_LEVEL_3_1 */ 31,1736 /* V4L2_MPEG_VIDEO_H264_LEVEL_3_2 */ 32,1737 /* V4L2_MPEG_VIDEO_H264_LEVEL_4_0 */ 40,1738 };1739 return t[lvl];1740}1741 1742static inline int mpeg4_level(enum v4l2_mpeg_video_mpeg4_level lvl)1743{1744 static unsigned int t[V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 + 1] = {1745 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 */ 0,1746 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B */ 9,1747 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 */ 1,1748 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 */ 2,1749 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 */ 3,1750 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B */ 7,1751 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 */ 4,1752 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 */ 5,1753 };1754 return t[lvl];1755}1756 1757static inline int hevc_level(enum v4l2_mpeg_video_hevc_level lvl)1758{1759 static unsigned int t[] = {1760 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_1 */ 10,1761 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_2 */ 20,1762 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 */ 21,1763 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_3 */ 30,1764 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 */ 31,1765 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_4 */ 40,1766 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 */ 41,1767 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5 */ 50,1768 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 */ 51,1769 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 */ 52,1770 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6 */ 60,1771 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 */ 61,1772 /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 */ 62,1773 };1774 return t[lvl];1775}1776 1777static inline int vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar)1778{1779 static unsigned int t[V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED + 1] = {1780 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED */ 0,1781 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 */ 1,1782 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 */ 2,1783 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 */ 3,1784 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 */ 4,1785 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 */ 5,1786 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 */ 6,1787 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 */ 7,1788 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 */ 8,1789 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 */ 9,1790 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 */ 10,1791 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 */ 11,1792 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 */ 12,1793 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 */ 13,1794 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 */ 14,1795 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 */ 15,1796 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 */ 16,1797 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED */ 255,1798 };1799 return t[sar];1800}1801 1802/*1803 * Update range of all HEVC quantization parameter controls that depend on the1804 * V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP controls.1805 */1806static void __enc_update_hevc_qp_ctrls_range(struct s5p_mfc_ctx *ctx,1807 int min, int max)1808{1809 static const int __hevc_qp_ctrls[] = {1810 V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,1811 V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP,1812 V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP,1813 V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP,1814 V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP,1815 V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP,1816 V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP,1817 V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP,1818 V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP,1819 V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP,1820 };1821 struct v4l2_ctrl *ctrl = NULL;1822 int i, j;1823 1824 for (i = 0; i < ARRAY_SIZE(__hevc_qp_ctrls); i++) {1825 for (j = 0; j < ARRAY_SIZE(ctx->ctrls); j++) {1826 if (ctx->ctrls[j]->id == __hevc_qp_ctrls[i]) {1827 ctrl = ctx->ctrls[j];1828 break;1829 }1830 }1831 if (WARN_ON(!ctrl))1832 break;1833 1834 __v4l2_ctrl_modify_range(ctrl, min, max, ctrl->step, min);1835 }1836}1837 1838static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)1839{1840 struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);1841 struct s5p_mfc_dev *dev = ctx->dev;1842 struct s5p_mfc_enc_params *p = &ctx->enc_params;1843 int ret = 0;1844 1845 switch (ctrl->id) {1846 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:1847 p->gop_size = ctrl->val;1848 break;1849 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:1850 p->slice_mode = ctrl->val;1851 break;1852 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:1853 p->slice_mb = ctrl->val;1854 break;1855 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:1856 p->slice_bit = ctrl->val * 8;1857 break;1858 case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:1859 p->intra_refresh_mb = ctrl->val;1860 break;1861 case V4L2_CID_MPEG_MFC51_VIDEO_PADDING:1862 p->pad = ctrl->val;1863 break;1864 case V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV:1865 p->pad_luma = (ctrl->val >> 16) & 0xff;1866 p->pad_cb = (ctrl->val >> 8) & 0xff;1867 p->pad_cr = (ctrl->val >> 0) & 0xff;1868 break;1869 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:1870 p->rc_frame = ctrl->val;1871 break;1872 case V4L2_CID_MPEG_VIDEO_BITRATE:1873 p->rc_bitrate = ctrl->val;1874 break;1875 case V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF:1876 p->rc_reaction_coeff = ctrl->val;1877 break;1878 case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:1879 ctx->force_frame_type = ctrl->val;1880 break;1881 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:1882 ctx->force_frame_type =1883 V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME;1884 break;1885 case V4L2_CID_MPEG_VIDEO_VBV_SIZE:1886 p->vbv_size = ctrl->val;1887 break;1888 case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:1889 p->mv_h_range = ctrl->val;1890 break;1891 case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:1892 p->mv_v_range = ctrl->val;1893 break;1894 case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:1895 p->codec.h264.cpb_size = ctrl->val;1896 break;1897 case V4L2_CID_MPEG_VIDEO_HEADER_MODE:1898 p->seq_hdr_mode = ctrl->val;1899 break;1900 case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE:1901 case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE:1902 p->frame_skip_mode = ctrl->val;1903 break;1904 case V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT:1905 p->fixed_target_bit = ctrl->val;1906 break;1907 case V4L2_CID_MPEG_VIDEO_B_FRAMES:1908 p->num_b_frame = ctrl->val;1909 break;1910 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:1911 switch (ctrl->val) {1912 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:1913 p->codec.h264.profile =1914 S5P_FIMV_ENC_PROFILE_H264_MAIN;1915 break;1916 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:1917 p->codec.h264.profile =1918 S5P_FIMV_ENC_PROFILE_H264_HIGH;1919 break;1920 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:1921 p->codec.h264.profile =1922 S5P_FIMV_ENC_PROFILE_H264_BASELINE;1923 break;1924 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:1925 if (IS_MFCV6_PLUS(dev))1926 p->codec.h264.profile =1927 S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE;1928 else1929 ret = -EINVAL;1930 break;1931 default:1932 ret = -EINVAL;1933 }1934 break;1935 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:1936 p->codec.h264.level_v4l2 = ctrl->val;1937 p->codec.h264.level = h264_level(ctrl->val);1938 if (p->codec.h264.level < 0) {1939 mfc_err("Level number is wrong\n");1940 ret = p->codec.h264.level;1941 }1942 break;1943 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:1944 p->codec.mpeg4.level_v4l2 = ctrl->val;1945 p->codec.mpeg4.level = mpeg4_level(ctrl->val);1946 if (p->codec.mpeg4.level < 0) {1947 mfc_err("Level number is wrong\n");1948 ret = p->codec.mpeg4.level;1949 }1950 break;1951 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:1952 p->codec.h264.loop_filter_mode = ctrl->val;1953 break;1954 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:1955 p->codec.h264.loop_filter_alpha = ctrl->val;1956 break;1957 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:1958 p->codec.h264.loop_filter_beta = ctrl->val;1959 break;1960 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:1961 p->codec.h264.entropy_mode = ctrl->val;1962 break;1963 case V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P:1964 p->codec.h264.num_ref_pic_4p = ctrl->val;1965 break;1966 case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:1967 p->codec.h264._8x8_transform = ctrl->val;1968 break;1969 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:1970 p->rc_mb = ctrl->val;1971 break;1972 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:1973 p->codec.h264.rc_frame_qp = ctrl->val;1974 break;1975 case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:1976 p->codec.h264.rc_min_qp = ctrl->val;1977 break;1978 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:1979 p->codec.h264.rc_max_qp = ctrl->val;1980 break;1981 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:1982 p->codec.h264.rc_p_frame_qp = ctrl->val;1983 break;1984 case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:1985 p->codec.h264.rc_b_frame_qp = ctrl->val;1986 break;1987 case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:1988 case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:1989 p->codec.mpeg4.rc_frame_qp = ctrl->val;1990 break;1991 case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:1992 case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:1993 p->codec.mpeg4.rc_min_qp = ctrl->val;1994 break;1995 case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:1996 case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:1997 p->codec.mpeg4.rc_max_qp = ctrl->val;1998 break;1999 case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:2000 case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:2001 p->codec.mpeg4.rc_p_frame_qp = ctrl->val;2002 break;2003 case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:2004 case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:2005 p->codec.mpeg4.rc_b_frame_qp = ctrl->val;2006 break;2007 case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK:2008 p->codec.h264.rc_mb_dark = ctrl->val;2009 break;2010 case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH:2011 p->codec.h264.rc_mb_smooth = ctrl->val;2012 break;2013 case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC:2014 p->codec.h264.rc_mb_static = ctrl->val;2015 break;2016 case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY:2017 p->codec.h264.rc_mb_activity = ctrl->val;2018 break;2019 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:2020 p->codec.h264.vui_sar = ctrl->val;2021 break;2022 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:2023 p->codec.h264.vui_sar_idc = vui_sar_idc(ctrl->val);2024 break;2025 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:2026 p->codec.h264.vui_ext_sar_width = ctrl->val;2027 break;2028 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:2029 p->codec.h264.vui_ext_sar_height = ctrl->val;2030 break;2031 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:2032 p->codec.h264.open_gop = !ctrl->val;2033 break;2034 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:2035 p->codec.h264.open_gop_size = ctrl->val;2036 break;2037 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:2038 switch (ctrl->val) {2039 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:2040 p->codec.mpeg4.profile =2041 S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE;2042 break;2043 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:2044 p->codec.mpeg4.profile =2045 S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE;2046 break;2047 default:2048 ret = -EINVAL;2049 }2050 break;2051 case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:2052 p->codec.mpeg4.quarter_pixel = ctrl->val;2053 break;2054 case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS:2055 p->codec.vp8.num_partitions = ctrl->val;2056 break;2057 case V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4:2058 p->codec.vp8.imd_4x4 = ctrl->val;2059 break;2060 case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES:2061 p->codec.vp8.num_ref = ctrl->val;2062 break;2063 case V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL:2064 p->codec.vp8.filter_level = ctrl->val;2065 break;2066 case V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS:2067 p->codec.vp8.filter_sharpness = ctrl->val;2068 break;2069 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD:2070 p->codec.vp8.golden_frame_ref_period = ctrl->val;2071 break;2072 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL:2073 p->codec.vp8.golden_frame_sel = ctrl->val;2074 break;2075 case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP:2076 p->codec.vp8.rc_min_qp = ctrl->val;2077 break;2078 case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP:2079 p->codec.vp8.rc_max_qp = ctrl->val;2080 break;2081 case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP:2082 p->codec.vp8.rc_frame_qp = ctrl->val;2083 break;2084 case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP:2085 p->codec.vp8.rc_p_frame_qp = ctrl->val;2086 break;2087 case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:2088 p->codec.vp8.profile = ctrl->val;2089 break;2090 case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:2091 p->codec.hevc.rc_frame_qp = ctrl->val;2092 break;2093 case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:2094 p->codec.hevc.rc_p_frame_qp = ctrl->val;2095 break;2096 case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:2097 p->codec.hevc.rc_b_frame_qp = ctrl->val;2098 break;2099 case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION:2100 p->codec.hevc.rc_framerate = ctrl->val;2101 break;2102 case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:2103 p->codec.hevc.rc_min_qp = ctrl->val;2104 __enc_update_hevc_qp_ctrls_range(ctx, ctrl->val,2105 p->codec.hevc.rc_max_qp);2106 break;2107 case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:2108 p->codec.hevc.rc_max_qp = ctrl->val;2109 __enc_update_hevc_qp_ctrls_range(ctx, p->codec.hevc.rc_min_qp,2110 ctrl->val);2111 break;2112 case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:2113 p->codec.hevc.level_v4l2 = ctrl->val;2114 p->codec.hevc.level = hevc_level(ctrl->val);2115 break;2116 case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:2117 switch (ctrl->val) {2118 case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN:2119 p->codec.hevc.profile =2120 V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN;2121 break;2122 case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE:2123 p->codec.hevc.profile =2124 V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE;2125 break;2126 default:2127 ret = -EINVAL;2128 }2129 break;2130 case V4L2_CID_MPEG_VIDEO_HEVC_TIER:2131 p->codec.hevc.tier = ctrl->val;2132 break;2133 case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH:2134 p->codec.hevc.max_partition_depth = ctrl->val;2135 break;2136 case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES:2137 p->codec.hevc.num_refs_for_p = ctrl->val;2138 break;2139 case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE:2140 p->codec.hevc.refreshtype = ctrl->val;2141 break;2142 case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED:2143 p->codec.hevc.const_intra_period_enable = ctrl->val;2144 break;2145 case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU:2146 p->codec.hevc.lossless_cu_enable = ctrl->val;2147 break;2148 case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT:2149 p->codec.hevc.wavefront_enable = ctrl->val;2150 break;2151 case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE:2152 p->codec.hevc.loopfilter = ctrl->val;2153 break;2154 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP:2155 p->codec.hevc.hier_qp_enable = ctrl->val;2156 break;2157 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:2158 p->codec.hevc.hier_qp_type = ctrl->val;2159 break;2160 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER:2161 p->codec.hevc.num_hier_layer = ctrl->val;2162 break;2163 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP:2164 p->codec.hevc.hier_qp_layer[0] = ctrl->val;2165 break;2166 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP:2167 p->codec.hevc.hier_qp_layer[1] = ctrl->val;2168 break;2169 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP:2170 p->codec.hevc.hier_qp_layer[2] = ctrl->val;2171 break;2172 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP:2173 p->codec.hevc.hier_qp_layer[3] = ctrl->val;2174 break;2175 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP:2176 p->codec.hevc.hier_qp_layer[4] = ctrl->val;2177 break;2178 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP:2179 p->codec.hevc.hier_qp_layer[5] = ctrl->val;2180 break;2181 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP:2182 p->codec.hevc.hier_qp_layer[6] = ctrl->val;2183 break;2184 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR:2185 p->codec.hevc.hier_bit_layer[0] = ctrl->val;2186 break;2187 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR:2188 p->codec.hevc.hier_bit_layer[1] = ctrl->val;2189 break;2190 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR:2191 p->codec.hevc.hier_bit_layer[2] = ctrl->val;2192 break;2193 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR:2194 p->codec.hevc.hier_bit_layer[3] = ctrl->val;2195 break;2196 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR:2197 p->codec.hevc.hier_bit_layer[4] = ctrl->val;2198 break;2199 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR:2200 p->codec.hevc.hier_bit_layer[5] = ctrl->val;2201 break;2202 case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR:2203 p->codec.hevc.hier_bit_layer[6] = ctrl->val;2204 break;2205 case V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB:2206 p->codec.hevc.general_pb_enable = ctrl->val;2207 break;2208 case V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID:2209 p->codec.hevc.temporal_id_enable = ctrl->val;2210 break;2211 case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING:2212 p->codec.hevc.strong_intra_smooth = ctrl->val;2213 break;2214 case V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT:2215 p->codec.hevc.intra_pu_split_disable = ctrl->val;2216 break;2217 case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION:2218 p->codec.hevc.tmv_prediction_disable = !ctrl->val;2219 break;2220 case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1:2221 p->codec.hevc.max_num_merge_mv = ctrl->val;2222 break;2223 case V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE:2224 p->codec.hevc.encoding_nostartcode_enable = ctrl->val;2225 break;2226 case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD:2227 p->codec.hevc.refreshperiod = ctrl->val;2228 break;2229 case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2:2230 p->codec.hevc.lf_beta_offset_div2 = ctrl->val;2231 break;2232 case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2:2233 p->codec.hevc.lf_tc_offset_div2 = ctrl->val;2234 break;2235 case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:2236 p->codec.hevc.size_of_length_field = ctrl->val;2237 break;2238 case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR:2239 p->codec.hevc.prepend_sps_pps_to_idr = ctrl->val;2240 break;2241 default:2242 v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n",2243 ctrl->id, ctrl->val);2244 ret = -EINVAL;2245 }2246 return ret;2247}2248 2249static int s5p_mfc_enc_g_v_ctrl(struct v4l2_ctrl *ctrl)2250{2251 struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);2252 struct s5p_mfc_dev *dev = ctx->dev;2253 2254 switch (ctrl->id) {2255 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:2256 if (ctx->state >= MFCINST_HEAD_PARSED &&2257 ctx->state < MFCINST_ABORT) {2258 ctrl->val = ctx->pb_count;2259 break;2260 } else if (ctx->state != MFCINST_INIT) {2261 v4l2_err(&dev->v4l2_dev, "Encoding not initialised\n");2262 return -EINVAL;2263 }2264 /* Should wait for the header to be produced */2265 s5p_mfc_wait_for_done_ctx(ctx,2266 S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0);2267 if (ctx->state >= MFCINST_HEAD_PARSED &&2268 ctx->state < MFCINST_ABORT) {2269 ctrl->val = ctx->pb_count;2270 } else {2271 v4l2_err(&dev->v4l2_dev, "Encoding not initialised\n");2272 return -EINVAL;2273 }2274 break;2275 }2276 return 0;2277}2278 2279static const struct v4l2_ctrl_ops s5p_mfc_enc_ctrl_ops = {2280 .s_ctrl = s5p_mfc_enc_s_ctrl,2281 .g_volatile_ctrl = s5p_mfc_enc_g_v_ctrl,2282};2283 2284static int vidioc_s_parm(struct file *file, void *priv,2285 struct v4l2_streamparm *a)2286{2287 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);2288 2289 if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {2290 ctx->enc_params.rc_framerate_num =2291 a->parm.output.timeperframe.denominator;2292 ctx->enc_params.rc_framerate_denom =2293 a->parm.output.timeperframe.numerator;2294 } else {2295 mfc_err("Setting FPS is only possible for the output queue\n");2296 return -EINVAL;2297 }2298 return 0;2299}2300 2301static int vidioc_g_parm(struct file *file, void *priv,2302 struct v4l2_streamparm *a)2303{2304 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);2305 2306 if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {2307 a->parm.output.timeperframe.denominator =2308 ctx->enc_params.rc_framerate_num;2309 a->parm.output.timeperframe.numerator =2310 ctx->enc_params.rc_framerate_denom;2311 } else {2312 mfc_err("Setting FPS is only possible for the output queue\n");2313 return -EINVAL;2314 }2315 return 0;2316}2317 2318static int vidioc_encoder_cmd(struct file *file, void *priv,2319 struct v4l2_encoder_cmd *cmd)2320{2321 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);2322 struct s5p_mfc_dev *dev = ctx->dev;2323 struct s5p_mfc_buf *buf;2324 unsigned long flags;2325 2326 switch (cmd->cmd) {2327 case V4L2_ENC_CMD_STOP:2328 if (cmd->flags != 0)2329 return -EINVAL;2330 2331 if (!ctx->vq_src.streaming)2332 return -EINVAL;2333 2334 spin_lock_irqsave(&dev->irqlock, flags);2335 if (list_empty(&ctx->src_queue)) {2336 mfc_debug(2, "EOS: empty src queue, entering finishing state\n");2337 ctx->state = MFCINST_FINISHING;2338 if (s5p_mfc_ctx_ready(ctx))2339 set_work_bit_irqsave(ctx);2340 spin_unlock_irqrestore(&dev->irqlock, flags);2341 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);2342 } else {2343 mfc_debug(2, "EOS: marking last buffer of stream\n");2344 buf = list_entry(ctx->src_queue.prev,2345 struct s5p_mfc_buf, list);2346 if (buf->flags & MFC_BUF_FLAG_USED)2347 ctx->state = MFCINST_FINISHING;2348 else2349 buf->flags |= MFC_BUF_FLAG_EOS;2350 spin_unlock_irqrestore(&dev->irqlock, flags);2351 }2352 break;2353 default:2354 return -EINVAL;2355 2356 }2357 return 0;2358}2359 2360static int vidioc_subscribe_event(struct v4l2_fh *fh,2361 const struct v4l2_event_subscription *sub)2362{2363 switch (sub->type) {2364 case V4L2_EVENT_EOS:2365 return v4l2_event_subscribe(fh, sub, 2, NULL);2366 default:2367 return -EINVAL;2368 }2369}2370 2371static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = {2372 .vidioc_querycap = vidioc_querycap,2373 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,2374 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,2375 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt,2376 .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt,2377 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt,2378 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt,2379 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt,2380 .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt,2381 .vidioc_reqbufs = vidioc_reqbufs,2382 .vidioc_querybuf = vidioc_querybuf,2383 .vidioc_qbuf = vidioc_qbuf,2384 .vidioc_dqbuf = vidioc_dqbuf,2385 .vidioc_expbuf = vidioc_expbuf,2386 .vidioc_streamon = vidioc_streamon,2387 .vidioc_streamoff = vidioc_streamoff,2388 .vidioc_s_parm = vidioc_s_parm,2389 .vidioc_g_parm = vidioc_g_parm,2390 .vidioc_encoder_cmd = vidioc_encoder_cmd,2391 .vidioc_subscribe_event = vidioc_subscribe_event,2392 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,2393};2394 2395static int check_vb_with_fmt(const struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)2396{2397 int i;2398 2399 if (!fmt)2400 return -EINVAL;2401 if (fmt->num_planes != vb->num_planes) {2402 mfc_err("invalid plane number for the format\n");2403 return -EINVAL;2404 }2405 for (i = 0; i < fmt->num_planes; i++) {2406 dma_addr_t dma = vb2_dma_contig_plane_dma_addr(vb, i);2407 if (!dma) {2408 mfc_err("failed to get plane cookie\n");2409 return -EINVAL;2410 }2411 mfc_debug(2, "index: %d, plane[%d] cookie: %pad\n",2412 vb->index, i, &dma);2413 }2414 return 0;2415}2416 2417static int s5p_mfc_queue_setup(struct vb2_queue *vq,2418 unsigned int *buf_count, unsigned int *plane_count,2419 unsigned int psize[], struct device *alloc_devs[])2420{2421 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);2422 struct s5p_mfc_dev *dev = ctx->dev;2423 2424 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {2425 if (ctx->state != MFCINST_GOT_INST) {2426 mfc_err("invalid state: %d\n", ctx->state);2427 return -EINVAL;2428 }2429 2430 if (ctx->dst_fmt)2431 *plane_count = ctx->dst_fmt->num_planes;2432 else2433 *plane_count = MFC_ENC_CAP_PLANE_COUNT;2434 if (*buf_count < 1)2435 *buf_count = 1;2436 if (*buf_count > MFC_MAX_BUFFERS)2437 *buf_count = MFC_MAX_BUFFERS;2438 psize[0] = ctx->enc_dst_buf_size;2439 alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];2440 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {2441 if (ctx->src_fmt)2442 *plane_count = ctx->src_fmt->num_planes;2443 else2444 *plane_count = MFC_ENC_OUT_PLANE_COUNT;2445 2446 if (*buf_count < 1)2447 *buf_count = 1;2448 if (*buf_count > MFC_MAX_BUFFERS)2449 *buf_count = MFC_MAX_BUFFERS;2450 2451 psize[0] = ctx->luma_size;2452 psize[1] = ctx->chroma_size;2453 if (ctx->src_fmt && (ctx->src_fmt->fourcc ==2454 V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc ==2455 V4L2_PIX_FMT_YVU420M))2456 psize[2] = ctx->chroma_size_1;2457 2458 if (IS_MFCV6_PLUS(dev)) {2459 alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];2460 alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];2461 if (ctx->src_fmt && (ctx->src_fmt->fourcc ==2462 V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc ==2463 V4L2_PIX_FMT_YVU420M))2464 alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];2465 } else {2466 alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];2467 alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];2468 }2469 } else {2470 mfc_err("invalid queue type: %d\n", vq->type);2471 return -EINVAL;2472 }2473 return 0;2474}2475 2476static int s5p_mfc_buf_init(struct vb2_buffer *vb)2477{2478 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);2479 struct vb2_queue *vq = vb->vb2_queue;2480 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);2481 unsigned int i;2482 int ret;2483 2484 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {2485 ret = check_vb_with_fmt(ctx->dst_fmt, vb);2486 if (ret < 0)2487 return ret;2488 i = vb->index;2489 ctx->dst_bufs[i].b = vbuf;2490 ctx->dst_bufs[i].cookie.stream =2491 vb2_dma_contig_plane_dma_addr(vb, 0);2492 ctx->dst_bufs_cnt++;2493 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {2494 ret = check_vb_with_fmt(ctx->src_fmt, vb);2495 if (ret < 0)2496 return ret;2497 i = vb->index;2498 ctx->src_bufs[i].b = vbuf;2499 ctx->src_bufs[i].cookie.raw.luma =2500 vb2_dma_contig_plane_dma_addr(vb, 0);2501 ctx->src_bufs[i].cookie.raw.chroma =2502 vb2_dma_contig_plane_dma_addr(vb, 1);2503 if (ctx->src_fmt->fourcc ==2504 V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc ==2505 V4L2_PIX_FMT_YVU420M)2506 ctx->src_bufs[i].cookie.raw.chroma_1 =2507 vb2_dma_contig_plane_dma_addr(vb, 2);2508 ctx->src_bufs_cnt++;2509 } else {2510 mfc_err("invalid queue type: %d\n", vq->type);2511 return -EINVAL;2512 }2513 return 0;2514}2515 2516static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)2517{2518 struct vb2_queue *vq = vb->vb2_queue;2519 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);2520 int ret;2521 2522 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {2523 ret = check_vb_with_fmt(ctx->dst_fmt, vb);2524 if (ret < 0)2525 return ret;2526 mfc_debug(2, "plane size: %ld, dst size: %zu\n",2527 vb2_plane_size(vb, 0), ctx->enc_dst_buf_size);2528 if (vb2_plane_size(vb, 0) < ctx->enc_dst_buf_size) {2529 mfc_err("plane size is too small for capture\n");2530 return -EINVAL;2531 }2532 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {2533 ret = check_vb_with_fmt(ctx->src_fmt, vb);2534 if (ret < 0)2535 return ret;2536 mfc_debug(2, "plane size: %ld, luma size: %d\n",2537 vb2_plane_size(vb, 0), ctx->luma_size);2538 mfc_debug(2, "plane size: %ld, chroma size: %d\n",2539 vb2_plane_size(vb, 1), ctx->chroma_size);2540 if (vb2_plane_size(vb, 0) < ctx->luma_size ||2541 vb2_plane_size(vb, 1) < ctx->chroma_size) {2542 mfc_err("plane size is too small for output\n");2543 return -EINVAL;2544 }2545 if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||2546 ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&2547 (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {2548 mfc_err("plane size is too small for output\n");2549 return -EINVAL;2550 }2551 } else {2552 mfc_err("invalid queue type: %d\n", vq->type);2553 return -EINVAL;2554 }2555 return 0;2556}2557 2558static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)2559{2560 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);2561 struct s5p_mfc_dev *dev = ctx->dev;2562 2563 if (IS_MFCV6_PLUS(dev) &&2564 (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) {2565 2566 if ((ctx->state == MFCINST_GOT_INST) &&2567 (dev->curr_ctx == ctx->num) && dev->hw_lock) {2568 s5p_mfc_wait_for_done_ctx(ctx,2569 S5P_MFC_R2H_CMD_SEQ_DONE_RET,2570 0);2571 }2572 if (q->memory != V4L2_MEMORY_DMABUF) {2573 if (ctx->src_bufs_cnt < ctx->pb_count) {2574 mfc_err("Need minimum %d OUTPUT buffers\n", ctx->pb_count);2575 return -ENOBUFS;2576 }2577 }2578 }2579 2580 /* If context is ready then dev = work->data;schedule it to run */2581 if (s5p_mfc_ctx_ready(ctx))2582 set_work_bit_irqsave(ctx);2583 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);2584 2585 return 0;2586}2587 2588static void s5p_mfc_stop_streaming(struct vb2_queue *q)2589{2590 unsigned long flags;2591 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);2592 struct s5p_mfc_dev *dev = ctx->dev;2593 2594 if ((ctx->state == MFCINST_FINISHING ||2595 ctx->state == MFCINST_RUNNING) &&2596 dev->curr_ctx == ctx->num && dev->hw_lock) {2597 ctx->state = MFCINST_ABORT;2598 s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_FRAME_DONE_RET,2599 0);2600 }2601 ctx->state = MFCINST_FINISHED;2602 spin_lock_irqsave(&dev->irqlock, flags);2603 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {2604 s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);2605 INIT_LIST_HEAD(&ctx->dst_queue);2606 ctx->dst_queue_cnt = 0;2607 }2608 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {2609 cleanup_ref_queue(ctx);2610 s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);2611 INIT_LIST_HEAD(&ctx->src_queue);2612 ctx->src_queue_cnt = 0;2613 }2614 spin_unlock_irqrestore(&dev->irqlock, flags);2615}2616 2617static void s5p_mfc_buf_queue(struct vb2_buffer *vb)2618{2619 struct vb2_queue *vq = vb->vb2_queue;2620 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);2621 struct s5p_mfc_dev *dev = ctx->dev;2622 unsigned long flags;2623 struct s5p_mfc_buf *mfc_buf;2624 2625 if (ctx->state == MFCINST_ERROR) {2626 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);2627 cleanup_ref_queue(ctx);2628 return;2629 }2630 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {2631 mfc_buf = &ctx->dst_bufs[vb->index];2632 mfc_buf->flags &= ~MFC_BUF_FLAG_USED;2633 /* Mark destination as available for use by MFC */2634 spin_lock_irqsave(&dev->irqlock, flags);2635 list_add_tail(&mfc_buf->list, &ctx->dst_queue);2636 ctx->dst_queue_cnt++;2637 spin_unlock_irqrestore(&dev->irqlock, flags);2638 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {2639 mfc_buf = &ctx->src_bufs[vb->index];2640 mfc_buf->flags &= ~MFC_BUF_FLAG_USED;2641 spin_lock_irqsave(&dev->irqlock, flags);2642 list_add_tail(&mfc_buf->list, &ctx->src_queue);2643 ctx->src_queue_cnt++;2644 spin_unlock_irqrestore(&dev->irqlock, flags);2645 } else {2646 mfc_err("unsupported buffer type (%d)\n", vq->type);2647 }2648 if (s5p_mfc_ctx_ready(ctx))2649 set_work_bit_irqsave(ctx);2650 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);2651}2652 2653static const struct vb2_ops s5p_mfc_enc_qops = {2654 .queue_setup = s5p_mfc_queue_setup,2655 .wait_prepare = vb2_ops_wait_prepare,2656 .wait_finish = vb2_ops_wait_finish,2657 .buf_init = s5p_mfc_buf_init,2658 .buf_prepare = s5p_mfc_buf_prepare,2659 .start_streaming = s5p_mfc_start_streaming,2660 .stop_streaming = s5p_mfc_stop_streaming,2661 .buf_queue = s5p_mfc_buf_queue,2662};2663 2664const struct s5p_mfc_codec_ops *get_enc_codec_ops(void)2665{2666 return &encoder_codec_ops;2667}2668 2669const struct vb2_ops *get_enc_queue_ops(void)2670{2671 return &s5p_mfc_enc_qops;2672}2673 2674const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void)2675{2676 return &s5p_mfc_enc_ioctl_ops;2677}2678 2679#define IS_MFC51_PRIV(x) ((V4L2_CTRL_ID2WHICH(x) == V4L2_CTRL_CLASS_CODEC) \2680 && V4L2_CTRL_DRIVER_PRIV(x))2681 2682int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx)2683{2684 struct v4l2_ctrl_config cfg;2685 int i;2686 2687 v4l2_ctrl_handler_init(&ctx->ctrl_handler, NUM_CTRLS);2688 if (ctx->ctrl_handler.error) {2689 mfc_err("v4l2_ctrl_handler_init failed\n");2690 return ctx->ctrl_handler.error;2691 }2692 for (i = 0; i < NUM_CTRLS; i++) {2693 if (IS_MFC51_PRIV(controls[i].id)) {2694 memset(&cfg, 0, sizeof(struct v4l2_ctrl_config));2695 cfg.ops = &s5p_mfc_enc_ctrl_ops;2696 cfg.id = controls[i].id;2697 cfg.min = controls[i].minimum;2698 cfg.max = controls[i].maximum;2699 cfg.def = controls[i].default_value;2700 cfg.name = controls[i].name;2701 cfg.type = controls[i].type;2702 cfg.flags = 0;2703 2704 if (cfg.type == V4L2_CTRL_TYPE_MENU) {2705 cfg.step = 0;2706 cfg.menu_skip_mask = controls[i].menu_skip_mask;2707 cfg.qmenu = mfc51_get_menu(cfg.id);2708 } else {2709 cfg.step = controls[i].step;2710 cfg.menu_skip_mask = 0;2711 }2712 ctx->ctrls[i] = v4l2_ctrl_new_custom(&ctx->ctrl_handler,2713 &cfg, NULL);2714 } else {2715 if ((controls[i].type == V4L2_CTRL_TYPE_MENU) ||2716 (controls[i].type ==2717 V4L2_CTRL_TYPE_INTEGER_MENU)) {2718 ctx->ctrls[i] = v4l2_ctrl_new_std_menu(2719 &ctx->ctrl_handler,2720 &s5p_mfc_enc_ctrl_ops, controls[i].id,2721 controls[i].maximum, 0,2722 controls[i].default_value);2723 } else {2724 ctx->ctrls[i] = v4l2_ctrl_new_std(2725 &ctx->ctrl_handler,2726 &s5p_mfc_enc_ctrl_ops, controls[i].id,2727 controls[i].minimum,2728 controls[i].maximum, controls[i].step,2729 controls[i].default_value);2730 }2731 }2732 if (ctx->ctrl_handler.error) {2733 mfc_err("Adding control (%d) failed\n", i);2734 return ctx->ctrl_handler.error;2735 }2736 if (controls[i].is_volatile && ctx->ctrls[i])2737 ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;2738 }2739 v4l2_ctrl_handler_setup(&ctx->ctrl_handler);2740 return 0;2741}2742 2743void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx)2744{2745 int i;2746 2747 v4l2_ctrl_handler_free(&ctx->ctrl_handler);2748 for (i = 0; i < NUM_CTRLS; i++)2749 ctx->ctrls[i] = NULL;2750}2751 2752void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx)2753{2754 struct v4l2_format f;2755 f.fmt.pix_mp.pixelformat = DEF_SRC_FMT_ENC;2756 ctx->src_fmt = find_format(&f, MFC_FMT_RAW);2757 f.fmt.pix_mp.pixelformat = DEF_DST_FMT_ENC;2758 ctx->dst_fmt = find_format(&f, MFC_FMT_ENC);2759}2760