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 194 if (vb2_is_busy(q)) 195 return -EBUSY; 196 197 iris_vdec_try_fmt(inst, f); 198 199 switch (f->type) { 200 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 201 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) 202 return -EINVAL; 203 204 fmt = inst->fmt_src; 205 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 206 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 207 inst->codec = fmt->fmt.pix_mp.pixelformat; 208 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; 209 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align); 210 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align); 211 fmt->fmt.pix_mp.num_planes = 1; 212 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 213 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 214 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 215 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 216 217 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 218 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 219 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 220 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 221 222 output_fmt = inst->fmt_dst; 223 output_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 224 output_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 225 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 226 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 227 228 /* Update capture format based on new ip w/h */ 229 output_fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 230 output_fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 231 inst->buffers[BUF_OUTPUT].size = iris_get_buffer_size(inst, BUF_OUTPUT); 232 233 inst->crop.left = 0; 234 inst->crop.top = 0; 235 inst->crop.width = f->fmt.pix_mp.width; 236 inst->crop.height = f->fmt.pix_mp.height; 237 break; 238 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 239 fmt = inst->fmt_dst; 240 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 241 if (fmt->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) 242 return -EINVAL; 243 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 244 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 245 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 246 fmt->fmt.pix_mp.num_planes = 1; 247 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128); 248 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 249 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 250 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 251 252 inst->crop.top = 0; 253 inst->crop.left = 0; 254 inst->crop.width = f->fmt.pix_mp.width; 255 inst->crop.height = f->fmt.pix_mp.height; 256 break; 257 default: 258 return -EINVAL; 259 } 260 memcpy(f, fmt, sizeof(*fmt)); 261 262 return 0; 263 } 264 265 int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat) 266 { 267 const struct iris_fmt *fmt = NULL; 268 269 if (pixelformat != V4L2_PIX_FMT_NV12) { 270 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 271 if (!fmt) 272 return -EINVAL; 273 } 274 275 return 0; 276 } 277 278 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub) 279 { 280 int ret = 0; 281 282 switch (sub->type) { 283 case V4L2_EVENT_EOS: 284 ret = v4l2_event_subscribe(&inst->fh, sub, 0, NULL); 285 break; 286 case V4L2_EVENT_SOURCE_CHANGE: 287 ret = v4l2_src_change_event_subscribe(&inst->fh, sub); 288 break; 289 case V4L2_EVENT_CTRL: 290 ret = v4l2_ctrl_subscribe_event(&inst->fh, sub); 291 break; 292 default: 293 return -EINVAL; 294 } 295 296 return ret; 297 } 298 299 void iris_vdec_src_change(struct iris_inst *inst) 300 { 301 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 302 struct v4l2_event event = {0}; 303 struct vb2_queue *src_q; 304 305 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 306 if (!vb2_is_streaming(src_q)) 307 return; 308 309 event.type = V4L2_EVENT_SOURCE_CHANGE; 310 event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION; 311 v4l2_event_queue_fh(&inst->fh, &event); 312 } 313 314 int iris_vdec_streamon_input(struct iris_inst *inst) 315 { 316 int ret; 317 318 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 319 if (ret) 320 return ret; 321 322 ret = iris_alloc_and_queue_persist_bufs(inst, BUF_PERSIST); 323 if (ret) 324 return ret; 325 326 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 327 328 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 329 if (ret) 330 return ret; 331 332 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 333 if (ret) 334 return ret; 335 336 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 337 if (ret) 338 return ret; 339 340 return iris_process_streamon_input(inst); 341 } 342 343 int iris_vdec_streamon_output(struct iris_inst *inst) 344 { 345 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 346 int ret; 347 348 ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 349 if (ret) 350 return ret; 351 352 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 353 354 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 355 if (ret) 356 return ret; 357 358 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 359 if (ret) 360 return ret; 361 362 ret = iris_process_streamon_output(inst); 363 if (ret) 364 goto error; 365 366 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 367 if (ret) 368 goto error; 369 370 return ret; 371 372 error: 373 iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 374 375 return ret; 376 } 377 378 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) 379 { 380 struct iris_buffer *buf = to_iris_buffer(vbuf); 381 struct vb2_buffer *vb2 = &vbuf->vb2_buf; 382 struct vb2_queue *q; 383 int ret; 384 385 ret = iris_vb2_buffer_to_driver(vb2, buf); 386 if (ret) 387 return ret; 388 389 if (buf->type == BUF_INPUT) 390 iris_set_ts_metadata(inst, vbuf); 391 392 q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type); 393 if (!vb2_is_streaming(q)) { 394 buf->attr |= BUF_ATTR_DEFERRED; 395 return 0; 396 } 397 398 iris_scale_power(inst); 399 400 return iris_queue_buffer(inst, buf); 401 } 402 403 int iris_vdec_start_cmd(struct iris_inst *inst) 404 { 405 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 406 enum iris_inst_sub_state clear_sub_state = 0; 407 struct vb2_queue *dst_vq; 408 int ret; 409 410 dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 411 412 if (inst->sub_state & IRIS_INST_SUB_DRC && 413 inst->sub_state & IRIS_INST_SUB_DRC_LAST) { 414 vb2_clear_last_buffer_dequeued(dst_vq); 415 clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; 416 417 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 418 ret = hfi_ops->session_resume_drc(inst, 419 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 420 if (ret) 421 return ret; 422 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 423 } 424 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 425 ret = hfi_ops->session_resume_drc(inst, 426 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 427 if (ret) 428 return ret; 429 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 430 } 431 } else if (inst->sub_state & IRIS_INST_SUB_DRAIN && 432 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) { 433 vb2_clear_last_buffer_dequeued(dst_vq); 434 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; 435 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 436 if (hfi_ops->session_resume_drain) { 437 ret = 438 hfi_ops->session_resume_drain(inst, 439 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 440 if (ret) 441 return ret; 442 } 443 444 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 445 } 446 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 447 if (hfi_ops->session_resume_drain) { 448 ret = 449 hfi_ops->session_resume_drain(inst, 450 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 451 if (ret) 452 return ret; 453 } 454 455 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 456 } 457 } else { 458 dev_err(inst->core->dev, "start called before receiving last_flag\n"); 459 iris_inst_change_state(inst, IRIS_INST_ERROR); 460 return -EBUSY; 461 } 462 463 return iris_inst_change_sub_state(inst, clear_sub_state, 0); 464 } 465 466 int iris_vdec_stop_cmd(struct iris_inst *inst) 467 { 468 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 469 int ret; 470 471 ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 472 if (ret) 473 return ret; 474 475 return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN); 476 } 477