Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: iris: Add V4L2 streaming support for encoder video device

Add support for V4L2 streaming operations on the encoder video device.
During stream-on, configure mandatory properties on the respective
planes and notify the firmware to initiate an encode session.

Tested-by: Vikash Garodia <quic_vgarodia@quicinc.com> # X1E80100
Reviewed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # x1e80100-crd
[bod: add sm8750 enc/dec declarations during merge process]
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>

authored by

Dikshita Agarwal and committed by
Hans Verkuil
92e007ca 6bdfa3f9

+790 -410
+2 -2
drivers/media/platform/qcom/iris/Makefile
··· 1 - qcom-iris-objs += \ 2 - iris_buffer.o \ 1 + qcom-iris-objs += iris_buffer.o \ 2 + iris_common.o \ 3 3 iris_core.o \ 4 4 iris_ctrls.o \ 5 5 iris_firmware.o \
+196
drivers/media/platform/qcom/iris/iris_common.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #include <media/v4l2-mem2mem.h> 7 + 8 + #include "iris_common.h" 9 + #include "iris_ctrls.h" 10 + #include "iris_instance.h" 11 + #include "iris_power.h" 12 + 13 + int iris_process_streamon_input(struct iris_inst *inst) 14 + { 15 + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 16 + enum iris_inst_sub_state set_sub_state = 0; 17 + int ret; 18 + 19 + iris_scale_power(inst); 20 + 21 + ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 22 + if (ret) 23 + return ret; 24 + 25 + if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 26 + ret = iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0); 27 + if (ret) 28 + return ret; 29 + } 30 + 31 + if (inst->domain == DECODER && 32 + (inst->sub_state & IRIS_INST_SUB_DRC || 33 + inst->sub_state & IRIS_INST_SUB_DRAIN || 34 + inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)) { 35 + if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) { 36 + if (hfi_ops->session_pause) { 37 + ret = hfi_ops->session_pause(inst, 38 + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 39 + if (ret) 40 + return ret; 41 + } 42 + set_sub_state = IRIS_INST_SUB_INPUT_PAUSE; 43 + } 44 + } 45 + 46 + ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 47 + if (ret) 48 + return ret; 49 + 50 + inst->last_buffer_dequeued = false; 51 + 52 + return iris_inst_change_sub_state(inst, 0, set_sub_state); 53 + } 54 + 55 + int iris_process_streamon_output(struct iris_inst *inst) 56 + { 57 + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 58 + bool drain_active = false, drc_active = false; 59 + enum iris_inst_sub_state clear_sub_state = 0; 60 + int ret = 0; 61 + 62 + iris_scale_power(inst); 63 + 64 + drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN && 65 + inst->sub_state & IRIS_INST_SUB_DRAIN_LAST; 66 + 67 + drc_active = inst->sub_state & IRIS_INST_SUB_DRC && 68 + inst->sub_state & IRIS_INST_SUB_DRC_LAST; 69 + 70 + if (drc_active) 71 + clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; 72 + else if (drain_active) 73 + clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; 74 + 75 + if (inst->domain == DECODER && inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 76 + ret = iris_alloc_and_queue_input_int_bufs(inst); 77 + if (ret) 78 + return ret; 79 + ret = iris_set_stage(inst, STAGE); 80 + if (ret) 81 + return ret; 82 + ret = iris_set_pipe(inst, PIPE); 83 + if (ret) 84 + return ret; 85 + } 86 + 87 + if (inst->state == IRIS_INST_INPUT_STREAMING && 88 + inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 89 + if (!drain_active) 90 + ret = hfi_ops->session_resume_drc(inst, 91 + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 92 + else if (hfi_ops->session_resume_drain) 93 + ret = hfi_ops->session_resume_drain(inst, 94 + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 95 + if (ret) 96 + return ret; 97 + clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 98 + } 99 + 100 + if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) 101 + clear_sub_state |= IRIS_INST_SUB_FIRST_IPSC; 102 + 103 + ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 104 + if (ret) 105 + return ret; 106 + 107 + if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) 108 + clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 109 + 110 + ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 111 + if (ret) 112 + return ret; 113 + 114 + inst->last_buffer_dequeued = false; 115 + 116 + return iris_inst_change_sub_state(inst, clear_sub_state, 0); 117 + } 118 + 119 + static void iris_flush_deferred_buffers(struct iris_inst *inst, 120 + enum iris_buffer_type type) 121 + { 122 + struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 123 + struct v4l2_m2m_buffer *buffer, *n; 124 + struct iris_buffer *buf; 125 + 126 + if (type == BUF_INPUT) { 127 + v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { 128 + buf = to_iris_buffer(&buffer->vb); 129 + if (buf->attr & BUF_ATTR_DEFERRED) { 130 + if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { 131 + buf->attr |= BUF_ATTR_BUFFER_DONE; 132 + buf->data_size = 0; 133 + iris_vb2_buffer_done(inst, buf); 134 + } 135 + } 136 + } 137 + } else { 138 + v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) { 139 + buf = to_iris_buffer(&buffer->vb); 140 + if (buf->attr & BUF_ATTR_DEFERRED) { 141 + if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { 142 + buf->attr |= BUF_ATTR_BUFFER_DONE; 143 + buf->data_size = 0; 144 + iris_vb2_buffer_done(inst, buf); 145 + } 146 + } 147 + } 148 + } 149 + } 150 + 151 + static void iris_kill_session(struct iris_inst *inst) 152 + { 153 + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 154 + 155 + if (!inst->session_id) 156 + return; 157 + 158 + hfi_ops->session_close(inst); 159 + iris_inst_change_state(inst, IRIS_INST_ERROR); 160 + } 161 + 162 + int iris_session_streamoff(struct iris_inst *inst, u32 plane) 163 + { 164 + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 165 + enum iris_buffer_type buffer_type; 166 + int ret; 167 + 168 + switch (plane) { 169 + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 170 + buffer_type = BUF_INPUT; 171 + break; 172 + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 173 + buffer_type = BUF_OUTPUT; 174 + break; 175 + default: 176 + return -EINVAL; 177 + } 178 + 179 + ret = hfi_ops->session_stop(inst, plane); 180 + if (ret) 181 + goto error; 182 + 183 + ret = iris_inst_state_change_streamoff(inst, plane); 184 + if (ret) 185 + goto error; 186 + 187 + iris_flush_deferred_buffers(inst, buffer_type); 188 + 189 + return 0; 190 + 191 + error: 192 + iris_kill_session(inst); 193 + iris_flush_deferred_buffers(inst, buffer_type); 194 + 195 + return ret; 196 + }
+16
drivers/media/platform/qcom/iris/iris_common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef __IRIS_COMMON_H__ 7 + #define __IRIS_COMMON_H__ 8 + 9 + struct iris_inst; 10 + struct iris_buffer; 11 + 12 + int iris_process_streamon_input(struct iris_inst *inst); 13 + int iris_process_streamon_output(struct iris_inst *inst); 14 + int iris_session_streamoff(struct iris_inst *inst, u32 plane); 15 + 16 + #endif
+1 -1
drivers/media/platform/qcom/iris/iris_hfi_common.h
··· 102 102 103 103 struct iris_hfi_prop_type_handle { 104 104 u32 type; 105 - int (*handle)(struct iris_inst *inst); 105 + int (*handle)(struct iris_inst *inst, u32 plane); 106 106 }; 107 107 108 108 struct iris_hfi_command_ops {
+177 -80
drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
··· 189 189 u32 flush_type = 0; 190 190 int ret = 0; 191 191 192 - if (inst->state == IRIS_INST_STREAMING) { 193 - if (V4L2_TYPE_IS_OUTPUT(plane)) 194 - flush_type = HFI_FLUSH_ALL; 195 - else if (V4L2_TYPE_IS_CAPTURE(plane)) 196 - flush_type = HFI_FLUSH_OUTPUT; 192 + if (inst->domain == DECODER) { 193 + if (inst->state == IRIS_INST_STREAMING) { 194 + if (V4L2_TYPE_IS_OUTPUT(plane)) 195 + flush_type = HFI_FLUSH_ALL; 196 + else if (V4L2_TYPE_IS_CAPTURE(plane)) 197 + flush_type = HFI_FLUSH_OUTPUT; 197 198 198 - reinit_completion(&inst->flush_completion); 199 + reinit_completion(&inst->flush_completion); 199 200 200 - flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt); 201 - flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH; 202 - flush_pkt.shdr.session_id = inst->session_id; 203 - flush_pkt.flush_type = flush_type; 201 + flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt); 202 + flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH; 203 + flush_pkt.shdr.session_id = inst->session_id; 204 + flush_pkt.flush_type = flush_type; 204 205 205 - ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size); 206 - if (!ret) { 207 - inst->flush_responses_pending++; 208 - ret = iris_wait_for_session_response(inst, true); 206 + ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size); 207 + if (!ret) { 208 + inst->flush_responses_pending++; 209 + ret = iris_wait_for_session_response(inst, true); 210 + } 211 + } else if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES) { 212 + reinit_completion(&inst->completion); 213 + iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP); 214 + ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 215 + if (!ret) 216 + ret = iris_wait_for_session_response(inst, false); 217 + 218 + reinit_completion(&inst->completion); 219 + iris_hfi_gen1_packet_session_cmd(inst, &pkt, 220 + HFI_CMD_SESSION_RELEASE_RESOURCES); 221 + ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 222 + if (!ret) 223 + ret = iris_wait_for_session_response(inst, false); 224 + 225 + iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0); 226 + 227 + iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 228 + VB2_BUF_STATE_ERROR); 229 + iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 230 + VB2_BUF_STATE_ERROR); 209 231 } 210 - } else if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES) { 211 - reinit_completion(&inst->completion); 212 - iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP); 213 - ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 214 - if (!ret) 215 - ret = iris_wait_for_session_response(inst, false); 232 + } else { 233 + if (inst->state == IRIS_INST_STREAMING || 234 + inst->state == IRIS_INST_INPUT_STREAMING || 235 + inst->state == IRIS_INST_ERROR) { 236 + reinit_completion(&inst->completion); 237 + iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP); 238 + ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 239 + if (!ret) 240 + ret = iris_wait_for_session_response(inst, false); 216 241 217 - reinit_completion(&inst->completion); 218 - iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_RELEASE_RESOURCES); 219 - ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 220 - if (!ret) 221 - ret = iris_wait_for_session_response(inst, false); 242 + reinit_completion(&inst->completion); 243 + iris_hfi_gen1_packet_session_cmd(inst, &pkt, 244 + HFI_CMD_SESSION_RELEASE_RESOURCES); 245 + ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 246 + if (!ret) 247 + ret = iris_wait_for_session_response(inst, false); 222 248 223 - iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0); 249 + iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0); 250 + } 224 251 225 252 iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 226 253 VB2_BUF_STATE_ERROR); ··· 576 549 return hfi_gen1_set_property(inst, packet_type, payload, payload_size); 577 550 } 578 551 579 - static int iris_hfi_gen1_set_resolution(struct iris_inst *inst) 552 + static int iris_hfi_gen1_set_resolution(struct iris_inst *inst, u32 plane) 580 553 { 581 554 u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE; 582 555 struct hfi_framesize fs; ··· 591 564 if (ret) 592 565 return ret; 593 566 } 594 - fs.buffer_type = HFI_BUFFER_OUTPUT2; 567 + if (inst->domain == DECODER) 568 + fs.buffer_type = HFI_BUFFER_OUTPUT2; 569 + else 570 + fs.buffer_type = HFI_BUFFER_OUTPUT; 571 + 595 572 fs.width = inst->fmt_dst->fmt.pix_mp.width; 596 573 fs.height = inst->fmt_dst->fmt.pix_mp.height; 597 574 598 575 return hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); 599 576 } 600 577 601 - static int iris_hfi_gen1_decide_core(struct iris_inst *inst) 578 + static int iris_hfi_gen1_decide_core(struct iris_inst *inst, u32 plane) 602 579 { 603 580 const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE; 604 581 struct hfi_videocores_usage_type cu; ··· 612 581 return hfi_gen1_set_property(inst, ptype, &cu, sizeof(cu)); 613 582 } 614 583 615 - static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst) 584 + static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst, u32 plane) 616 585 { 617 586 const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT; 618 - u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 619 587 struct hfi_uncompressed_format_select fmt; 588 + u32 pixelformat; 620 589 int ret; 621 590 622 - if (iris_split_mode_enabled(inst)) { 623 - fmt.buffer_type = HFI_BUFFER_OUTPUT; 624 - fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12_UBWC : 0; 591 + if (inst->domain == DECODER) { 592 + pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 593 + if (iris_split_mode_enabled(inst)) { 594 + fmt.buffer_type = HFI_BUFFER_OUTPUT; 595 + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? 596 + HFI_COLOR_FORMAT_NV12_UBWC : 0; 625 597 626 - ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 627 - if (ret) 628 - return ret; 598 + ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 599 + if (ret) 600 + return ret; 629 601 630 - fmt.buffer_type = HFI_BUFFER_OUTPUT2; 631 - fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; 602 + fmt.buffer_type = HFI_BUFFER_OUTPUT2; 603 + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; 632 604 633 - ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 605 + ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 606 + } else { 607 + fmt.buffer_type = HFI_BUFFER_OUTPUT; 608 + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; 609 + 610 + ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 611 + } 634 612 } else { 635 - fmt.buffer_type = HFI_BUFFER_OUTPUT; 613 + pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat; 614 + fmt.buffer_type = HFI_BUFFER_INPUT; 636 615 fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; 637 - 638 616 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 639 617 } 640 618 641 619 return ret; 642 620 } 643 621 644 - static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst) 622 + static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst, u32 plane) 645 623 { 646 624 const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO; 647 625 struct hfi_uncompressed_plane_actual_constraints_info pconstraint; ··· 670 630 return hfi_gen1_set_property(inst, ptype, &pconstraint, sizeof(pconstraint)); 671 631 } 672 632 673 - static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst) 633 + static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst, u32 plane) 674 634 { 675 635 u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL; 676 636 struct hfi_buffer_count_actual buf_count; ··· 684 644 if (ret) 685 645 return ret; 686 646 687 - if (iris_split_mode_enabled(inst)) { 688 - buf_count.type = HFI_BUFFER_OUTPUT; 689 - buf_count.count_actual = VIDEO_MAX_FRAME; 690 - buf_count.count_min_host = VIDEO_MAX_FRAME; 647 + if (inst->domain == DECODER) { 648 + if (iris_split_mode_enabled(inst)) { 649 + buf_count.type = HFI_BUFFER_OUTPUT; 650 + buf_count.count_actual = VIDEO_MAX_FRAME; 651 + buf_count.count_min_host = VIDEO_MAX_FRAME; 691 652 692 - ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 693 - if (ret) 694 - return ret; 653 + ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 654 + if (ret) 655 + return ret; 695 656 696 - buf_count.type = HFI_BUFFER_OUTPUT2; 697 - buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB); 698 - buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB); 657 + buf_count.type = HFI_BUFFER_OUTPUT2; 658 + buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB); 659 + buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB); 699 660 700 - ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 661 + ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 662 + } else { 663 + buf_count.type = HFI_BUFFER_OUTPUT; 664 + buf_count.count_actual = VIDEO_MAX_FRAME; 665 + buf_count.count_min_host = VIDEO_MAX_FRAME; 666 + 667 + ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 668 + } 701 669 } else { 702 670 buf_count.type = HFI_BUFFER_OUTPUT; 703 671 buf_count.count_actual = VIDEO_MAX_FRAME; ··· 717 669 return ret; 718 670 } 719 671 720 - static int iris_hfi_gen1_set_multistream(struct iris_inst *inst) 672 + static int iris_hfi_gen1_set_multistream(struct iris_inst *inst, u32 plane) 721 673 { 722 674 u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM; 723 675 struct hfi_multi_stream multi = {0}; ··· 752 704 return ret; 753 705 } 754 706 755 - static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst) 707 + static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst, u32 plane) 756 708 { 757 709 const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL; 758 710 struct hfi_buffer_size_actual bufsz; ··· 787 739 return ret; 788 740 } 789 741 742 + static int iris_hfi_gen1_set_frame_rate(struct iris_inst *inst, u32 plane) 743 + { 744 + const u32 ptype = HFI_PROPERTY_CONFIG_FRAME_RATE; 745 + struct hfi_framerate frate; 746 + 747 + if (V4L2_TYPE_IS_OUTPUT(plane)) 748 + return 0; 749 + 750 + frate.buffer_type = HFI_BUFFER_OUTPUT; 751 + frate.framerate = inst->frame_rate << 16; 752 + 753 + return hfi_gen1_set_property(inst, ptype, &frate, sizeof(frate)); 754 + } 755 + 756 + static int iris_hfi_gen1_set_stride(struct iris_inst *inst, u32 plane) 757 + { 758 + const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO; 759 + struct hfi_uncompressed_plane_actual_info plane_actual_info; 760 + 761 + plane_actual_info.buffer_type = HFI_BUFFER_INPUT; 762 + plane_actual_info.num_planes = 2; 763 + plane_actual_info.plane_format[0].actual_stride = 764 + ALIGN(inst->fmt_src->fmt.pix_mp.width, 128); 765 + plane_actual_info.plane_format[0].actual_plane_buffer_height = 766 + ALIGN(inst->fmt_src->fmt.pix_mp.height, 32); 767 + plane_actual_info.plane_format[1].actual_stride = 768 + ALIGN(inst->fmt_src->fmt.pix_mp.width, 128); 769 + plane_actual_info.plane_format[1].actual_plane_buffer_height = 770 + (ALIGN(inst->fmt_src->fmt.pix_mp.height, 32)) / 2; 771 + 772 + return hfi_gen1_set_property(inst, ptype, &plane_actual_info, sizeof(plane_actual_info)); 773 + } 774 + 790 775 static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 plane) 791 776 { 777 + struct iris_hfi_prop_type_handle const *handler = NULL; 778 + u32 handler_size = 0; 792 779 struct iris_core *core = inst->core; 793 780 u32 config_params_size, i, j; 794 781 const u32 *config_params; 795 782 int ret; 796 783 797 - static const struct iris_hfi_prop_type_handle prop_type_handle_inp_arr[] = { 784 + static const struct iris_hfi_prop_type_handle vdec_prop_type_handle_inp_arr[] = { 798 785 {HFI_PROPERTY_PARAM_FRAME_SIZE, 799 786 iris_hfi_gen1_set_resolution}, 800 787 {HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE, ··· 846 763 iris_hfi_gen1_set_bufsize}, 847 764 }; 848 765 849 - static const struct iris_hfi_prop_type_handle prop_type_handle_out_arr[] = { 766 + static const struct iris_hfi_prop_type_handle vdec_prop_type_handle_out_arr[] = { 850 767 {HFI_PROPERTY_PARAM_FRAME_SIZE, 851 768 iris_hfi_gen1_set_resolution}, 852 769 {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, ··· 861 778 iris_hfi_gen1_set_bufsize}, 862 779 }; 863 780 864 - config_params = core->iris_platform_data->input_config_params_default; 865 - config_params_size = core->iris_platform_data->input_config_params_default_size; 781 + static const struct iris_hfi_prop_type_handle venc_prop_type_handle_inp_arr[] = { 782 + {HFI_PROPERTY_CONFIG_FRAME_RATE, 783 + iris_hfi_gen1_set_frame_rate}, 784 + {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO, 785 + iris_hfi_gen1_set_stride}, 786 + {HFI_PROPERTY_PARAM_FRAME_SIZE, 787 + iris_hfi_gen1_set_resolution}, 788 + {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, 789 + iris_hfi_gen1_set_raw_format}, 790 + {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, 791 + iris_hfi_gen1_set_num_bufs}, 792 + }; 866 793 867 - if (V4L2_TYPE_IS_OUTPUT(plane)) { 868 - for (i = 0; i < config_params_size; i++) { 869 - for (j = 0; j < ARRAY_SIZE(prop_type_handle_inp_arr); j++) { 870 - if (prop_type_handle_inp_arr[j].type == config_params[i]) { 871 - ret = prop_type_handle_inp_arr[j].handle(inst); 872 - if (ret) 873 - return ret; 874 - break; 875 - } 876 - } 794 + if (inst->domain == DECODER) { 795 + config_params = core->iris_platform_data->dec_input_config_params_default; 796 + config_params_size = core->iris_platform_data->dec_input_config_params_default_size; 797 + if (V4L2_TYPE_IS_OUTPUT(plane)) { 798 + handler = vdec_prop_type_handle_inp_arr; 799 + handler_size = ARRAY_SIZE(vdec_prop_type_handle_inp_arr); 800 + } else if (V4L2_TYPE_IS_CAPTURE(plane)) { 801 + handler = vdec_prop_type_handle_out_arr; 802 + handler_size = ARRAY_SIZE(vdec_prop_type_handle_out_arr); 877 803 } 878 - } else if (V4L2_TYPE_IS_CAPTURE(plane)) { 879 - for (i = 0; i < config_params_size; i++) { 880 - for (j = 0; j < ARRAY_SIZE(prop_type_handle_out_arr); j++) { 881 - if (prop_type_handle_out_arr[j].type == config_params[i]) { 882 - ret = prop_type_handle_out_arr[j].handle(inst); 883 - if (ret) 884 - return ret; 885 - break; 886 - } 804 + } else { 805 + config_params = core->iris_platform_data->enc_input_config_params; 806 + config_params_size = core->iris_platform_data->enc_input_config_params_size; 807 + handler = venc_prop_type_handle_inp_arr; 808 + handler_size = ARRAY_SIZE(venc_prop_type_handle_inp_arr); 809 + } 810 + 811 + for (i = 0; i < config_params_size; i++) { 812 + for (j = 0; j < handler_size; j++) { 813 + if (handler[j].type == config_params[i]) { 814 + ret = handler[j].handle(inst, plane); 815 + if (ret) 816 + return ret; 817 + break; 887 818 } 888 819 } 889 820 }
+18
drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
··· 82 82 #define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6 83 83 84 84 #define HFI_PROPERTY_PARAM_FRAME_SIZE 0x1001 85 + #define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO 0x1002 85 86 #define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT 0x1003 86 87 #define HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT 0x1005 87 88 #define HFI_PROPERTY_PARAM_WORK_MODE 0x1015 88 89 #define HFI_PROPERTY_PARAM_WORK_ROUTE 0x1017 90 + #define HFI_PROPERTY_CONFIG_FRAME_RATE 0x2001 89 91 #define HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE 0x2002 90 92 91 93 #define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM 0x1003001 ··· 350 348 struct hfi_uncompressed_plane_constraints plane_format[2]; 351 349 }; 352 350 351 + struct hfi_uncompressed_plane_actual { 352 + int actual_stride; 353 + u32 actual_plane_buffer_height; 354 + }; 355 + 356 + struct hfi_uncompressed_plane_actual_info { 357 + u32 buffer_type; 358 + u32 num_planes; 359 + struct hfi_uncompressed_plane_actual plane_format[2]; 360 + }; 361 + 353 362 struct hfi_buffer_count_actual { 354 363 u32 type; 355 364 u32 count_actual; ··· 386 373 u32 count_actual; 387 374 u32 contiguous; 388 375 u32 alignment; 376 + }; 377 + 378 + struct hfi_framerate { 379 + u32 buffer_type; 380 + u32 framerate; 389 381 }; 390 382 391 383 struct hfi_event_data {
+191 -89
drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
··· 88 88 return ret; 89 89 } 90 90 91 - static u32 iris_hfi_gen2_get_port(u32 plane) 91 + static u32 iris_hfi_gen2_get_port(struct iris_inst *inst, u32 plane) 92 92 { 93 - switch (plane) { 94 - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 95 - return HFI_PORT_BITSTREAM; 96 - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 97 - return HFI_PORT_RAW; 98 - default: 99 - return HFI_PORT_NONE; 93 + if (inst->domain == DECODER) { 94 + switch (plane) { 95 + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 96 + return HFI_PORT_BITSTREAM; 97 + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 98 + return HFI_PORT_RAW; 99 + default: 100 + return HFI_PORT_NONE; 101 + } 102 + } else { 103 + switch (plane) { 104 + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 105 + return HFI_PORT_RAW; 106 + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 107 + return HFI_PORT_BITSTREAM; 108 + default: 109 + return HFI_PORT_NONE; 110 + } 100 111 } 101 112 } 102 113 ··· 147 136 inst_hfi_gen2->packet->size); 148 137 } 149 138 150 - static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst) 139 + static int iris_hfi_gen2_set_raw_resolution(struct iris_inst *inst, u32 plane) 151 140 { 152 - struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 153 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 154 141 u32 resolution = inst->fmt_src->fmt.pix_mp.width << 16 | 155 142 inst->fmt_src->fmt.pix_mp.height; 143 + u32 port = iris_hfi_gen2_get_port(inst, plane); 156 144 157 - inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution; 145 + return iris_hfi_gen2_session_set_property(inst, 146 + HFI_PROP_RAW_RESOLUTION, 147 + HFI_HOST_FLAGS_NONE, 148 + port, 149 + HFI_PAYLOAD_32_PACKED, 150 + &resolution, 151 + sizeof(u32)); 152 + } 153 + 154 + static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst, u32 plane) 155 + { 156 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 157 + u32 port = iris_hfi_gen2_get_port(inst, plane); 158 + enum hfi_packet_payload_info payload_type; 159 + u32 resolution, codec_align; 160 + 161 + if (inst->domain == DECODER) { 162 + resolution = inst->fmt_src->fmt.pix_mp.width << 16 | 163 + inst->fmt_src->fmt.pix_mp.height; 164 + inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution; 165 + payload_type = HFI_PAYLOAD_U32; 166 + } else { 167 + codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; 168 + resolution = ALIGN(inst->fmt_dst->fmt.pix_mp.width, codec_align) << 16 | 169 + ALIGN(inst->fmt_dst->fmt.pix_mp.height, codec_align); 170 + inst_hfi_gen2->dst_subcr_params.bitstream_resolution = resolution; 171 + payload_type = HFI_PAYLOAD_32_PACKED; 172 + } 158 173 159 174 return iris_hfi_gen2_session_set_property(inst, 160 175 HFI_PROP_BITSTREAM_RESOLUTION, 161 176 HFI_HOST_FLAGS_NONE, 162 177 port, 163 - HFI_PAYLOAD_U32, 178 + payload_type, 164 179 &resolution, 165 180 sizeof(u32)); 166 181 } 167 182 168 - static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst) 183 + static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst, u32 plane) 169 184 { 170 - u32 bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height); 171 - u32 right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width); 172 185 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 173 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 174 - u32 left_offset = inst->crop.left; 175 - u32 top_offset = inst->crop.top; 186 + u32 port = iris_hfi_gen2_get_port(inst, plane); 187 + u32 bottom_offset, right_offset; 188 + u32 left_offset, top_offset; 176 189 u32 payload[2]; 190 + 191 + if (inst->domain == DECODER) { 192 + if (V4L2_TYPE_IS_OUTPUT(plane)) { 193 + bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height); 194 + right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width); 195 + left_offset = inst->crop.left; 196 + top_offset = inst->crop.top; 197 + } else { 198 + bottom_offset = (inst->fmt_dst->fmt.pix_mp.height - inst->compose.height); 199 + right_offset = (inst->fmt_dst->fmt.pix_mp.width - inst->compose.width); 200 + left_offset = inst->compose.left; 201 + top_offset = inst->compose.top; 202 + } 203 + } else { 204 + bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height); 205 + right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width); 206 + left_offset = inst->crop.left; 207 + top_offset = inst->crop.top; 208 + } 177 209 178 210 payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset; 179 211 payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset; ··· 232 178 sizeof(u64)); 233 179 } 234 180 235 - static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst) 181 + static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst, u32 plane) 236 182 { 237 183 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 238 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 184 + u32 port = iris_hfi_gen2_get_port(inst, plane); 239 185 u32 bitdepth = BIT_DEPTH_8; 240 186 241 187 inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth; ··· 249 195 sizeof(u32)); 250 196 } 251 197 252 - static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst) 198 + static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst, u32 plane) 253 199 { 254 200 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 255 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 201 + u32 port = iris_hfi_gen2_get_port(inst, plane); 256 202 u32 coded_frames = 0; 257 203 258 204 if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE) ··· 268 214 sizeof(u32)); 269 215 } 270 216 271 - static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst) 217 + static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst, u32 plane) 272 218 { 273 219 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 274 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 275 220 u32 min_output = inst->buffers[BUF_OUTPUT].min_count; 221 + u32 port = iris_hfi_gen2_get_port(inst, plane); 276 222 277 223 inst_hfi_gen2->src_subcr_params.fw_min_count = min_output; 278 224 ··· 285 231 sizeof(u32)); 286 232 } 287 233 288 - static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst) 234 + static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst, u32 plane) 289 235 { 290 236 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 291 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 237 + u32 port = iris_hfi_gen2_get_port(inst, plane); 292 238 u32 poc = 0; 293 239 294 240 inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc; ··· 302 248 sizeof(u32)); 303 249 } 304 250 305 - static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst) 251 + static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst, u32 plane) 306 252 { 307 253 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 308 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 309 254 struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp; 310 255 u32 video_signal_type_present_flag = 0, color_info; 311 256 u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED; 312 257 u32 video_format = UNSPECIFIED_COLOR_FORMAT; 313 258 u32 full_range = V4L2_QUANTIZATION_DEFAULT; 314 259 u32 transfer_char = HFI_TRANSFER_RESERVED; 260 + u32 port = iris_hfi_gen2_get_port(inst, plane); 315 261 u32 colour_description_present_flag = 0; 316 262 u32 primaries = HFI_PRIMARIES_RESERVED; 317 263 ··· 345 291 sizeof(u32)); 346 292 } 347 293 348 - static int iris_hfi_gen2_set_profile(struct iris_inst *inst) 294 + static int iris_hfi_gen2_set_profile(struct iris_inst *inst, u32 plane) 349 295 { 350 296 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 351 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 297 + u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 352 298 u32 profile = 0; 353 299 354 300 switch (inst->codec) { ··· 374 320 sizeof(u32)); 375 321 } 376 322 377 - static int iris_hfi_gen2_set_level(struct iris_inst *inst) 323 + static int iris_hfi_gen2_set_level(struct iris_inst *inst, u32 plane) 378 324 { 379 325 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 380 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 326 + u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 381 327 u32 level = 0; 382 328 383 329 switch (inst->codec) { ··· 403 349 sizeof(u32)); 404 350 } 405 351 406 - static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst) 352 + static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane) 407 353 { 408 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 354 + u32 port = iris_hfi_gen2_get_port(inst, plane); 409 355 u32 hfi_colorformat, pixelformat; 410 356 411 - pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 412 - hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0; 357 + if (inst->domain == DECODER) { 358 + pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 359 + hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0; 360 + } else { 361 + pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat; 362 + hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0; 363 + } 413 364 414 365 return iris_hfi_gen2_session_set_property(inst, 415 366 HFI_PROP_COLOR_FORMAT, 416 367 HFI_HOST_FLAGS_NONE, 417 368 port, 418 - HFI_PAYLOAD_U32, 369 + HFI_PAYLOAD_U32_ENUM, 419 370 &hfi_colorformat, 420 371 sizeof(u32)); 421 372 } 422 373 423 - static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst) 374 + static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst, u32 plane) 424 375 { 425 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 426 - u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 427 - u32 scanline_y = inst->fmt_dst->fmt.pix_mp.height; 428 - u32 stride_y = inst->fmt_dst->fmt.pix_mp.width; 429 - u32 scanline_uv = scanline_y / 2; 430 - u32 stride_uv = stride_y; 376 + u32 pixelformat, stride_y, stride_uv, scanline_y, scanline_uv; 377 + u32 port = iris_hfi_gen2_get_port(inst, plane); 431 378 u32 payload[2]; 379 + 380 + if (inst->domain == DECODER) { 381 + pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 382 + stride_y = inst->fmt_dst->fmt.pix_mp.width; 383 + scanline_y = inst->fmt_dst->fmt.pix_mp.height; 384 + } else { 385 + pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat; 386 + stride_y = ALIGN(inst->fmt_src->fmt.pix_mp.width, 128); 387 + scanline_y = ALIGN(inst->fmt_src->fmt.pix_mp.height, 32); 388 + } 389 + 390 + stride_uv = stride_y; 391 + scanline_uv = scanline_y / 2; 432 392 433 393 if (pixelformat != V4L2_PIX_FMT_NV12) 434 394 return 0; ··· 454 386 HFI_PROP_LINEAR_STRIDE_SCANLINE, 455 387 HFI_HOST_FLAGS_NONE, 456 388 port, 457 - HFI_PAYLOAD_U64, 389 + HFI_PAYLOAD_64_PACKED, 458 390 &payload, 459 391 sizeof(u64)); 460 392 } 461 393 462 - static int iris_hfi_gen2_set_tier(struct iris_inst *inst) 394 + static int iris_hfi_gen2_set_tier(struct iris_inst *inst, u32 plane) 463 395 { 464 396 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 465 - u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 397 + u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 466 398 u32 tier = inst->fw_caps[TIER].value; 467 399 468 400 inst_hfi_gen2->src_subcr_params.tier = tier; ··· 476 408 sizeof(u32)); 477 409 } 478 410 411 + static int iris_hfi_gen2_set_frame_rate(struct iris_inst *inst, u32 plane) 412 + { 413 + u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 414 + u32 frame_rate = inst->frame_rate << 16; 415 + 416 + return iris_hfi_gen2_session_set_property(inst, 417 + HFI_PROP_FRAME_RATE, 418 + HFI_HOST_FLAGS_NONE, 419 + port, 420 + HFI_PAYLOAD_Q16, 421 + &frame_rate, 422 + sizeof(u32)); 423 + } 424 + 479 425 static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane) 480 426 { 481 - struct iris_core *core = inst->core; 427 + const struct iris_platform_data *pdata = inst->core->iris_platform_data; 482 428 u32 config_params_size = 0, i, j; 483 429 const u32 *config_params = NULL; 484 430 int ret; 485 431 486 432 static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = { 433 + {HFI_PROP_RAW_RESOLUTION, iris_hfi_gen2_set_raw_resolution }, 487 434 {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution }, 488 435 {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets }, 489 436 {HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames }, ··· 511 428 {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat }, 512 429 {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline }, 513 430 {HFI_PROP_TIER, iris_hfi_gen2_set_tier }, 431 + {HFI_PROP_FRAME_RATE, iris_hfi_gen2_set_frame_rate }, 514 432 }; 515 433 516 - if (V4L2_TYPE_IS_OUTPUT(plane)) { 517 - switch (inst->codec) { 518 - case V4L2_PIX_FMT_H264: 519 - config_params = core->iris_platform_data->input_config_params_default; 520 - config_params_size = 521 - core->iris_platform_data->input_config_params_default_size; 522 - break; 523 - case V4L2_PIX_FMT_HEVC: 524 - config_params = core->iris_platform_data->input_config_params_hevc; 525 - config_params_size = 526 - core->iris_platform_data->input_config_params_hevc_size; 527 - break; 528 - case V4L2_PIX_FMT_VP9: 529 - config_params = core->iris_platform_data->input_config_params_vp9; 530 - config_params_size = 531 - core->iris_platform_data->input_config_params_vp9_size; 532 - break; 434 + if (inst->domain == DECODER) { 435 + if (V4L2_TYPE_IS_OUTPUT(plane)) { 436 + if (inst->codec == V4L2_PIX_FMT_H264) { 437 + config_params = pdata->dec_input_config_params_default; 438 + config_params_size = pdata->dec_input_config_params_default_size; 439 + } else if (inst->codec == V4L2_PIX_FMT_HEVC) { 440 + config_params = pdata->dec_input_config_params_hevc; 441 + config_params_size = pdata->dec_input_config_params_hevc_size; 442 + } else if (inst->codec == V4L2_PIX_FMT_VP9) { 443 + config_params = pdata->dec_input_config_params_vp9; 444 + config_params_size = pdata->dec_input_config_params_vp9_size; 445 + } else { 446 + return -EINVAL; 447 + } 448 + } else { 449 + config_params = pdata->dec_output_config_params; 450 + config_params_size = pdata->dec_output_config_params_size; 533 451 } 534 452 } else { 535 - config_params = core->iris_platform_data->output_config_params; 536 - config_params_size = core->iris_platform_data->output_config_params_size; 453 + if (V4L2_TYPE_IS_OUTPUT(plane)) { 454 + config_params = pdata->enc_input_config_params; 455 + config_params_size = pdata->enc_input_config_params_size; 456 + } else { 457 + config_params = pdata->enc_output_config_params; 458 + config_params_size = pdata->enc_output_config_params_size; 459 + } 537 460 } 538 461 539 462 if (!config_params || !config_params_size) ··· 548 459 for (i = 0; i < config_params_size; i++) { 549 460 for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) { 550 461 if (prop_type_handle_arr[j].type == config_params[i]) { 551 - ret = prop_type_handle_arr[j].handle(inst); 462 + ret = prop_type_handle_arr[j].handle(inst, plane); 552 463 if (ret) 553 464 return ret; 554 465 break; ··· 566 477 567 478 switch (inst->codec) { 568 479 case V4L2_PIX_FMT_H264: 569 - codec = HFI_CODEC_DECODE_AVC; 480 + if (inst->domain == ENCODER) 481 + codec = HFI_CODEC_ENCODE_AVC; 482 + else 483 + codec = HFI_CODEC_DECODE_AVC; 570 484 break; 571 485 case V4L2_PIX_FMT_HEVC: 572 - codec = HFI_CODEC_DECODE_HEVC; 486 + if (inst->domain == ENCODER) 487 + codec = HFI_CODEC_ENCODE_HEVC; 488 + else 489 + codec = HFI_CODEC_DECODE_HEVC; 573 490 break; 574 491 case V4L2_PIX_FMT_VP9: 575 492 codec = HFI_CODEC_DECODE_VP9; 576 - break; 577 493 } 578 494 579 495 iris_hfi_gen2_packet_session_property(inst, ··· 644 550 if (ret) 645 551 goto fail_free_packet; 646 552 647 - ret = iris_hfi_gen2_session_set_default_header(inst); 648 - if (ret) 649 - goto fail_free_packet; 553 + if (inst->domain == DECODER) { 554 + ret = iris_hfi_gen2_session_set_default_header(inst); 555 + if (ret) 556 + goto fail_free_packet; 557 + } 650 558 651 559 return 0; 652 560 ··· 697 601 cmd, 698 602 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 699 603 HFI_HOST_FLAGS_INTR_REQUIRED), 700 - iris_hfi_gen2_get_port(plane), 604 + iris_hfi_gen2_get_port(inst, plane), 701 605 inst->session_id, 702 606 payload_type, 703 607 payload, ··· 719 623 u32 hfi_port = 0, i; 720 624 int ret; 721 625 626 + if (inst->domain == ENCODER) 627 + return 0; 628 + 722 629 if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) || 723 630 (V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) { 724 631 dev_err(core->dev, "invalid plane\n"); ··· 730 631 731 632 switch (inst->codec) { 732 633 case V4L2_PIX_FMT_H264: 733 - change_param = core->iris_platform_data->input_config_params_default; 634 + change_param = core->iris_platform_data->dec_input_config_params_default; 734 635 change_param_size = 735 - core->iris_platform_data->input_config_params_default_size; 636 + core->iris_platform_data->dec_input_config_params_default_size; 736 637 break; 737 638 case V4L2_PIX_FMT_HEVC: 738 - change_param = core->iris_platform_data->input_config_params_hevc; 639 + change_param = core->iris_platform_data->dec_input_config_params_hevc; 739 640 change_param_size = 740 - core->iris_platform_data->input_config_params_hevc_size; 641 + core->iris_platform_data->dec_input_config_params_hevc_size; 741 642 break; 742 643 case V4L2_PIX_FMT_VP9: 743 - change_param = core->iris_platform_data->input_config_params_vp9; 644 + change_param = core->iris_platform_data->dec_input_config_params_vp9; 744 645 change_param_size = 745 - core->iris_platform_data->input_config_params_vp9_size; 646 + core->iris_platform_data->dec_input_config_params_vp9_size; 746 647 break; 747 648 } 748 649 ··· 763 664 if (V4L2_TYPE_IS_OUTPUT(plane)) { 764 665 inst_hfi_gen2->ipsc_properties_set = true; 765 666 } else { 766 - hfi_port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 667 + hfi_port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 767 668 memcpy(&inst_hfi_gen2->dst_subcr_params, 768 669 &inst_hfi_gen2->src_subcr_params, 769 670 sizeof(inst_hfi_gen2->src_subcr_params)); ··· 858 759 859 760 payload[0] = HFI_MODE_PROPERTY; 860 761 762 + if (inst->domain == ENCODER) 763 + return 0; 764 + 861 765 if (V4L2_TYPE_IS_OUTPUT(plane)) { 862 766 subscribe_prop_size = core->iris_platform_data->dec_input_prop_size; 863 767 subcribe_prop = core->iris_platform_data->dec_input_prop; ··· 912 810 HFI_CMD_START, 913 811 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 914 812 HFI_HOST_FLAGS_INTR_REQUIRED), 915 - iris_hfi_gen2_get_port(plane), 813 + iris_hfi_gen2_get_port(inst, plane), 916 814 inst->session_id, 917 815 HFI_PAYLOAD_NONE, 918 816 NULL, ··· 934 832 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 935 833 HFI_HOST_FLAGS_INTR_REQUIRED | 936 834 HFI_HOST_FLAGS_NON_DISCARDABLE), 937 - iris_hfi_gen2_get_port(plane), 835 + iris_hfi_gen2_get_port(inst, plane), 938 836 inst->session_id, 939 837 HFI_PAYLOAD_NONE, 940 838 NULL, ··· 956 854 HFI_CMD_PAUSE, 957 855 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 958 856 HFI_HOST_FLAGS_INTR_REQUIRED), 959 - iris_hfi_gen2_get_port(plane), 857 + iris_hfi_gen2_get_port(inst, plane), 960 858 inst->session_id, 961 859 HFI_PAYLOAD_NONE, 962 860 NULL, ··· 975 873 HFI_CMD_RESUME, 976 874 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 977 875 HFI_HOST_FLAGS_INTR_REQUIRED), 978 - iris_hfi_gen2_get_port(plane), 876 + iris_hfi_gen2_get_port(inst, plane), 979 877 inst->session_id, 980 878 HFI_PAYLOAD_U32, 981 879 &payload, ··· 994 892 HFI_CMD_RESUME, 995 893 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 996 894 HFI_HOST_FLAGS_INTR_REQUIRED), 997 - iris_hfi_gen2_get_port(plane), 895 + iris_hfi_gen2_get_port(inst, plane), 998 896 inst->session_id, 999 897 HFI_PAYLOAD_U32, 1000 898 &payload, ··· 1016 914 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 1017 915 HFI_HOST_FLAGS_INTR_REQUIRED | 1018 916 HFI_HOST_FLAGS_NON_DISCARDABLE), 1019 - iris_hfi_gen2_get_port(plane), 917 + iris_hfi_gen2_get_port(inst, plane), 1020 918 inst->session_id, 1021 919 HFI_PAYLOAD_NONE, 1022 920 NULL,
+3
drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
··· 49 49 #define HFI_PROP_TIER 0x03000109 50 50 #define HFI_PROP_STAGE 0x0300010a 51 51 #define HFI_PROP_PIPE 0x0300010b 52 + #define HFI_PROP_FRAME_RATE 0x0300010c 52 53 #define HFI_PROP_LUMA_CHROMA_BIT_DEPTH 0x0300010f 53 54 #define HFI_PROP_CODED_FRAMES 0x03000120 54 55 #define HFI_PROP_CABAC_SESSION 0x03000121 ··· 70 69 #define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168 71 70 #define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169 72 71 #define HFI_PROP_NO_OUTPUT 0x0300016a 72 + #define HFI_PROP_BUFFER_MARK 0x0300016c 73 + #define HFI_PROP_RAW_RESOLUTION 0x03000178 73 74 #define HFI_PROP_TOTAL_PEAK_BITRATE 0x0300017C 74 75 #define HFI_PROP_COMV_BUFFER_COUNT 0x03000193 75 76 #define HFI_PROP_END 0x03FFFFFF
+12 -8
drivers/media/platform/qcom/iris/iris_platform_common.h
··· 227 227 u32 max_core_mbpf; 228 228 /* max number of macroblocks per second supported */ 229 229 u32 max_core_mbps; 230 - const u32 *input_config_params_default; 231 - unsigned int input_config_params_default_size; 232 - const u32 *input_config_params_hevc; 233 - unsigned int input_config_params_hevc_size; 234 - const u32 *input_config_params_vp9; 235 - unsigned int input_config_params_vp9_size; 236 - const u32 *output_config_params; 237 - unsigned int output_config_params_size; 230 + const u32 *dec_input_config_params_default; 231 + unsigned int dec_input_config_params_default_size; 232 + const u32 *dec_input_config_params_hevc; 233 + unsigned int dec_input_config_params_hevc_size; 234 + const u32 *dec_input_config_params_vp9; 235 + unsigned int dec_input_config_params_vp9_size; 236 + const u32 *dec_output_config_params; 237 + unsigned int dec_output_config_params_size; 238 + const u32 *enc_input_config_params; 239 + unsigned int enc_input_config_params_size; 240 + const u32 *enc_output_config_params; 241 + unsigned int enc_output_config_params_size; 238 242 const u32 *dec_input_prop; 239 243 unsigned int dec_input_prop_size; 240 244 const u32 *dec_output_prop_avc;
+86 -32
drivers/media/platform/qcom/iris/iris_platform_gen2.c
··· 658 658 HFI_PROP_LEVEL, 659 659 }; 660 660 661 + static const u32 sm8550_venc_input_config_params[] = { 662 + HFI_PROP_COLOR_FORMAT, 663 + HFI_PROP_RAW_RESOLUTION, 664 + HFI_PROP_CROP_OFFSETS, 665 + HFI_PROP_LINEAR_STRIDE_SCANLINE, 666 + HFI_PROP_SIGNAL_COLOR_INFO, 667 + }; 668 + 661 669 static const u32 sm8550_vdec_output_config_params[] = { 662 670 HFI_PROP_COLOR_FORMAT, 663 671 HFI_PROP_LINEAR_STRIDE_SCANLINE, 672 + }; 673 + 674 + static const u32 sm8550_venc_output_config_params[] = { 675 + HFI_PROP_BITSTREAM_RESOLUTION, 676 + HFI_PROP_CROP_OFFSETS, 677 + HFI_PROP_FRAME_RATE, 664 678 }; 665 679 666 680 static const u32 sm8550_vdec_subscribe_input_properties[] = { ··· 740 726 .max_session_count = 16, 741 727 .max_core_mbpf = NUM_MBS_8K * 2, 742 728 .max_core_mbps = ((7680 * 4320) / 256) * 60, 743 - .input_config_params_default = 729 + .dec_input_config_params_default = 744 730 sm8550_vdec_input_config_params_default, 745 - .input_config_params_default_size = 731 + .dec_input_config_params_default_size = 746 732 ARRAY_SIZE(sm8550_vdec_input_config_params_default), 747 - .input_config_params_hevc = 733 + .dec_input_config_params_hevc = 748 734 sm8550_vdec_input_config_param_hevc, 749 - .input_config_params_hevc_size = 735 + .dec_input_config_params_hevc_size = 750 736 ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), 751 - .input_config_params_vp9 = 737 + .dec_input_config_params_vp9 = 752 738 sm8550_vdec_input_config_param_vp9, 753 - .input_config_params_vp9_size = 739 + .dec_input_config_params_vp9_size = 754 740 ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), 755 - .output_config_params = 741 + .dec_output_config_params = 756 742 sm8550_vdec_output_config_params, 757 - .output_config_params_size = 743 + .dec_output_config_params_size = 758 744 ARRAY_SIZE(sm8550_vdec_output_config_params), 745 + 746 + .enc_input_config_params = 747 + sm8550_venc_input_config_params, 748 + .enc_input_config_params_size = 749 + ARRAY_SIZE(sm8550_venc_input_config_params), 750 + .enc_output_config_params = 751 + sm8550_venc_output_config_params, 752 + .enc_output_config_params_size = 753 + ARRAY_SIZE(sm8550_venc_output_config_params), 754 + 759 755 .dec_input_prop = sm8550_vdec_subscribe_input_properties, 760 756 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), 761 757 .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, ··· 828 804 .max_session_count = 16, 829 805 .max_core_mbpf = NUM_MBS_8K * 2, 830 806 .max_core_mbps = ((7680 * 4320) / 256) * 60, 831 - .input_config_params_default = 807 + .dec_input_config_params_default = 832 808 sm8550_vdec_input_config_params_default, 833 - .input_config_params_default_size = 809 + .dec_input_config_params_default_size = 834 810 ARRAY_SIZE(sm8550_vdec_input_config_params_default), 835 - .input_config_params_hevc = 811 + .dec_input_config_params_hevc = 836 812 sm8550_vdec_input_config_param_hevc, 837 - .input_config_params_hevc_size = 813 + .dec_input_config_params_hevc_size = 838 814 ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), 839 - .input_config_params_vp9 = 815 + .dec_input_config_params_vp9 = 840 816 sm8550_vdec_input_config_param_vp9, 841 - .input_config_params_vp9_size = 817 + .dec_input_config_params_vp9_size = 842 818 ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), 843 - .output_config_params = 819 + .dec_output_config_params = 844 820 sm8550_vdec_output_config_params, 845 - .output_config_params_size = 821 + .dec_output_config_params_size = 846 822 ARRAY_SIZE(sm8550_vdec_output_config_params), 823 + 824 + .enc_input_config_params = 825 + sm8550_venc_input_config_params, 826 + .enc_input_config_params_size = 827 + ARRAY_SIZE(sm8550_venc_input_config_params), 828 + .enc_output_config_params = 829 + sm8550_venc_output_config_params, 830 + .enc_output_config_params_size = 831 + ARRAY_SIZE(sm8550_venc_output_config_params), 832 + 847 833 .dec_input_prop = sm8550_vdec_subscribe_input_properties, 848 834 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), 849 835 .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, ··· 906 872 .num_vpp_pipe = 4, 907 873 .max_session_count = 16, 908 874 .max_core_mbpf = NUM_MBS_8K * 2, 909 - .input_config_params_default = 875 + .dec_input_config_params_default = 910 876 sm8550_vdec_input_config_params_default, 911 - .input_config_params_default_size = 877 + .dec_input_config_params_default_size = 912 878 ARRAY_SIZE(sm8550_vdec_input_config_params_default), 913 - .input_config_params_hevc = 879 + .dec_input_config_params_hevc = 914 880 sm8550_vdec_input_config_param_hevc, 915 - .input_config_params_hevc_size = 881 + .dec_input_config_params_hevc_size = 916 882 ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), 917 - .input_config_params_vp9 = 883 + .dec_input_config_params_vp9 = 918 884 sm8550_vdec_input_config_param_vp9, 919 - .input_config_params_vp9_size = 885 + .dec_input_config_params_vp9_size = 920 886 ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), 921 - .output_config_params = 887 + .dec_output_config_params = 922 888 sm8550_vdec_output_config_params, 923 - .output_config_params_size = 889 + .dec_output_config_params_size = 924 890 ARRAY_SIZE(sm8550_vdec_output_config_params), 891 + 892 + .enc_input_config_params = 893 + sm8550_venc_input_config_params, 894 + .enc_input_config_params_size = 895 + ARRAY_SIZE(sm8550_venc_input_config_params), 896 + .enc_output_config_params = 897 + sm8550_venc_output_config_params, 898 + .enc_output_config_params_size = 899 + ARRAY_SIZE(sm8550_venc_output_config_params), 900 + 925 901 .dec_input_prop = sm8550_vdec_subscribe_input_properties, 926 902 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), 927 903 .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, ··· 990 946 .max_session_count = 16, 991 947 .max_core_mbpf = ((4096 * 2176) / 256) * 4, 992 948 .max_core_mbps = (((3840 * 2176) / 256) * 120), 993 - .input_config_params_default = 949 + .dec_input_config_params_default = 994 950 sm8550_vdec_input_config_params_default, 995 - .input_config_params_default_size = 951 + .dec_input_config_params_default_size = 996 952 ARRAY_SIZE(sm8550_vdec_input_config_params_default), 997 - .input_config_params_hevc = 953 + .dec_input_config_params_hevc = 998 954 sm8550_vdec_input_config_param_hevc, 999 - .input_config_params_hevc_size = 955 + .dec_input_config_params_hevc_size = 1000 956 ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), 1001 - .input_config_params_vp9 = 957 + .dec_input_config_params_vp9 = 1002 958 sm8550_vdec_input_config_param_vp9, 1003 - .input_config_params_vp9_size = 959 + .dec_input_config_params_vp9_size = 1004 960 ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), 1005 - .output_config_params = 961 + .dec_output_config_params = 1006 962 sm8550_vdec_output_config_params, 1007 - .output_config_params_size = 963 + .dec_output_config_params_size = 1008 964 ARRAY_SIZE(sm8550_vdec_output_config_params), 965 + 966 + .enc_input_config_params = 967 + sm8550_venc_input_config_params, 968 + .enc_input_config_params_size = 969 + ARRAY_SIZE(sm8550_venc_input_config_params), 970 + .enc_output_config_params = 971 + sm8550_venc_output_config_params, 972 + .enc_output_config_params_size = 973 + ARRAY_SIZE(sm8550_venc_output_config_params), 974 + 1009 975 .dec_input_prop = sm8550_vdec_subscribe_input_properties, 1010 976 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), 1011 977 .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
+21 -2
drivers/media/platform/qcom/iris/iris_platform_sm8250.c
··· 39 39 40 40 static struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = { 41 41 { 42 + .cap_id = STAGE, 43 + .min = STAGE_1, 44 + .max = STAGE_2, 45 + .step_or_mask = 1, 46 + .value = STAGE_2, 47 + .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE, 48 + }, 49 + { 42 50 .cap_id = PROFILE_H264, 43 51 .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, 44 52 .max = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH, ··· 276 268 HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE, 277 269 }; 278 270 271 + static const u32 sm8250_venc_input_config_param[] = { 272 + HFI_PROPERTY_CONFIG_FRAME_RATE, 273 + HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO, 274 + HFI_PROPERTY_PARAM_FRAME_SIZE, 275 + HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, 276 + HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, 277 + }; 278 + 279 279 static const u32 sm8250_dec_ip_int_buf_tbl[] = { 280 280 BUF_BIN, 281 281 BUF_SCRATCH_1, ··· 326 310 .max_session_count = 16, 327 311 .max_core_mbpf = NUM_MBS_8K, 328 312 .max_core_mbps = ((7680 * 4320) / 256) * 60, 329 - .input_config_params_default = 313 + .dec_input_config_params_default = 330 314 sm8250_vdec_input_config_param_default, 331 - .input_config_params_default_size = 315 + .dec_input_config_params_default_size = 332 316 ARRAY_SIZE(sm8250_vdec_input_config_param_default), 317 + .enc_input_config_params = sm8250_venc_input_config_param, 318 + .enc_input_config_params_size = 319 + ARRAY_SIZE(sm8250_venc_input_config_param), 333 320 334 321 .dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl, 335 322 .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_ip_int_buf_tbl),
+27 -9
drivers/media/platform/qcom/iris/iris_vb2.c
··· 7 7 #include <media/v4l2-event.h> 8 8 #include <media/v4l2-mem2mem.h> 9 9 10 + #include "iris_common.h" 10 11 #include "iris_instance.h" 11 12 #include "iris_vb2.h" 12 13 #include "iris_vdec.h" 14 + #include "iris_venc.h" 13 15 #include "iris_power.h" 14 16 15 17 static int iris_check_inst_mbpf(struct iris_inst *inst) ··· 176 174 if (ret) 177 175 goto error; 178 176 179 - if (V4L2_TYPE_IS_OUTPUT(q->type)) 180 - ret = iris_vdec_streamon_input(inst); 181 - else if (V4L2_TYPE_IS_CAPTURE(q->type)) 182 - ret = iris_vdec_streamon_output(inst); 177 + if (V4L2_TYPE_IS_OUTPUT(q->type)) { 178 + if (inst->domain == DECODER) 179 + ret = iris_vdec_streamon_input(inst); 180 + else 181 + ret = iris_venc_streamon_input(inst); 182 + } else if (V4L2_TYPE_IS_CAPTURE(q->type)) { 183 + if (inst->domain == DECODER) 184 + ret = iris_vdec_streamon_output(inst); 185 + else 186 + ret = iris_venc_streamon_output(inst); 187 + } 183 188 if (ret) 184 189 goto error; 185 190 186 191 buf_type = iris_v4l2_type_to_driver(q->type); 187 192 188 - if (inst->state == IRIS_INST_STREAMING) 189 - ret = iris_queue_internal_deferred_buffers(inst, BUF_DPB); 190 - if (!ret) 191 - ret = iris_queue_deferred_buffers(inst, buf_type); 193 + if (inst->domain == DECODER) { 194 + if (inst->state == IRIS_INST_STREAMING) 195 + ret = iris_queue_internal_deferred_buffers(inst, BUF_DPB); 196 + if (!ret) 197 + ret = iris_queue_deferred_buffers(inst, buf_type); 198 + } else { 199 + if (inst->state == IRIS_INST_STREAMING) { 200 + ret = iris_queue_deferred_buffers(inst, BUF_INPUT); 201 + if (!ret) 202 + ret = iris_queue_deferred_buffers(inst, BUF_OUTPUT); 203 + } 204 + } 205 + 192 206 if (ret) 193 207 goto error; 194 208 ··· 236 218 !V4L2_TYPE_IS_CAPTURE(q->type)) 237 219 goto exit; 238 220 239 - ret = iris_vdec_session_streamoff(inst, q->type); 221 + ret = iris_session_streamoff(inst, q->type); 240 222 if (ret) 241 223 goto exit; 242 224
+4 -186
drivers/media/platform/qcom/iris/iris_vdec.c
··· 7 7 #include <media/v4l2-mem2mem.h> 8 8 9 9 #include "iris_buffer.h" 10 + #include "iris_common.h" 10 11 #include "iris_ctrls.h" 11 12 #include "iris_instance.h" 12 13 #include "iris_power.h" ··· 313 312 v4l2_event_queue_fh(&inst->fh, &event); 314 313 } 315 314 316 - 317 - static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst, 318 - enum iris_buffer_type type) 319 - { 320 - struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 321 - struct v4l2_m2m_buffer *buffer, *n; 322 - struct iris_buffer *buf; 323 - 324 - if (type == BUF_INPUT) { 325 - v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { 326 - buf = to_iris_buffer(&buffer->vb); 327 - if (buf->attr & BUF_ATTR_DEFERRED) { 328 - if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { 329 - buf->attr |= BUF_ATTR_BUFFER_DONE; 330 - buf->data_size = 0; 331 - iris_vb2_buffer_done(inst, buf); 332 - } 333 - } 334 - } 335 - } else { 336 - v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) { 337 - buf = to_iris_buffer(&buffer->vb); 338 - if (buf->attr & BUF_ATTR_DEFERRED) { 339 - if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { 340 - buf->attr |= BUF_ATTR_BUFFER_DONE; 341 - buf->data_size = 0; 342 - iris_vb2_buffer_done(inst, buf); 343 - } 344 - } 345 - } 346 - } 347 - } 348 - 349 - static void iris_vdec_kill_session(struct iris_inst *inst) 350 - { 351 - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 352 - 353 - if (!inst->session_id) 354 - return; 355 - 356 - hfi_ops->session_close(inst); 357 - iris_inst_change_state(inst, IRIS_INST_ERROR); 358 - } 359 - 360 - int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) 361 - { 362 - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 363 - enum iris_buffer_type buffer_type; 364 - int ret; 365 - 366 - switch (plane) { 367 - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 368 - buffer_type = BUF_INPUT; 369 - break; 370 - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 371 - buffer_type = BUF_OUTPUT; 372 - break; 373 - default: 374 - return -EINVAL; 375 - } 376 - 377 - ret = hfi_ops->session_stop(inst, plane); 378 - if (ret) 379 - goto error; 380 - 381 - ret = iris_inst_state_change_streamoff(inst, plane); 382 - if (ret) 383 - goto error; 384 - 385 - iris_vdec_flush_deferred_buffers(inst, buffer_type); 386 - 387 - return 0; 388 - 389 - error: 390 - iris_vdec_kill_session(inst); 391 - iris_vdec_flush_deferred_buffers(inst, buffer_type); 392 - 393 - return ret; 394 - } 395 - 396 - static int iris_vdec_process_streamon_input(struct iris_inst *inst) 397 - { 398 - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 399 - enum iris_inst_sub_state set_sub_state = 0; 400 - int ret; 401 - 402 - iris_scale_power(inst); 403 - 404 - ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 405 - if (ret) 406 - return ret; 407 - 408 - if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 409 - ret = iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0); 410 - if (ret) 411 - return ret; 412 - } 413 - 414 - if (inst->sub_state & IRIS_INST_SUB_DRC || 415 - inst->sub_state & IRIS_INST_SUB_DRAIN || 416 - inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) { 417 - if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) { 418 - if (hfi_ops->session_pause) { 419 - ret = hfi_ops->session_pause(inst, 420 - V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 421 - if (ret) 422 - return ret; 423 - } 424 - set_sub_state = IRIS_INST_SUB_INPUT_PAUSE; 425 - } 426 - } 427 - 428 - ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 429 - if (ret) 430 - return ret; 431 - 432 - return iris_inst_change_sub_state(inst, 0, set_sub_state); 433 - } 434 - 435 315 int iris_vdec_streamon_input(struct iris_inst *inst) 436 316 { 437 317 int ret; ··· 339 457 if (ret) 340 458 return ret; 341 459 342 - return iris_vdec_process_streamon_input(inst); 343 - } 344 - 345 - static int iris_vdec_process_streamon_output(struct iris_inst *inst) 346 - { 347 - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 348 - bool drain_active = false, drc_active = false; 349 - enum iris_inst_sub_state clear_sub_state = 0; 350 - int ret = 0; 351 - 352 - iris_scale_power(inst); 353 - 354 - drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN && 355 - inst->sub_state & IRIS_INST_SUB_DRAIN_LAST; 356 - 357 - drc_active = inst->sub_state & IRIS_INST_SUB_DRC && 358 - inst->sub_state & IRIS_INST_SUB_DRC_LAST; 359 - 360 - if (drc_active) 361 - clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; 362 - else if (drain_active) 363 - clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; 364 - 365 - if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 366 - ret = iris_alloc_and_queue_input_int_bufs(inst); 367 - if (ret) 368 - return ret; 369 - ret = iris_set_stage(inst, STAGE); 370 - if (ret) 371 - return ret; 372 - ret = iris_set_pipe(inst, PIPE); 373 - if (ret) 374 - return ret; 375 - } 376 - 377 - if (inst->state == IRIS_INST_INPUT_STREAMING && 378 - inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 379 - if (!drain_active) 380 - ret = hfi_ops->session_resume_drc(inst, 381 - V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 382 - else if (hfi_ops->session_resume_drain) 383 - ret = hfi_ops->session_resume_drain(inst, 384 - V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 385 - if (ret) 386 - return ret; 387 - clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 388 - } 389 - 390 - if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) 391 - clear_sub_state |= IRIS_INST_SUB_FIRST_IPSC; 392 - 393 - ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 394 - if (ret) 395 - return ret; 396 - 397 - if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) 398 - clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 399 - 400 - ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 401 - if (ret) 402 - return ret; 403 - 404 - inst->last_buffer_dequeued = false; 405 - 406 - return iris_inst_change_sub_state(inst, clear_sub_state, 0); 460 + return iris_process_streamon_input(inst); 407 461 } 408 462 409 463 int iris_vdec_streamon_output(struct iris_inst *inst) ··· 361 543 if (ret) 362 544 return ret; 363 545 364 - ret = iris_vdec_process_streamon_output(inst); 546 + ret = iris_process_streamon_output(inst); 365 547 if (ret) 366 548 goto error; 367 549 ··· 372 554 return ret; 373 555 374 556 error: 375 - iris_vdec_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 557 + iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 376 558 377 559 return ret; 378 560 }
-1
drivers/media/platform/qcom/iris/iris_vdec.h
··· 21 21 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf); 22 22 int iris_vdec_start_cmd(struct iris_inst *inst); 23 23 int iris_vdec_stop_cmd(struct iris_inst *inst); 24 - int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane); 25 24 26 25 #endif
+32
drivers/media/platform/qcom/iris/iris_venc.c
··· 7 7 #include <media/v4l2-mem2mem.h> 8 8 9 9 #include "iris_buffer.h" 10 + #include "iris_common.h" 10 11 #include "iris_ctrls.h" 11 12 #include "iris_instance.h" 12 13 #include "iris_venc.h" ··· 425 424 } 426 425 427 426 return 0; 427 + } 428 + 429 + int iris_venc_streamon_input(struct iris_inst *inst) 430 + { 431 + int ret; 432 + 433 + ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 434 + if (ret) 435 + return ret; 436 + 437 + return iris_process_streamon_input(inst); 438 + } 439 + 440 + int iris_venc_streamon_output(struct iris_inst *inst) 441 + { 442 + int ret; 443 + 444 + ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 445 + if (ret) 446 + goto error; 447 + 448 + ret = iris_process_streamon_output(inst); 449 + if (ret) 450 + goto error; 451 + 452 + return ret; 453 + 454 + error: 455 + iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 456 + 457 + return ret; 428 458 }
+2
drivers/media/platform/qcom/iris/iris_venc.h
··· 18 18 int iris_venc_s_selection(struct iris_inst *inst, struct v4l2_selection *s); 19 19 int iris_venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm); 20 20 int iris_venc_s_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm); 21 + int iris_venc_streamon_input(struct iris_inst *inst); 22 + int iris_venc_streamon_output(struct iris_inst *inst); 21 23 22 24 #endif
+2
drivers/media/platform/qcom/iris/iris_vidc.c
··· 656 656 .vidioc_s_selection = iris_s_selection, 657 657 .vidioc_s_parm = iris_s_parm, 658 658 .vidioc_g_parm = iris_g_parm, 659 + .vidioc_streamon = v4l2_m2m_ioctl_streamon, 660 + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 659 661 }; 660 662 661 663 void iris_init_ops(struct iris_core *core)