1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <media/v4l2-event.h> 7 #include <media/v4l2-mem2mem.h> 8 9 #include "iris_buffer.h" 10 #include "iris_common.h" 11 #include "iris_ctrls.h" 12 #include "iris_instance.h" 13 #include "iris_power.h" 14 #include "iris_vdec.h" 15 #include "iris_vpu_buffer.h" 16 17 #define DEFAULT_CODEC_ALIGNMENT 16 18 19 int iris_vdec_inst_init(struct iris_inst *inst) 20 { 21 struct iris_core *core = inst->core; 22 struct v4l2_format *f; 23 24 inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL); 25 inst->fmt_dst = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL); 26 27 inst->fw_min_count = MIN_BUFFERS; 28 29 f = inst->fmt_src; 30 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 31 f->fmt.pix_mp.width = DEFAULT_WIDTH; 32 f->fmt.pix_mp.height = DEFAULT_HEIGHT; 33 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; 34 inst->codec = f->fmt.pix_mp.pixelformat; 35 f->fmt.pix_mp.num_planes = 1; 36 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 37 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 38 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 39 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 40 inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 41 42 f = inst->fmt_dst; 43 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 44 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 45 f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128); 46 f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32); 47 f->fmt.pix_mp.num_planes = 1; 48 f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128); 49 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 50 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 51 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; 52 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 53 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 54 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 55 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 56 inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 57 58 memcpy(&inst->fw_caps[0], &core->inst_fw_caps_dec[0], 59 INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap)); 60 61 return iris_ctrls_init(inst); 62 } 63 64 void iris_vdec_inst_deinit(struct iris_inst *inst) 65 { 66 kfree(inst->fmt_dst); 67 kfree(inst->fmt_src); 68 } 69 70 static const struct iris_fmt iris_vdec_formats[] = { 71 [IRIS_FMT_H264] = { 72 .pixfmt = V4L2_PIX_FMT_H264, 73 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 74 }, 75 [IRIS_FMT_HEVC] = { 76 .pixfmt = V4L2_PIX_FMT_HEVC, 77 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 78 }, 79 [IRIS_FMT_VP9] = { 80 .pixfmt = V4L2_PIX_FMT_VP9, 81 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 82 }, 83 }; 84 85 static const struct iris_fmt * 86 find_format(struct iris_inst *inst, u32 pixfmt, u32 type) 87 { 88 unsigned int size = ARRAY_SIZE(iris_vdec_formats); 89 const struct iris_fmt *fmt = iris_vdec_formats; 90 unsigned int i; 91 92 for (i = 0; i < size; i++) { 93 if (fmt[i].pixfmt == pixfmt) 94 break; 95 } 96 97 if (i == size || fmt[i].type != type) 98 return NULL; 99 100 return &fmt[i]; 101 } 102 103 static const struct iris_fmt * 104 find_format_by_index(struct iris_inst *inst, u32 index, u32 type) 105 { 106 const struct iris_fmt *fmt = iris_vdec_formats; 107 unsigned int size = ARRAY_SIZE(iris_vdec_formats); 108 109 if (index >= size || fmt[index].type != type) 110 return NULL; 111 112 return &fmt[index]; 113 } 114 115 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f) 116 { 117 const struct iris_fmt *fmt; 118 119 switch (f->type) { 120 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 121 fmt = find_format_by_index(inst, f->index, f->type); 122 if (!fmt) 123 return -EINVAL; 124 125 f->pixelformat = fmt->pixfmt; 126 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION; 127 break; 128 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 129 if (f->index) 130 return -EINVAL; 131 f->pixelformat = V4L2_PIX_FMT_NV12; 132 break; 133 default: 134 return -EINVAL; 135 } 136 137 return 0; 138 } 139 140 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) 141 { 142 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 143 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 144 const struct iris_fmt *fmt; 145 struct v4l2_format *f_inst; 146 struct vb2_queue *src_q; 147 148 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 149 fmt = find_format(inst, pixmp->pixelformat, f->type); 150 switch (f->type) { 151 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 152 if (!fmt) { 153 f_inst = inst->fmt_src; 154 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 155 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 156 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 157 } 158 break; 159 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 160 if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) { 161 f_inst = inst->fmt_dst; 162 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 163 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 164 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 165 } 166 167 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 168 if (vb2_is_streaming(src_q)) { 169 f_inst = inst->fmt_src; 170 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 171 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 172 } 173 break; 174 default: 175 return -EINVAL; 176 } 177 178 if (pixmp->field == V4L2_FIELD_ANY) 179 pixmp->field = V4L2_FIELD_NONE; 180 181 pixmp->num_planes = 1; 182 183 return 0; 184 } 185 186 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) 187 { 188 struct v4l2_format *fmt, *output_fmt; 189 struct vb2_queue *q; 190 u32 codec_align; 191 192 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); 193 if (!q) 194 return -EINVAL; 195 196 if (vb2_is_busy(q)) 197 return -EBUSY; 198 199 iris_vdec_try_fmt(inst, f); 200 201 switch (f->type) { 202 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 203 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) 204 return -EINVAL; 205 206 fmt = inst->fmt_src; 207 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 208 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 209 inst->codec = fmt->fmt.pix_mp.pixelformat; 210 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; 211 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align); 212 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align); 213 fmt->fmt.pix_mp.num_planes = 1; 214 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 215 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 216 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 217 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 218 219 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 220 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 221 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 222 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 223 224 output_fmt = inst->fmt_dst; 225 output_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 226 output_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 227 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 228 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 229 230 /* Update capture format based on new ip w/h */ 231 output_fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 232 output_fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 233 inst->buffers[BUF_OUTPUT].size = iris_get_buffer_size(inst, BUF_OUTPUT); 234 235 inst->crop.left = 0; 236 inst->crop.top = 0; 237 inst->crop.width = f->fmt.pix_mp.width; 238 inst->crop.height = f->fmt.pix_mp.height; 239 break; 240 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 241 fmt = inst->fmt_dst; 242 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 243 if (fmt->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) 244 return -EINVAL; 245 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 246 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 247 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 248 fmt->fmt.pix_mp.num_planes = 1; 249 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128); 250 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 251 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 252 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 253 254 inst->crop.top = 0; 255 inst->crop.left = 0; 256 inst->crop.width = f->fmt.pix_mp.width; 257 inst->crop.height = f->fmt.pix_mp.height; 258 break; 259 default: 260 return -EINVAL; 261 } 262 memcpy(f, fmt, sizeof(*fmt)); 263 264 return 0; 265 } 266 267 int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat) 268 { 269 const struct iris_fmt *fmt = NULL; 270 271 if (pixelformat != V4L2_PIX_FMT_NV12) { 272 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 273 if (!fmt) 274 return -EINVAL; 275 } 276 277 return 0; 278 } 279 280 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub) 281 { 282 int ret = 0; 283 284 switch (sub->type) { 285 case V4L2_EVENT_EOS: 286 ret = v4l2_event_subscribe(&inst->fh, sub, 0, NULL); 287 break; 288 case V4L2_EVENT_SOURCE_CHANGE: 289 ret = v4l2_src_change_event_subscribe(&inst->fh, sub); 290 break; 291 case V4L2_EVENT_CTRL: 292 ret = v4l2_ctrl_subscribe_event(&inst->fh, sub); 293 break; 294 default: 295 return -EINVAL; 296 } 297 298 return ret; 299 } 300 301 void iris_vdec_src_change(struct iris_inst *inst) 302 { 303 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 304 struct v4l2_event event = {0}; 305 struct vb2_queue *src_q; 306 307 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 308 if (!vb2_is_streaming(src_q)) 309 return; 310 311 event.type = V4L2_EVENT_SOURCE_CHANGE; 312 event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION; 313 v4l2_event_queue_fh(&inst->fh, &event); 314 } 315 316 int iris_vdec_streamon_input(struct iris_inst *inst) 317 { 318 int ret; 319 320 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 321 if (ret) 322 return ret; 323 324 ret = iris_alloc_and_queue_persist_bufs(inst, BUF_PERSIST); 325 if (ret) 326 return ret; 327 328 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 329 330 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 331 if (ret) 332 return ret; 333 334 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 335 if (ret) 336 return ret; 337 338 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 339 if (ret) 340 return ret; 341 342 return iris_process_streamon_input(inst); 343 } 344 345 int iris_vdec_streamon_output(struct iris_inst *inst) 346 { 347 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 348 int ret; 349 350 ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 351 if (ret) 352 return ret; 353 354 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 355 356 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 357 if (ret) 358 return ret; 359 360 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 361 if (ret) 362 return ret; 363 364 ret = iris_process_streamon_output(inst); 365 if (ret) 366 goto error; 367 368 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 369 if (ret) 370 goto error; 371 372 return ret; 373 374 error: 375 iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 376 377 return ret; 378 } 379 380 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) 381 { 382 struct iris_buffer *buf = to_iris_buffer(vbuf); 383 struct vb2_buffer *vb2 = &vbuf->vb2_buf; 384 struct vb2_queue *q; 385 int ret; 386 387 ret = iris_vb2_buffer_to_driver(vb2, buf); 388 if (ret) 389 return ret; 390 391 if (buf->type == BUF_INPUT) 392 iris_set_ts_metadata(inst, vbuf); 393 394 q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type); 395 if (!vb2_is_streaming(q)) { 396 buf->attr |= BUF_ATTR_DEFERRED; 397 return 0; 398 } 399 400 iris_scale_power(inst); 401 402 return iris_queue_buffer(inst, buf); 403 } 404 405 int iris_vdec_start_cmd(struct iris_inst *inst) 406 { 407 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 408 enum iris_inst_sub_state clear_sub_state = 0; 409 struct vb2_queue *dst_vq; 410 int ret; 411 412 dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 413 414 if (inst->sub_state & IRIS_INST_SUB_DRC && 415 inst->sub_state & IRIS_INST_SUB_DRC_LAST) { 416 vb2_clear_last_buffer_dequeued(dst_vq); 417 clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; 418 419 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 420 ret = hfi_ops->session_resume_drc(inst, 421 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 422 if (ret) 423 return ret; 424 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 425 } 426 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 427 ret = hfi_ops->session_resume_drc(inst, 428 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 429 if (ret) 430 return ret; 431 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 432 } 433 } else if (inst->sub_state & IRIS_INST_SUB_DRAIN && 434 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) { 435 vb2_clear_last_buffer_dequeued(dst_vq); 436 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; 437 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 438 if (hfi_ops->session_resume_drain) { 439 ret = 440 hfi_ops->session_resume_drain(inst, 441 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 442 if (ret) 443 return ret; 444 } 445 446 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 447 } 448 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 449 if (hfi_ops->session_resume_drain) { 450 ret = 451 hfi_ops->session_resume_drain(inst, 452 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 453 if (ret) 454 return ret; 455 } 456 457 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 458 } 459 } else { 460 dev_err(inst->core->dev, "start called before receiving last_flag\n"); 461 iris_inst_change_state(inst, IRIS_INST_ERROR); 462 return -EBUSY; 463 } 464 465 return iris_inst_change_sub_state(inst, clear_sub_state, 0); 466 } 467 468 int iris_vdec_stop_cmd(struct iris_inst *inst) 469 { 470 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 471 int ret; 472 473 ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 474 if (ret) 475 return ret; 476 477 return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN); 478 } 479