197fb5e8dSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2af2c3834SStanimir Varbanov /* 3af2c3834SStanimir Varbanov * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 4af2c3834SStanimir Varbanov * Copyright (C) 2017 Linaro Ltd. 5af2c3834SStanimir Varbanov */ 6af2c3834SStanimir Varbanov #include <linux/list.h> 7af2c3834SStanimir Varbanov #include <linux/mutex.h> 8af2c3834SStanimir Varbanov #include <linux/slab.h> 92c2dc2fdSStanimir Varbanov #include <linux/kernel.h> 10cc82fd69SAlexandre Courbot #include <media/videobuf2-dma-contig.h> 11af2c3834SStanimir Varbanov #include <media/v4l2-mem2mem.h> 12af2c3834SStanimir Varbanov #include <asm/div64.h> 13af2c3834SStanimir Varbanov 14af2c3834SStanimir Varbanov #include "core.h" 15af2c3834SStanimir Varbanov #include "helpers.h" 16af2c3834SStanimir Varbanov #include "hfi_helper.h" 177482a983SStanimir Varbanov #include "pm_helpers.h" 18aa603389SStanimir Varbanov #include "hfi_platform.h" 19*7371093fSStanimir Varbanov #include "hfi_parser.h" 20af2c3834SStanimir Varbanov 21af2c3834SStanimir Varbanov struct intbuf { 22af2c3834SStanimir Varbanov struct list_head list; 23af2c3834SStanimir Varbanov u32 type; 24af2c3834SStanimir Varbanov size_t size; 25af2c3834SStanimir Varbanov void *va; 26af2c3834SStanimir Varbanov dma_addr_t da; 27af2c3834SStanimir Varbanov unsigned long attrs; 28af2c3834SStanimir Varbanov }; 29af2c3834SStanimir Varbanov 30d8db57c2SStanimir Varbanov bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt) 31d8db57c2SStanimir Varbanov { 32d8db57c2SStanimir Varbanov struct venus_core *core = inst->core; 33d8db57c2SStanimir Varbanov u32 session_type = inst->session_type; 34d8db57c2SStanimir Varbanov u32 codec; 35d8db57c2SStanimir Varbanov 36d8db57c2SStanimir Varbanov switch (v4l2_pixfmt) { 37d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_H264: 38d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_H264; 39d8db57c2SStanimir Varbanov break; 40d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_H263: 41d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_H263; 42d8db57c2SStanimir Varbanov break; 43d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_MPEG1: 44d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_MPEG1; 45d8db57c2SStanimir Varbanov break; 46d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_MPEG2: 47d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_MPEG2; 48d8db57c2SStanimir Varbanov break; 49d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_MPEG4: 50d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_MPEG4; 51d8db57c2SStanimir Varbanov break; 52d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_VC1_ANNEX_G: 53d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_VC1_ANNEX_L: 54d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_VC1; 55d8db57c2SStanimir Varbanov break; 56d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_VP8: 57d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_VP8; 58d8db57c2SStanimir Varbanov break; 59d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_VP9: 60d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_VP9; 61d8db57c2SStanimir Varbanov break; 62d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_XVID: 63d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_DIVX; 64d8db57c2SStanimir Varbanov break; 651fb9a605SStanimir Varbanov case V4L2_PIX_FMT_HEVC: 661fb9a605SStanimir Varbanov codec = HFI_VIDEO_CODEC_HEVC; 671fb9a605SStanimir Varbanov break; 68d8db57c2SStanimir Varbanov default: 69d8db57c2SStanimir Varbanov return false; 70d8db57c2SStanimir Varbanov } 71d8db57c2SStanimir Varbanov 72d8db57c2SStanimir Varbanov if (session_type == VIDC_SESSION_TYPE_ENC && core->enc_codecs & codec) 73d8db57c2SStanimir Varbanov return true; 74d8db57c2SStanimir Varbanov 75d8db57c2SStanimir Varbanov if (session_type == VIDC_SESSION_TYPE_DEC && core->dec_codecs & codec) 76d8db57c2SStanimir Varbanov return true; 77d8db57c2SStanimir Varbanov 78d8db57c2SStanimir Varbanov return false; 79d8db57c2SStanimir Varbanov } 80d8db57c2SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_check_codec); 81d8db57c2SStanimir Varbanov 821e485ee5SStanimir Varbanov int venus_helper_queue_dpb_bufs(struct venus_inst *inst) 83f012b23dSStanimir Varbanov { 84f012b23dSStanimir Varbanov struct intbuf *buf; 85f012b23dSStanimir Varbanov int ret = 0; 86f012b23dSStanimir Varbanov 87f012b23dSStanimir Varbanov list_for_each_entry(buf, &inst->dpbbufs, list) { 88f012b23dSStanimir Varbanov struct hfi_frame_data fdata; 89f012b23dSStanimir Varbanov 90f012b23dSStanimir Varbanov memset(&fdata, 0, sizeof(fdata)); 91f012b23dSStanimir Varbanov fdata.alloc_len = buf->size; 92f012b23dSStanimir Varbanov fdata.device_addr = buf->da; 93f012b23dSStanimir Varbanov fdata.buffer_type = buf->type; 94f012b23dSStanimir Varbanov 95f012b23dSStanimir Varbanov ret = hfi_session_process_buf(inst, &fdata); 96f012b23dSStanimir Varbanov if (ret) 97f012b23dSStanimir Varbanov goto fail; 98f012b23dSStanimir Varbanov } 99f012b23dSStanimir Varbanov 100f012b23dSStanimir Varbanov fail: 101f012b23dSStanimir Varbanov return ret; 102f012b23dSStanimir Varbanov } 1031e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_queue_dpb_bufs); 104f012b23dSStanimir Varbanov 105f012b23dSStanimir Varbanov int venus_helper_free_dpb_bufs(struct venus_inst *inst) 106f012b23dSStanimir Varbanov { 107f012b23dSStanimir Varbanov struct intbuf *buf, *n; 108f012b23dSStanimir Varbanov 109f012b23dSStanimir Varbanov list_for_each_entry_safe(buf, n, &inst->dpbbufs, list) { 110f012b23dSStanimir Varbanov list_del_init(&buf->list); 111f012b23dSStanimir Varbanov dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, 112f012b23dSStanimir Varbanov buf->attrs); 113f012b23dSStanimir Varbanov kfree(buf); 114f012b23dSStanimir Varbanov } 115f012b23dSStanimir Varbanov 116f012b23dSStanimir Varbanov INIT_LIST_HEAD(&inst->dpbbufs); 117f012b23dSStanimir Varbanov 118f012b23dSStanimir Varbanov return 0; 119f012b23dSStanimir Varbanov } 120f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_free_dpb_bufs); 121f012b23dSStanimir Varbanov 122f012b23dSStanimir Varbanov int venus_helper_alloc_dpb_bufs(struct venus_inst *inst) 123f012b23dSStanimir Varbanov { 124f012b23dSStanimir Varbanov struct venus_core *core = inst->core; 125f012b23dSStanimir Varbanov struct device *dev = core->dev; 126f012b23dSStanimir Varbanov enum hfi_version ver = core->res->hfi_version; 127f012b23dSStanimir Varbanov struct hfi_buffer_requirements bufreq; 128f012b23dSStanimir Varbanov u32 buftype = inst->dpb_buftype; 129f012b23dSStanimir Varbanov unsigned int dpb_size = 0; 130f012b23dSStanimir Varbanov struct intbuf *buf; 131f012b23dSStanimir Varbanov unsigned int i; 132f012b23dSStanimir Varbanov u32 count; 133f012b23dSStanimir Varbanov int ret; 134f012b23dSStanimir Varbanov 135f012b23dSStanimir Varbanov /* no need to allocate dpb buffers */ 136f012b23dSStanimir Varbanov if (!inst->dpb_fmt) 137f012b23dSStanimir Varbanov return 0; 138f012b23dSStanimir Varbanov 139f012b23dSStanimir Varbanov if (inst->dpb_buftype == HFI_BUFFER_OUTPUT) 140f012b23dSStanimir Varbanov dpb_size = inst->output_buf_size; 141f012b23dSStanimir Varbanov else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2) 142f012b23dSStanimir Varbanov dpb_size = inst->output2_buf_size; 143f012b23dSStanimir Varbanov 144f012b23dSStanimir Varbanov if (!dpb_size) 145f012b23dSStanimir Varbanov return 0; 146f012b23dSStanimir Varbanov 147f012b23dSStanimir Varbanov ret = venus_helper_get_bufreq(inst, buftype, &bufreq); 148f012b23dSStanimir Varbanov if (ret) 149f012b23dSStanimir Varbanov return ret; 150f012b23dSStanimir Varbanov 151f012b23dSStanimir Varbanov count = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); 152f012b23dSStanimir Varbanov 153f012b23dSStanimir Varbanov for (i = 0; i < count; i++) { 154f012b23dSStanimir Varbanov buf = kzalloc(sizeof(*buf), GFP_KERNEL); 155f012b23dSStanimir Varbanov if (!buf) { 156f012b23dSStanimir Varbanov ret = -ENOMEM; 157f012b23dSStanimir Varbanov goto fail; 158f012b23dSStanimir Varbanov } 159f012b23dSStanimir Varbanov 160f012b23dSStanimir Varbanov buf->type = buftype; 161f012b23dSStanimir Varbanov buf->size = dpb_size; 162f012b23dSStanimir Varbanov buf->attrs = DMA_ATTR_WRITE_COMBINE | 163f012b23dSStanimir Varbanov DMA_ATTR_NO_KERNEL_MAPPING; 164f012b23dSStanimir Varbanov buf->va = dma_alloc_attrs(dev, buf->size, &buf->da, GFP_KERNEL, 165f012b23dSStanimir Varbanov buf->attrs); 166f012b23dSStanimir Varbanov if (!buf->va) { 167f012b23dSStanimir Varbanov kfree(buf); 168f012b23dSStanimir Varbanov ret = -ENOMEM; 169f012b23dSStanimir Varbanov goto fail; 170f012b23dSStanimir Varbanov } 171f012b23dSStanimir Varbanov 172f012b23dSStanimir Varbanov list_add_tail(&buf->list, &inst->dpbbufs); 173f012b23dSStanimir Varbanov } 174f012b23dSStanimir Varbanov 175f012b23dSStanimir Varbanov return 0; 176f012b23dSStanimir Varbanov 177f012b23dSStanimir Varbanov fail: 178f012b23dSStanimir Varbanov venus_helper_free_dpb_bufs(inst); 179f012b23dSStanimir Varbanov return ret; 180f012b23dSStanimir Varbanov } 181f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_alloc_dpb_bufs); 182f012b23dSStanimir Varbanov 183af2c3834SStanimir Varbanov static int intbufs_set_buffer(struct venus_inst *inst, u32 type) 184af2c3834SStanimir Varbanov { 185af2c3834SStanimir Varbanov struct venus_core *core = inst->core; 186af2c3834SStanimir Varbanov struct device *dev = core->dev; 187af2c3834SStanimir Varbanov struct hfi_buffer_requirements bufreq; 188af2c3834SStanimir Varbanov struct hfi_buffer_desc bd; 189af2c3834SStanimir Varbanov struct intbuf *buf; 190af2c3834SStanimir Varbanov unsigned int i; 191af2c3834SStanimir Varbanov int ret; 192af2c3834SStanimir Varbanov 193af2c3834SStanimir Varbanov ret = venus_helper_get_bufreq(inst, type, &bufreq); 194af2c3834SStanimir Varbanov if (ret) 195af2c3834SStanimir Varbanov return 0; 196af2c3834SStanimir Varbanov 197af2c3834SStanimir Varbanov if (!bufreq.size) 198af2c3834SStanimir Varbanov return 0; 199af2c3834SStanimir Varbanov 200af2c3834SStanimir Varbanov for (i = 0; i < bufreq.count_actual; i++) { 201af2c3834SStanimir Varbanov buf = kzalloc(sizeof(*buf), GFP_KERNEL); 202af2c3834SStanimir Varbanov if (!buf) { 203af2c3834SStanimir Varbanov ret = -ENOMEM; 204af2c3834SStanimir Varbanov goto fail; 205af2c3834SStanimir Varbanov } 206af2c3834SStanimir Varbanov 207af2c3834SStanimir Varbanov buf->type = bufreq.type; 208af2c3834SStanimir Varbanov buf->size = bufreq.size; 209af2c3834SStanimir Varbanov buf->attrs = DMA_ATTR_WRITE_COMBINE | 210af2c3834SStanimir Varbanov DMA_ATTR_NO_KERNEL_MAPPING; 211af2c3834SStanimir Varbanov buf->va = dma_alloc_attrs(dev, buf->size, &buf->da, GFP_KERNEL, 212af2c3834SStanimir Varbanov buf->attrs); 213af2c3834SStanimir Varbanov if (!buf->va) { 214af2c3834SStanimir Varbanov ret = -ENOMEM; 215af2c3834SStanimir Varbanov goto fail; 216af2c3834SStanimir Varbanov } 217af2c3834SStanimir Varbanov 218af2c3834SStanimir Varbanov memset(&bd, 0, sizeof(bd)); 219af2c3834SStanimir Varbanov bd.buffer_size = buf->size; 220af2c3834SStanimir Varbanov bd.buffer_type = buf->type; 221af2c3834SStanimir Varbanov bd.num_buffers = 1; 222af2c3834SStanimir Varbanov bd.device_addr = buf->da; 223af2c3834SStanimir Varbanov 224af2c3834SStanimir Varbanov ret = hfi_session_set_buffers(inst, &bd); 225af2c3834SStanimir Varbanov if (ret) { 226af2c3834SStanimir Varbanov dev_err(dev, "set session buffers failed\n"); 227af2c3834SStanimir Varbanov goto dma_free; 228af2c3834SStanimir Varbanov } 229af2c3834SStanimir Varbanov 230af2c3834SStanimir Varbanov list_add_tail(&buf->list, &inst->internalbufs); 231af2c3834SStanimir Varbanov } 232af2c3834SStanimir Varbanov 233af2c3834SStanimir Varbanov return 0; 234af2c3834SStanimir Varbanov 235af2c3834SStanimir Varbanov dma_free: 236af2c3834SStanimir Varbanov dma_free_attrs(dev, buf->size, buf->va, buf->da, buf->attrs); 237af2c3834SStanimir Varbanov fail: 238af2c3834SStanimir Varbanov kfree(buf); 239af2c3834SStanimir Varbanov return ret; 240af2c3834SStanimir Varbanov } 241af2c3834SStanimir Varbanov 242af2c3834SStanimir Varbanov static int intbufs_unset_buffers(struct venus_inst *inst) 243af2c3834SStanimir Varbanov { 244af2c3834SStanimir Varbanov struct hfi_buffer_desc bd = {0}; 245af2c3834SStanimir Varbanov struct intbuf *buf, *n; 246af2c3834SStanimir Varbanov int ret = 0; 247af2c3834SStanimir Varbanov 248af2c3834SStanimir Varbanov list_for_each_entry_safe(buf, n, &inst->internalbufs, list) { 249af2c3834SStanimir Varbanov bd.buffer_size = buf->size; 250af2c3834SStanimir Varbanov bd.buffer_type = buf->type; 251af2c3834SStanimir Varbanov bd.num_buffers = 1; 252af2c3834SStanimir Varbanov bd.device_addr = buf->da; 253af2c3834SStanimir Varbanov bd.response_required = true; 254af2c3834SStanimir Varbanov 255af2c3834SStanimir Varbanov ret = hfi_session_unset_buffers(inst, &bd); 256af2c3834SStanimir Varbanov 257af2c3834SStanimir Varbanov list_del_init(&buf->list); 258af2c3834SStanimir Varbanov dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, 259af2c3834SStanimir Varbanov buf->attrs); 260af2c3834SStanimir Varbanov kfree(buf); 261af2c3834SStanimir Varbanov } 262af2c3834SStanimir Varbanov 263af2c3834SStanimir Varbanov return ret; 264af2c3834SStanimir Varbanov } 265af2c3834SStanimir Varbanov 266f04997bdSStanimir Varbanov static const unsigned int intbuf_types_1xx[] = { 267f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_1XX), 268f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_1XX), 269f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_1XX), 270f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_PERSIST, 271f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_PERSIST_1, 272f04997bdSStanimir Varbanov }; 273f04997bdSStanimir Varbanov 274f04997bdSStanimir Varbanov static const unsigned int intbuf_types_4xx[] = { 275f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_4XX), 276f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_4XX), 277f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_4XX), 278af2c3834SStanimir Varbanov HFI_BUFFER_INTERNAL_PERSIST, 279af2c3834SStanimir Varbanov HFI_BUFFER_INTERNAL_PERSIST_1, 280af2c3834SStanimir Varbanov }; 281af2c3834SStanimir Varbanov 2821e485ee5SStanimir Varbanov int venus_helper_intbufs_alloc(struct venus_inst *inst) 283af2c3834SStanimir Varbanov { 284f04997bdSStanimir Varbanov const unsigned int *intbuf; 285f04997bdSStanimir Varbanov size_t arr_sz, i; 286af2c3834SStanimir Varbanov int ret; 287af2c3834SStanimir Varbanov 288f04997bdSStanimir Varbanov if (IS_V4(inst->core)) { 289f04997bdSStanimir Varbanov arr_sz = ARRAY_SIZE(intbuf_types_4xx); 290f04997bdSStanimir Varbanov intbuf = intbuf_types_4xx; 291f04997bdSStanimir Varbanov } else { 292f04997bdSStanimir Varbanov arr_sz = ARRAY_SIZE(intbuf_types_1xx); 293f04997bdSStanimir Varbanov intbuf = intbuf_types_1xx; 294f04997bdSStanimir Varbanov } 295f04997bdSStanimir Varbanov 296f04997bdSStanimir Varbanov for (i = 0; i < arr_sz; i++) { 297f04997bdSStanimir Varbanov ret = intbufs_set_buffer(inst, intbuf[i]); 298af2c3834SStanimir Varbanov if (ret) 299af2c3834SStanimir Varbanov goto error; 300af2c3834SStanimir Varbanov } 301af2c3834SStanimir Varbanov 302af2c3834SStanimir Varbanov return 0; 303af2c3834SStanimir Varbanov 304af2c3834SStanimir Varbanov error: 305af2c3834SStanimir Varbanov intbufs_unset_buffers(inst); 306af2c3834SStanimir Varbanov return ret; 307af2c3834SStanimir Varbanov } 3081e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_intbufs_alloc); 309af2c3834SStanimir Varbanov 3101e485ee5SStanimir Varbanov int venus_helper_intbufs_free(struct venus_inst *inst) 311af2c3834SStanimir Varbanov { 312af2c3834SStanimir Varbanov return intbufs_unset_buffers(inst); 313af2c3834SStanimir Varbanov } 3141e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_intbufs_free); 315af2c3834SStanimir Varbanov 31614ea00d6SStanimir Varbanov int venus_helper_intbufs_realloc(struct venus_inst *inst) 31714ea00d6SStanimir Varbanov { 31814ea00d6SStanimir Varbanov enum hfi_version ver = inst->core->res->hfi_version; 31914ea00d6SStanimir Varbanov struct hfi_buffer_desc bd; 32014ea00d6SStanimir Varbanov struct intbuf *buf, *n; 32114ea00d6SStanimir Varbanov int ret; 32214ea00d6SStanimir Varbanov 32314ea00d6SStanimir Varbanov list_for_each_entry_safe(buf, n, &inst->internalbufs, list) { 32414ea00d6SStanimir Varbanov if (buf->type == HFI_BUFFER_INTERNAL_PERSIST || 32514ea00d6SStanimir Varbanov buf->type == HFI_BUFFER_INTERNAL_PERSIST_1) 32614ea00d6SStanimir Varbanov continue; 32714ea00d6SStanimir Varbanov 32814ea00d6SStanimir Varbanov memset(&bd, 0, sizeof(bd)); 32914ea00d6SStanimir Varbanov bd.buffer_size = buf->size; 33014ea00d6SStanimir Varbanov bd.buffer_type = buf->type; 33114ea00d6SStanimir Varbanov bd.num_buffers = 1; 33214ea00d6SStanimir Varbanov bd.device_addr = buf->da; 33314ea00d6SStanimir Varbanov bd.response_required = true; 33414ea00d6SStanimir Varbanov 33514ea00d6SStanimir Varbanov ret = hfi_session_unset_buffers(inst, &bd); 33614ea00d6SStanimir Varbanov 33714ea00d6SStanimir Varbanov dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, 33814ea00d6SStanimir Varbanov buf->attrs); 33914ea00d6SStanimir Varbanov 34014ea00d6SStanimir Varbanov list_del_init(&buf->list); 34114ea00d6SStanimir Varbanov kfree(buf); 34214ea00d6SStanimir Varbanov } 34314ea00d6SStanimir Varbanov 34414ea00d6SStanimir Varbanov ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH(ver)); 34514ea00d6SStanimir Varbanov if (ret) 34614ea00d6SStanimir Varbanov goto err; 34714ea00d6SStanimir Varbanov 34814ea00d6SStanimir Varbanov ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_1(ver)); 34914ea00d6SStanimir Varbanov if (ret) 35014ea00d6SStanimir Varbanov goto err; 35114ea00d6SStanimir Varbanov 35214ea00d6SStanimir Varbanov ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_2(ver)); 35314ea00d6SStanimir Varbanov if (ret) 35414ea00d6SStanimir Varbanov goto err; 35514ea00d6SStanimir Varbanov 35614ea00d6SStanimir Varbanov return 0; 35714ea00d6SStanimir Varbanov err: 35814ea00d6SStanimir Varbanov return ret; 35914ea00d6SStanimir Varbanov } 36014ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_intbufs_realloc); 36114ea00d6SStanimir Varbanov 362af2c3834SStanimir Varbanov static void fill_buffer_desc(const struct venus_buffer *buf, 363af2c3834SStanimir Varbanov struct hfi_buffer_desc *bd, bool response) 364af2c3834SStanimir Varbanov { 365af2c3834SStanimir Varbanov memset(bd, 0, sizeof(*bd)); 366af2c3834SStanimir Varbanov bd->buffer_type = HFI_BUFFER_OUTPUT; 367af2c3834SStanimir Varbanov bd->buffer_size = buf->size; 368af2c3834SStanimir Varbanov bd->num_buffers = 1; 369af2c3834SStanimir Varbanov bd->device_addr = buf->dma_addr; 370af2c3834SStanimir Varbanov bd->response_required = response; 371af2c3834SStanimir Varbanov } 372af2c3834SStanimir Varbanov 373af2c3834SStanimir Varbanov static void return_buf_error(struct venus_inst *inst, 374af2c3834SStanimir Varbanov struct vb2_v4l2_buffer *vbuf) 375af2c3834SStanimir Varbanov { 376af2c3834SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 377af2c3834SStanimir Varbanov 378af2c3834SStanimir Varbanov if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 379af2c3834SStanimir Varbanov v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf); 380af2c3834SStanimir Varbanov else 3810de0ef6cSGustavo A. R. Silva v4l2_m2m_dst_buf_remove_by_buf(m2m_ctx, vbuf); 382af2c3834SStanimir Varbanov 383af2c3834SStanimir Varbanov v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); 384af2c3834SStanimir Varbanov } 385af2c3834SStanimir Varbanov 386d42974e4SStanimir Varbanov static void 387d42974e4SStanimir Varbanov put_ts_metadata(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) 388d42974e4SStanimir Varbanov { 389d42974e4SStanimir Varbanov struct vb2_buffer *vb = &vbuf->vb2_buf; 390d42974e4SStanimir Varbanov unsigned int i; 391d42974e4SStanimir Varbanov int slot = -1; 392d42974e4SStanimir Varbanov u64 ts_us = vb->timestamp; 393d42974e4SStanimir Varbanov 394d42974e4SStanimir Varbanov for (i = 0; i < ARRAY_SIZE(inst->tss); i++) { 395d42974e4SStanimir Varbanov if (!inst->tss[i].used) { 396d42974e4SStanimir Varbanov slot = i; 397d42974e4SStanimir Varbanov break; 398d42974e4SStanimir Varbanov } 399d42974e4SStanimir Varbanov } 400d42974e4SStanimir Varbanov 401d42974e4SStanimir Varbanov if (slot == -1) { 4028c91dc08SStanimir Varbanov dev_dbg(inst->core->dev, VDBGL "no free slot\n"); 403d42974e4SStanimir Varbanov return; 404d42974e4SStanimir Varbanov } 405d42974e4SStanimir Varbanov 406d42974e4SStanimir Varbanov do_div(ts_us, NSEC_PER_USEC); 407d42974e4SStanimir Varbanov 408d42974e4SStanimir Varbanov inst->tss[slot].used = true; 409d42974e4SStanimir Varbanov inst->tss[slot].flags = vbuf->flags; 410d42974e4SStanimir Varbanov inst->tss[slot].tc = vbuf->timecode; 411d42974e4SStanimir Varbanov inst->tss[slot].ts_us = ts_us; 412d42974e4SStanimir Varbanov inst->tss[slot].ts_ns = vb->timestamp; 413d42974e4SStanimir Varbanov } 414d42974e4SStanimir Varbanov 415d42974e4SStanimir Varbanov void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us, 416d42974e4SStanimir Varbanov struct vb2_v4l2_buffer *vbuf) 417d42974e4SStanimir Varbanov { 418d42974e4SStanimir Varbanov struct vb2_buffer *vb = &vbuf->vb2_buf; 419d42974e4SStanimir Varbanov unsigned int i; 420d42974e4SStanimir Varbanov 421d42974e4SStanimir Varbanov for (i = 0; i < ARRAY_SIZE(inst->tss); ++i) { 422d42974e4SStanimir Varbanov if (!inst->tss[i].used) 423d42974e4SStanimir Varbanov continue; 424d42974e4SStanimir Varbanov 425d42974e4SStanimir Varbanov if (inst->tss[i].ts_us != timestamp_us) 426d42974e4SStanimir Varbanov continue; 427d42974e4SStanimir Varbanov 428d42974e4SStanimir Varbanov inst->tss[i].used = false; 429d42974e4SStanimir Varbanov vbuf->flags |= inst->tss[i].flags; 430d42974e4SStanimir Varbanov vbuf->timecode = inst->tss[i].tc; 431d42974e4SStanimir Varbanov vb->timestamp = inst->tss[i].ts_ns; 432d42974e4SStanimir Varbanov break; 433d42974e4SStanimir Varbanov } 434d42974e4SStanimir Varbanov } 435d42974e4SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_ts_metadata); 436d42974e4SStanimir Varbanov 437af2c3834SStanimir Varbanov static int 438af2c3834SStanimir Varbanov session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) 439af2c3834SStanimir Varbanov { 440af2c3834SStanimir Varbanov struct venus_buffer *buf = to_venus_buffer(vbuf); 441af2c3834SStanimir Varbanov struct vb2_buffer *vb = &vbuf->vb2_buf; 442af2c3834SStanimir Varbanov unsigned int type = vb->type; 443af2c3834SStanimir Varbanov struct hfi_frame_data fdata; 444af2c3834SStanimir Varbanov int ret; 445af2c3834SStanimir Varbanov 446af2c3834SStanimir Varbanov memset(&fdata, 0, sizeof(fdata)); 447af2c3834SStanimir Varbanov fdata.alloc_len = buf->size; 448af2c3834SStanimir Varbanov fdata.device_addr = buf->dma_addr; 449af2c3834SStanimir Varbanov fdata.timestamp = vb->timestamp; 450af2c3834SStanimir Varbanov do_div(fdata.timestamp, NSEC_PER_USEC); 451af2c3834SStanimir Varbanov fdata.flags = 0; 452af2c3834SStanimir Varbanov fdata.clnt_data = vbuf->vb2_buf.index; 453af2c3834SStanimir Varbanov 454af2c3834SStanimir Varbanov if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 455af2c3834SStanimir Varbanov fdata.buffer_type = HFI_BUFFER_INPUT; 456af2c3834SStanimir Varbanov fdata.filled_len = vb2_get_plane_payload(vb, 0); 457af2c3834SStanimir Varbanov fdata.offset = vb->planes[0].data_offset; 458af2c3834SStanimir Varbanov 459af2c3834SStanimir Varbanov if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len) 460af2c3834SStanimir Varbanov fdata.flags |= HFI_BUFFERFLAG_EOS; 461d42974e4SStanimir Varbanov 462d42974e4SStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_DEC) 463d42974e4SStanimir Varbanov put_ts_metadata(inst, vbuf); 464c0e284ccSAniket Masule 4657482a983SStanimir Varbanov venus_pm_load_scale(inst); 466af2c3834SStanimir Varbanov } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 467f012b23dSStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_ENC) 468af2c3834SStanimir Varbanov fdata.buffer_type = HFI_BUFFER_OUTPUT; 469f012b23dSStanimir Varbanov else 470f012b23dSStanimir Varbanov fdata.buffer_type = inst->opb_buftype; 471af2c3834SStanimir Varbanov fdata.filled_len = 0; 472af2c3834SStanimir Varbanov fdata.offset = 0; 473af2c3834SStanimir Varbanov } 474af2c3834SStanimir Varbanov 475af2c3834SStanimir Varbanov ret = hfi_session_process_buf(inst, &fdata); 476af2c3834SStanimir Varbanov if (ret) 477af2c3834SStanimir Varbanov return ret; 478af2c3834SStanimir Varbanov 479af2c3834SStanimir Varbanov return 0; 480af2c3834SStanimir Varbanov } 481af2c3834SStanimir Varbanov 482f0383520SStanimir Varbanov static bool is_dynamic_bufmode(struct venus_inst *inst) 483af2c3834SStanimir Varbanov { 484f0383520SStanimir Varbanov struct venus_core *core = inst->core; 4858f3b41dcSStanimir Varbanov struct hfi_plat_caps *caps; 486f0383520SStanimir Varbanov 487bc8c479aSStanimir Varbanov /* 488bc8c479aSStanimir Varbanov * v4 doesn't send BUFFER_ALLOC_MODE_SUPPORTED property and supports 489bc8c479aSStanimir Varbanov * dynamic buffer mode by default for HFI_BUFFER_OUTPUT/OUTPUT2. 490bc8c479aSStanimir Varbanov */ 491bc8c479aSStanimir Varbanov if (IS_V4(core)) 492bc8c479aSStanimir Varbanov return true; 493bc8c479aSStanimir Varbanov 494f0383520SStanimir Varbanov caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type); 495f0383520SStanimir Varbanov if (!caps) 4961cafbb86SGustavo A. R. Silva return false; 497af2c3834SStanimir Varbanov 498f0383520SStanimir Varbanov return caps->cap_bufs_mode_dynamic; 499af2c3834SStanimir Varbanov } 500af2c3834SStanimir Varbanov 5011e485ee5SStanimir Varbanov int venus_helper_unregister_bufs(struct venus_inst *inst) 502af2c3834SStanimir Varbanov { 503af2c3834SStanimir Varbanov struct venus_buffer *buf, *n; 504af2c3834SStanimir Varbanov struct hfi_buffer_desc bd; 505af2c3834SStanimir Varbanov int ret = 0; 506af2c3834SStanimir Varbanov 507f0383520SStanimir Varbanov if (is_dynamic_bufmode(inst)) 508af2c3834SStanimir Varbanov return 0; 509af2c3834SStanimir Varbanov 510af2c3834SStanimir Varbanov list_for_each_entry_safe(buf, n, &inst->registeredbufs, reg_list) { 511af2c3834SStanimir Varbanov fill_buffer_desc(buf, &bd, true); 512af2c3834SStanimir Varbanov ret = hfi_session_unset_buffers(inst, &bd); 513af2c3834SStanimir Varbanov list_del_init(&buf->reg_list); 514af2c3834SStanimir Varbanov } 515af2c3834SStanimir Varbanov 516af2c3834SStanimir Varbanov return ret; 517af2c3834SStanimir Varbanov } 5181e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_unregister_bufs); 519af2c3834SStanimir Varbanov 520af2c3834SStanimir Varbanov static int session_register_bufs(struct venus_inst *inst) 521af2c3834SStanimir Varbanov { 522af2c3834SStanimir Varbanov struct venus_core *core = inst->core; 523af2c3834SStanimir Varbanov struct device *dev = core->dev; 524af2c3834SStanimir Varbanov struct hfi_buffer_desc bd; 525af2c3834SStanimir Varbanov struct venus_buffer *buf; 526af2c3834SStanimir Varbanov int ret = 0; 527af2c3834SStanimir Varbanov 528f0383520SStanimir Varbanov if (is_dynamic_bufmode(inst)) 529af2c3834SStanimir Varbanov return 0; 530af2c3834SStanimir Varbanov 531af2c3834SStanimir Varbanov list_for_each_entry(buf, &inst->registeredbufs, reg_list) { 532af2c3834SStanimir Varbanov fill_buffer_desc(buf, &bd, false); 533af2c3834SStanimir Varbanov ret = hfi_session_set_buffers(inst, &bd); 534af2c3834SStanimir Varbanov if (ret) { 535af2c3834SStanimir Varbanov dev_err(dev, "%s: set buffer failed\n", __func__); 536af2c3834SStanimir Varbanov break; 537af2c3834SStanimir Varbanov } 538af2c3834SStanimir Varbanov } 539af2c3834SStanimir Varbanov 540af2c3834SStanimir Varbanov return ret; 541af2c3834SStanimir Varbanov } 542af2c3834SStanimir Varbanov 543ab97a3fbSStanimir Varbanov static u32 to_hfi_raw_fmt(u32 v4l2_fmt) 544ab97a3fbSStanimir Varbanov { 545ab97a3fbSStanimir Varbanov switch (v4l2_fmt) { 546ab97a3fbSStanimir Varbanov case V4L2_PIX_FMT_NV12: 547ab97a3fbSStanimir Varbanov return HFI_COLOR_FORMAT_NV12; 548ab97a3fbSStanimir Varbanov case V4L2_PIX_FMT_NV21: 549ab97a3fbSStanimir Varbanov return HFI_COLOR_FORMAT_NV21; 550ab97a3fbSStanimir Varbanov default: 551ab97a3fbSStanimir Varbanov break; 552ab97a3fbSStanimir Varbanov } 553ab97a3fbSStanimir Varbanov 554ab97a3fbSStanimir Varbanov return 0; 555ab97a3fbSStanimir Varbanov } 556ab97a3fbSStanimir Varbanov 557*7371093fSStanimir Varbanov static int platform_get_bufreq(struct venus_inst *inst, u32 buftype, 558*7371093fSStanimir Varbanov struct hfi_buffer_requirements *req) 559*7371093fSStanimir Varbanov { 560*7371093fSStanimir Varbanov enum hfi_version version = inst->core->res->hfi_version; 561*7371093fSStanimir Varbanov const struct hfi_platform *hfi_plat; 562*7371093fSStanimir Varbanov struct hfi_plat_buffers_params params; 563*7371093fSStanimir Varbanov bool is_dec = inst->session_type == VIDC_SESSION_TYPE_DEC; 564*7371093fSStanimir Varbanov struct venc_controls *enc_ctr = &inst->controls.enc; 565*7371093fSStanimir Varbanov 566*7371093fSStanimir Varbanov hfi_plat = hfi_platform_get(version); 567*7371093fSStanimir Varbanov 568*7371093fSStanimir Varbanov if (!hfi_plat || !hfi_plat->bufreq) 569*7371093fSStanimir Varbanov return -EINVAL; 570*7371093fSStanimir Varbanov 571*7371093fSStanimir Varbanov params.version = version; 572*7371093fSStanimir Varbanov params.num_vpp_pipes = hfi_platform_num_vpp_pipes(version); 573*7371093fSStanimir Varbanov 574*7371093fSStanimir Varbanov if (is_dec) { 575*7371093fSStanimir Varbanov params.width = inst->width; 576*7371093fSStanimir Varbanov params.height = inst->height; 577*7371093fSStanimir Varbanov params.codec = inst->fmt_out->pixfmt; 578*7371093fSStanimir Varbanov params.hfi_color_fmt = to_hfi_raw_fmt(inst->fmt_cap->pixfmt); 579*7371093fSStanimir Varbanov params.dec.max_mbs_per_frame = mbs_per_frame_max(inst); 580*7371093fSStanimir Varbanov params.dec.buffer_size_limit = 0; 581*7371093fSStanimir Varbanov params.dec.is_secondary_output = 582*7371093fSStanimir Varbanov inst->opb_buftype == HFI_BUFFER_OUTPUT2; 583*7371093fSStanimir Varbanov params.dec.is_interlaced = 584*7371093fSStanimir Varbanov inst->pic_struct != HFI_INTERLACE_FRAME_PROGRESSIVE ? 585*7371093fSStanimir Varbanov true : false; 586*7371093fSStanimir Varbanov } else { 587*7371093fSStanimir Varbanov params.width = inst->out_width; 588*7371093fSStanimir Varbanov params.height = inst->out_height; 589*7371093fSStanimir Varbanov params.codec = inst->fmt_cap->pixfmt; 590*7371093fSStanimir Varbanov params.hfi_color_fmt = to_hfi_raw_fmt(inst->fmt_out->pixfmt); 591*7371093fSStanimir Varbanov params.enc.work_mode = VIDC_WORK_MODE_2; 592*7371093fSStanimir Varbanov params.enc.rc_type = HFI_RATE_CONTROL_OFF; 593*7371093fSStanimir Varbanov if (enc_ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) 594*7371093fSStanimir Varbanov params.enc.rc_type = HFI_RATE_CONTROL_CQ; 595*7371093fSStanimir Varbanov params.enc.num_b_frames = enc_ctr->num_b_frames; 596*7371093fSStanimir Varbanov params.enc.is_tenbit = inst->bit_depth == VIDC_BITDEPTH_10; 597*7371093fSStanimir Varbanov } 598*7371093fSStanimir Varbanov 599*7371093fSStanimir Varbanov return hfi_plat->bufreq(¶ms, inst->session_type, buftype, req); 600*7371093fSStanimir Varbanov } 601*7371093fSStanimir Varbanov 602af2c3834SStanimir Varbanov int venus_helper_get_bufreq(struct venus_inst *inst, u32 type, 603af2c3834SStanimir Varbanov struct hfi_buffer_requirements *req) 604af2c3834SStanimir Varbanov { 605af2c3834SStanimir Varbanov u32 ptype = HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS; 606af2c3834SStanimir Varbanov union hfi_get_property hprop; 607af2c3834SStanimir Varbanov unsigned int i; 608af2c3834SStanimir Varbanov int ret; 609af2c3834SStanimir Varbanov 610af2c3834SStanimir Varbanov if (req) 611af2c3834SStanimir Varbanov memset(req, 0, sizeof(*req)); 612af2c3834SStanimir Varbanov 613*7371093fSStanimir Varbanov ret = platform_get_bufreq(inst, type, req); 614*7371093fSStanimir Varbanov if (!ret) 615*7371093fSStanimir Varbanov return 0; 616*7371093fSStanimir Varbanov 617af2c3834SStanimir Varbanov ret = hfi_session_get_property(inst, ptype, &hprop); 618af2c3834SStanimir Varbanov if (ret) 619af2c3834SStanimir Varbanov return ret; 620af2c3834SStanimir Varbanov 621af2c3834SStanimir Varbanov ret = -EINVAL; 622af2c3834SStanimir Varbanov 623af2c3834SStanimir Varbanov for (i = 0; i < HFI_BUFFER_TYPE_MAX; i++) { 624af2c3834SStanimir Varbanov if (hprop.bufreq[i].type != type) 625af2c3834SStanimir Varbanov continue; 626af2c3834SStanimir Varbanov 627af2c3834SStanimir Varbanov if (req) 628af2c3834SStanimir Varbanov memcpy(req, &hprop.bufreq[i], sizeof(*req)); 629af2c3834SStanimir Varbanov ret = 0; 630af2c3834SStanimir Varbanov break; 631af2c3834SStanimir Varbanov } 632af2c3834SStanimir Varbanov 633af2c3834SStanimir Varbanov return ret; 634af2c3834SStanimir Varbanov } 635af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_bufreq); 636af2c3834SStanimir Varbanov 6372c2dc2fdSStanimir Varbanov struct id_mapping { 6382c2dc2fdSStanimir Varbanov u32 hfi_id; 6392c2dc2fdSStanimir Varbanov u32 v4l2_id; 6402c2dc2fdSStanimir Varbanov }; 6412c2dc2fdSStanimir Varbanov 6422c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg4_profiles[] = { 6432c2dc2fdSStanimir Varbanov { HFI_MPEG4_PROFILE_SIMPLE, V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE }, 6442c2dc2fdSStanimir Varbanov { HFI_MPEG4_PROFILE_ADVANCEDSIMPLE, V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE }, 6452c2dc2fdSStanimir Varbanov }; 6462c2dc2fdSStanimir Varbanov 6472c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg4_levels[] = { 6482c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 }, 6492c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_0b, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B }, 6502c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_1, V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 }, 6512c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_2, V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 }, 6522c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_3, V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 }, 6532c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_4, V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 }, 6542c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_5, V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 }, 6552c2dc2fdSStanimir Varbanov }; 6562c2dc2fdSStanimir Varbanov 6572c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg2_profiles[] = { 6582c2dc2fdSStanimir Varbanov { HFI_MPEG2_PROFILE_SIMPLE, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE }, 6592c2dc2fdSStanimir Varbanov { HFI_MPEG2_PROFILE_MAIN, V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN }, 6602c2dc2fdSStanimir Varbanov { HFI_MPEG2_PROFILE_SNR, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE }, 6612c2dc2fdSStanimir Varbanov { HFI_MPEG2_PROFILE_SPATIAL, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE }, 6622c2dc2fdSStanimir Varbanov { HFI_MPEG2_PROFILE_HIGH, V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH }, 6632c2dc2fdSStanimir Varbanov }; 6642c2dc2fdSStanimir Varbanov 6652c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg2_levels[] = { 6662c2dc2fdSStanimir Varbanov { HFI_MPEG2_LEVEL_LL, V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW }, 6672c2dc2fdSStanimir Varbanov { HFI_MPEG2_LEVEL_ML, V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN }, 6682c2dc2fdSStanimir Varbanov { HFI_MPEG2_LEVEL_H14, V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440 }, 6692c2dc2fdSStanimir Varbanov { HFI_MPEG2_LEVEL_HL, V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH }, 6702c2dc2fdSStanimir Varbanov }; 6712c2dc2fdSStanimir Varbanov 6722c2dc2fdSStanimir Varbanov static const struct id_mapping h264_profiles[] = { 6732c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_BASELINE, V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE }, 6742c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_MAIN, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN }, 6752c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH }, 6762c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_STEREO_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH }, 6772c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_MULTIVIEW_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH }, 6782c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_CONSTRAINED_BASE, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE }, 6792c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_CONSTRAINED_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH }, 6802c2dc2fdSStanimir Varbanov }; 6812c2dc2fdSStanimir Varbanov 6822c2dc2fdSStanimir Varbanov static const struct id_mapping h264_levels[] = { 6832c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_1, V4L2_MPEG_VIDEO_H264_LEVEL_1_0 }, 6842c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_1b, V4L2_MPEG_VIDEO_H264_LEVEL_1B }, 6852c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_11, V4L2_MPEG_VIDEO_H264_LEVEL_1_1 }, 6862c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_12, V4L2_MPEG_VIDEO_H264_LEVEL_1_2 }, 6872c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_13, V4L2_MPEG_VIDEO_H264_LEVEL_1_3 }, 6882c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_2, V4L2_MPEG_VIDEO_H264_LEVEL_2_0 }, 6892c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_21, V4L2_MPEG_VIDEO_H264_LEVEL_2_1 }, 6902c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_22, V4L2_MPEG_VIDEO_H264_LEVEL_2_2 }, 6912c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_3, V4L2_MPEG_VIDEO_H264_LEVEL_3_0 }, 6922c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_31, V4L2_MPEG_VIDEO_H264_LEVEL_3_1 }, 6932c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_32, V4L2_MPEG_VIDEO_H264_LEVEL_3_2 }, 6942c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_4, V4L2_MPEG_VIDEO_H264_LEVEL_4_0 }, 6952c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_41, V4L2_MPEG_VIDEO_H264_LEVEL_4_1 }, 6962c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_42, V4L2_MPEG_VIDEO_H264_LEVEL_4_2 }, 6972c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_5, V4L2_MPEG_VIDEO_H264_LEVEL_5_0 }, 6982c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_51, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 }, 6992c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_52, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 }, 7002c2dc2fdSStanimir Varbanov }; 7012c2dc2fdSStanimir Varbanov 7022c2dc2fdSStanimir Varbanov static const struct id_mapping hevc_profiles[] = { 7032c2dc2fdSStanimir Varbanov { HFI_HEVC_PROFILE_MAIN, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN }, 7042c2dc2fdSStanimir Varbanov { HFI_HEVC_PROFILE_MAIN_STILL_PIC, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE }, 7052c2dc2fdSStanimir Varbanov { HFI_HEVC_PROFILE_MAIN10, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10 }, 7062c2dc2fdSStanimir Varbanov }; 7072c2dc2fdSStanimir Varbanov 7082c2dc2fdSStanimir Varbanov static const struct id_mapping hevc_levels[] = { 7092c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_1, V4L2_MPEG_VIDEO_HEVC_LEVEL_1 }, 7102c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_2, V4L2_MPEG_VIDEO_HEVC_LEVEL_2 }, 7112c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_21, V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 }, 7122c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_3, V4L2_MPEG_VIDEO_HEVC_LEVEL_3 }, 7132c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_31, V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 }, 7142c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_4, V4L2_MPEG_VIDEO_HEVC_LEVEL_4 }, 7152c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_41, V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 }, 7162c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_5, V4L2_MPEG_VIDEO_HEVC_LEVEL_5 }, 7172c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_51, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 }, 7182c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_52, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 }, 7192c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_6, V4L2_MPEG_VIDEO_HEVC_LEVEL_6 }, 7202c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_61, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 }, 7212c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_62, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 }, 7222c2dc2fdSStanimir Varbanov }; 7232c2dc2fdSStanimir Varbanov 7242c2dc2fdSStanimir Varbanov static const struct id_mapping vp8_profiles[] = { 7252c2dc2fdSStanimir Varbanov { HFI_VPX_PROFILE_VERSION_0, V4L2_MPEG_VIDEO_VP8_PROFILE_0 }, 7262c2dc2fdSStanimir Varbanov { HFI_VPX_PROFILE_VERSION_1, V4L2_MPEG_VIDEO_VP8_PROFILE_1 }, 7272c2dc2fdSStanimir Varbanov { HFI_VPX_PROFILE_VERSION_2, V4L2_MPEG_VIDEO_VP8_PROFILE_2 }, 7282c2dc2fdSStanimir Varbanov { HFI_VPX_PROFILE_VERSION_3, V4L2_MPEG_VIDEO_VP8_PROFILE_3 }, 7292c2dc2fdSStanimir Varbanov }; 7302c2dc2fdSStanimir Varbanov 7312c2dc2fdSStanimir Varbanov static const struct id_mapping vp9_profiles[] = { 7322c2dc2fdSStanimir Varbanov { HFI_VP9_PROFILE_P0, V4L2_MPEG_VIDEO_VP9_PROFILE_0 }, 7332c2dc2fdSStanimir Varbanov { HFI_VP9_PROFILE_P2_10B, V4L2_MPEG_VIDEO_VP9_PROFILE_2 }, 7342c2dc2fdSStanimir Varbanov }; 7352c2dc2fdSStanimir Varbanov 7362c2dc2fdSStanimir Varbanov static const struct id_mapping vp9_levels[] = { 7372c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_1, V4L2_MPEG_VIDEO_VP9_LEVEL_1_0 }, 7382c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_11, V4L2_MPEG_VIDEO_VP9_LEVEL_1_1 }, 7392c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_2, V4L2_MPEG_VIDEO_VP9_LEVEL_2_0}, 7402c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_21, V4L2_MPEG_VIDEO_VP9_LEVEL_2_1 }, 7412c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_3, V4L2_MPEG_VIDEO_VP9_LEVEL_3_0}, 7422c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_31, V4L2_MPEG_VIDEO_VP9_LEVEL_3_1 }, 7432c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_4, V4L2_MPEG_VIDEO_VP9_LEVEL_4_0 }, 7442c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_41, V4L2_MPEG_VIDEO_VP9_LEVEL_4_1 }, 7452c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_5, V4L2_MPEG_VIDEO_VP9_LEVEL_5_0 }, 7462c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_51, V4L2_MPEG_VIDEO_VP9_LEVEL_5_1 }, 7472c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_6, V4L2_MPEG_VIDEO_VP9_LEVEL_6_0 }, 7482c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_61, V4L2_MPEG_VIDEO_VP9_LEVEL_6_1 }, 7492c2dc2fdSStanimir Varbanov }; 7502c2dc2fdSStanimir Varbanov 7512c2dc2fdSStanimir Varbanov static u32 find_v4l2_id(u32 hfi_id, const struct id_mapping *array, unsigned int array_sz) 7522c2dc2fdSStanimir Varbanov { 7532c2dc2fdSStanimir Varbanov unsigned int i; 7542c2dc2fdSStanimir Varbanov 7552c2dc2fdSStanimir Varbanov if (!array || !array_sz) 7562c2dc2fdSStanimir Varbanov return 0; 7572c2dc2fdSStanimir Varbanov 7582c2dc2fdSStanimir Varbanov for (i = 0; i < array_sz; i++) 7592c2dc2fdSStanimir Varbanov if (hfi_id == array[i].hfi_id) 7602c2dc2fdSStanimir Varbanov return array[i].v4l2_id; 7612c2dc2fdSStanimir Varbanov 7622c2dc2fdSStanimir Varbanov return 0; 7632c2dc2fdSStanimir Varbanov } 7642c2dc2fdSStanimir Varbanov 7652c2dc2fdSStanimir Varbanov static u32 find_hfi_id(u32 v4l2_id, const struct id_mapping *array, unsigned int array_sz) 7662c2dc2fdSStanimir Varbanov { 7672c2dc2fdSStanimir Varbanov unsigned int i; 7682c2dc2fdSStanimir Varbanov 7692c2dc2fdSStanimir Varbanov if (!array || !array_sz) 7702c2dc2fdSStanimir Varbanov return 0; 7712c2dc2fdSStanimir Varbanov 7722c2dc2fdSStanimir Varbanov for (i = 0; i < array_sz; i++) 7732c2dc2fdSStanimir Varbanov if (v4l2_id == array[i].v4l2_id) 7742c2dc2fdSStanimir Varbanov return array[i].hfi_id; 7752c2dc2fdSStanimir Varbanov 7762c2dc2fdSStanimir Varbanov return 0; 7772c2dc2fdSStanimir Varbanov } 7782c2dc2fdSStanimir Varbanov 7792c2dc2fdSStanimir Varbanov static void 7802c2dc2fdSStanimir Varbanov v4l2_id_profile_level(u32 hfi_codec, struct hfi_profile_level *pl, u32 *profile, u32 *level) 7812c2dc2fdSStanimir Varbanov { 7822c2dc2fdSStanimir Varbanov u32 hfi_pf = pl->profile; 7832c2dc2fdSStanimir Varbanov u32 hfi_lvl = pl->level; 7842c2dc2fdSStanimir Varbanov 7852c2dc2fdSStanimir Varbanov switch (hfi_codec) { 7862c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_H264: 7872c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, h264_profiles, ARRAY_SIZE(h264_profiles)); 7882c2dc2fdSStanimir Varbanov *level = find_v4l2_id(hfi_lvl, h264_levels, ARRAY_SIZE(h264_levels)); 7892c2dc2fdSStanimir Varbanov break; 7902c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_MPEG2: 7912c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, mpeg2_profiles, ARRAY_SIZE(mpeg2_profiles)); 7922c2dc2fdSStanimir Varbanov *level = find_v4l2_id(hfi_lvl, mpeg2_levels, ARRAY_SIZE(mpeg2_levels)); 7932c2dc2fdSStanimir Varbanov break; 7942c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_MPEG4: 7952c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, mpeg4_profiles, ARRAY_SIZE(mpeg4_profiles)); 7962c2dc2fdSStanimir Varbanov *level = find_v4l2_id(hfi_lvl, mpeg4_levels, ARRAY_SIZE(mpeg4_levels)); 7972c2dc2fdSStanimir Varbanov break; 7982c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_VP8: 7992c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, vp8_profiles, ARRAY_SIZE(vp8_profiles)); 8002c2dc2fdSStanimir Varbanov *level = 0; 8012c2dc2fdSStanimir Varbanov break; 8022c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_VP9: 8032c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, vp9_profiles, ARRAY_SIZE(vp9_profiles)); 8042c2dc2fdSStanimir Varbanov *level = find_v4l2_id(hfi_lvl, vp9_levels, ARRAY_SIZE(vp9_levels)); 8052c2dc2fdSStanimir Varbanov break; 8062c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_HEVC: 8072c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, hevc_profiles, ARRAY_SIZE(hevc_profiles)); 8082c2dc2fdSStanimir Varbanov *level = find_v4l2_id(hfi_lvl, hevc_levels, ARRAY_SIZE(hevc_levels)); 8092c2dc2fdSStanimir Varbanov break; 8102c2dc2fdSStanimir Varbanov default: 8112c2dc2fdSStanimir Varbanov break; 8122c2dc2fdSStanimir Varbanov } 8132c2dc2fdSStanimir Varbanov } 8142c2dc2fdSStanimir Varbanov 8152c2dc2fdSStanimir Varbanov static void 8162c2dc2fdSStanimir Varbanov hfi_id_profile_level(u32 hfi_codec, u32 v4l2_pf, u32 v4l2_lvl, struct hfi_profile_level *pl) 8172c2dc2fdSStanimir Varbanov { 8182c2dc2fdSStanimir Varbanov switch (hfi_codec) { 8192c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_H264: 8202c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, h264_profiles, ARRAY_SIZE(h264_profiles)); 8212c2dc2fdSStanimir Varbanov pl->level = find_hfi_id(v4l2_lvl, h264_levels, ARRAY_SIZE(h264_levels)); 8222c2dc2fdSStanimir Varbanov break; 8232c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_MPEG2: 8242c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, mpeg2_profiles, ARRAY_SIZE(mpeg2_profiles)); 8252c2dc2fdSStanimir Varbanov pl->level = find_hfi_id(v4l2_lvl, mpeg2_levels, ARRAY_SIZE(mpeg2_levels)); 8262c2dc2fdSStanimir Varbanov break; 8272c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_MPEG4: 8282c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, mpeg4_profiles, ARRAY_SIZE(mpeg4_profiles)); 8292c2dc2fdSStanimir Varbanov pl->level = find_hfi_id(v4l2_lvl, mpeg4_levels, ARRAY_SIZE(mpeg4_levels)); 8302c2dc2fdSStanimir Varbanov break; 8312c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_VP8: 8322c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, vp8_profiles, ARRAY_SIZE(vp8_profiles)); 8332c2dc2fdSStanimir Varbanov pl->level = 0; 8342c2dc2fdSStanimir Varbanov break; 8352c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_VP9: 8362c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, vp9_profiles, ARRAY_SIZE(vp9_profiles)); 8372c2dc2fdSStanimir Varbanov pl->level = find_hfi_id(v4l2_lvl, vp9_levels, ARRAY_SIZE(vp9_levels)); 8382c2dc2fdSStanimir Varbanov break; 8392c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_HEVC: 8402c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, hevc_profiles, ARRAY_SIZE(hevc_profiles)); 8412c2dc2fdSStanimir Varbanov pl->level = find_hfi_id(v4l2_lvl, hevc_levels, ARRAY_SIZE(hevc_levels)); 8422c2dc2fdSStanimir Varbanov break; 8432c2dc2fdSStanimir Varbanov default: 8442c2dc2fdSStanimir Varbanov break; 8452c2dc2fdSStanimir Varbanov } 8462c2dc2fdSStanimir Varbanov } 8472c2dc2fdSStanimir Varbanov 8482c2dc2fdSStanimir Varbanov int venus_helper_get_profile_level(struct venus_inst *inst, u32 *profile, u32 *level) 8492c2dc2fdSStanimir Varbanov { 8502c2dc2fdSStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT; 8512c2dc2fdSStanimir Varbanov union hfi_get_property hprop; 8522c2dc2fdSStanimir Varbanov int ret; 8532c2dc2fdSStanimir Varbanov 8542c2dc2fdSStanimir Varbanov ret = hfi_session_get_property(inst, ptype, &hprop); 8552c2dc2fdSStanimir Varbanov if (ret) 8562c2dc2fdSStanimir Varbanov return ret; 8572c2dc2fdSStanimir Varbanov 8582c2dc2fdSStanimir Varbanov v4l2_id_profile_level(inst->hfi_codec, &hprop.profile_level, profile, level); 8592c2dc2fdSStanimir Varbanov 8602c2dc2fdSStanimir Varbanov return 0; 8612c2dc2fdSStanimir Varbanov } 8622c2dc2fdSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_profile_level); 8632c2dc2fdSStanimir Varbanov 8642c2dc2fdSStanimir Varbanov int venus_helper_set_profile_level(struct venus_inst *inst, u32 profile, u32 level) 8652c2dc2fdSStanimir Varbanov { 8662c2dc2fdSStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT; 8672c2dc2fdSStanimir Varbanov struct hfi_profile_level pl; 8682c2dc2fdSStanimir Varbanov 8692c2dc2fdSStanimir Varbanov hfi_id_profile_level(inst->hfi_codec, profile, level, &pl); 8702c2dc2fdSStanimir Varbanov 8712c2dc2fdSStanimir Varbanov return hfi_session_set_property(inst, ptype, &pl); 8722c2dc2fdSStanimir Varbanov } 8732c2dc2fdSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_profile_level); 8742c2dc2fdSStanimir Varbanov 875e1cb72deSStanimir Varbanov static u32 get_framesize_raw_nv12(u32 width, u32 height) 876e1cb72deSStanimir Varbanov { 877e1cb72deSStanimir Varbanov u32 y_stride, uv_stride, y_plane; 878e1cb72deSStanimir Varbanov u32 y_sclines, uv_sclines, uv_plane; 879e1cb72deSStanimir Varbanov u32 size; 880e1cb72deSStanimir Varbanov 881e1cb72deSStanimir Varbanov y_stride = ALIGN(width, 128); 882e1cb72deSStanimir Varbanov uv_stride = ALIGN(width, 128); 883e1cb72deSStanimir Varbanov y_sclines = ALIGN(height, 32); 884e1cb72deSStanimir Varbanov uv_sclines = ALIGN(((height + 1) >> 1), 16); 885e1cb72deSStanimir Varbanov 886e1cb72deSStanimir Varbanov y_plane = y_stride * y_sclines; 887e1cb72deSStanimir Varbanov uv_plane = uv_stride * uv_sclines + SZ_4K; 888e1cb72deSStanimir Varbanov size = y_plane + uv_plane + SZ_8K; 889e1cb72deSStanimir Varbanov 890e1cb72deSStanimir Varbanov return ALIGN(size, SZ_4K); 891e1cb72deSStanimir Varbanov } 892e1cb72deSStanimir Varbanov 893e1cb72deSStanimir Varbanov static u32 get_framesize_raw_nv12_ubwc(u32 width, u32 height) 894e1cb72deSStanimir Varbanov { 895e1cb72deSStanimir Varbanov u32 y_meta_stride, y_meta_plane; 896e1cb72deSStanimir Varbanov u32 y_stride, y_plane; 897e1cb72deSStanimir Varbanov u32 uv_meta_stride, uv_meta_plane; 898e1cb72deSStanimir Varbanov u32 uv_stride, uv_plane; 899e1cb72deSStanimir Varbanov u32 extradata = SZ_16K; 900e1cb72deSStanimir Varbanov 901e1cb72deSStanimir Varbanov y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64); 902e1cb72deSStanimir Varbanov y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(height, 8), 16); 903e1cb72deSStanimir Varbanov y_meta_plane = ALIGN(y_meta_plane, SZ_4K); 904e1cb72deSStanimir Varbanov 905e1cb72deSStanimir Varbanov y_stride = ALIGN(width, 128); 906e1cb72deSStanimir Varbanov y_plane = ALIGN(y_stride * ALIGN(height, 32), SZ_4K); 907e1cb72deSStanimir Varbanov 908e1cb72deSStanimir Varbanov uv_meta_stride = ALIGN(DIV_ROUND_UP(width / 2, 16), 64); 909e1cb72deSStanimir Varbanov uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(height / 2, 8), 16); 910e1cb72deSStanimir Varbanov uv_meta_plane = ALIGN(uv_meta_plane, SZ_4K); 911e1cb72deSStanimir Varbanov 912e1cb72deSStanimir Varbanov uv_stride = ALIGN(width, 128); 913e1cb72deSStanimir Varbanov uv_plane = ALIGN(uv_stride * ALIGN(height / 2, 32), SZ_4K); 914e1cb72deSStanimir Varbanov 915e1cb72deSStanimir Varbanov return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane + 916e1cb72deSStanimir Varbanov max(extradata, y_stride * 48), SZ_4K); 917e1cb72deSStanimir Varbanov } 918e1cb72deSStanimir Varbanov 919ab1eda44SAniket Masule static u32 get_framesize_raw_p010(u32 width, u32 height) 920ab1eda44SAniket Masule { 921ab1eda44SAniket Masule u32 y_plane, uv_plane, y_stride, uv_stride, y_sclines, uv_sclines; 922ab1eda44SAniket Masule 923ab1eda44SAniket Masule y_stride = ALIGN(width * 2, 256); 924ab1eda44SAniket Masule uv_stride = ALIGN(width * 2, 256); 925ab1eda44SAniket Masule y_sclines = ALIGN(height, 32); 926ab1eda44SAniket Masule uv_sclines = ALIGN((height + 1) >> 1, 16); 927ab1eda44SAniket Masule y_plane = y_stride * y_sclines; 928ab1eda44SAniket Masule uv_plane = uv_stride * uv_sclines; 929ab1eda44SAniket Masule 930ab1eda44SAniket Masule return ALIGN((y_plane + uv_plane), SZ_4K); 931ab1eda44SAniket Masule } 932ab1eda44SAniket Masule 933ab1eda44SAniket Masule static u32 get_framesize_raw_p010_ubwc(u32 width, u32 height) 934ab1eda44SAniket Masule { 935ab1eda44SAniket Masule u32 y_stride, uv_stride, y_sclines, uv_sclines; 936ab1eda44SAniket Masule u32 y_ubwc_plane, uv_ubwc_plane; 937ab1eda44SAniket Masule u32 y_meta_stride, y_meta_scanlines; 938ab1eda44SAniket Masule u32 uv_meta_stride, uv_meta_scanlines; 939ab1eda44SAniket Masule u32 y_meta_plane, uv_meta_plane; 940ab1eda44SAniket Masule u32 size; 941ab1eda44SAniket Masule 942ab1eda44SAniket Masule y_stride = ALIGN(width * 2, 256); 943ab1eda44SAniket Masule uv_stride = ALIGN(width * 2, 256); 944ab1eda44SAniket Masule y_sclines = ALIGN(height, 16); 945ab1eda44SAniket Masule uv_sclines = ALIGN((height + 1) >> 1, 16); 946ab1eda44SAniket Masule 947ab1eda44SAniket Masule y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K); 948ab1eda44SAniket Masule uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K); 949ab1eda44SAniket Masule y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64); 950ab1eda44SAniket Masule y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16); 951ab1eda44SAniket Masule y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K); 952ab1eda44SAniket Masule uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64); 953ab1eda44SAniket Masule uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16); 954ab1eda44SAniket Masule uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K); 955ab1eda44SAniket Masule 956ab1eda44SAniket Masule size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane; 957ab1eda44SAniket Masule 958ab1eda44SAniket Masule return ALIGN(size, SZ_4K); 959ab1eda44SAniket Masule } 960ab1eda44SAniket Masule 961ab1eda44SAniket Masule static u32 get_framesize_raw_yuv420_tp10_ubwc(u32 width, u32 height) 962ab1eda44SAniket Masule { 963ab1eda44SAniket Masule u32 y_stride, uv_stride, y_sclines, uv_sclines; 964ab1eda44SAniket Masule u32 y_ubwc_plane, uv_ubwc_plane; 965ab1eda44SAniket Masule u32 y_meta_stride, y_meta_scanlines; 966ab1eda44SAniket Masule u32 uv_meta_stride, uv_meta_scanlines; 967ab1eda44SAniket Masule u32 y_meta_plane, uv_meta_plane; 968ab1eda44SAniket Masule u32 extradata = SZ_16K; 969ab1eda44SAniket Masule u32 size; 970ab1eda44SAniket Masule 971ab1eda44SAniket Masule y_stride = ALIGN(ALIGN(width, 192) * 4 / 3, 256); 972ab1eda44SAniket Masule uv_stride = ALIGN(ALIGN(width, 192) * 4 / 3, 256); 973ab1eda44SAniket Masule y_sclines = ALIGN(height, 16); 974ab1eda44SAniket Masule uv_sclines = ALIGN((height + 1) >> 1, 16); 975ab1eda44SAniket Masule 976ab1eda44SAniket Masule y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K); 977ab1eda44SAniket Masule uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K); 978ab1eda44SAniket Masule y_meta_stride = ALIGN(DIV_ROUND_UP(width, 48), 64); 979ab1eda44SAniket Masule y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16); 980ab1eda44SAniket Masule y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K); 981ab1eda44SAniket Masule uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64); 982ab1eda44SAniket Masule uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16); 983ab1eda44SAniket Masule uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K); 984ab1eda44SAniket Masule 985ab1eda44SAniket Masule size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane; 986ab1eda44SAniket Masule size += max(extradata + SZ_8K, y_stride * 48); 987ab1eda44SAniket Masule 988ab1eda44SAniket Masule return ALIGN(size, SZ_4K); 989ab1eda44SAniket Masule } 990ab1eda44SAniket Masule 991e1cb72deSStanimir Varbanov u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height) 992e1cb72deSStanimir Varbanov { 993e1cb72deSStanimir Varbanov switch (hfi_fmt) { 994e1cb72deSStanimir Varbanov case HFI_COLOR_FORMAT_NV12: 995e1cb72deSStanimir Varbanov case HFI_COLOR_FORMAT_NV21: 996e1cb72deSStanimir Varbanov return get_framesize_raw_nv12(width, height); 997e1cb72deSStanimir Varbanov case HFI_COLOR_FORMAT_NV12_UBWC: 998e1cb72deSStanimir Varbanov return get_framesize_raw_nv12_ubwc(width, height); 999ab1eda44SAniket Masule case HFI_COLOR_FORMAT_P010: 1000ab1eda44SAniket Masule return get_framesize_raw_p010(width, height); 1001ab1eda44SAniket Masule case HFI_COLOR_FORMAT_P010_UBWC: 1002ab1eda44SAniket Masule return get_framesize_raw_p010_ubwc(width, height); 1003ab1eda44SAniket Masule case HFI_COLOR_FORMAT_YUV420_TP10_UBWC: 1004ab1eda44SAniket Masule return get_framesize_raw_yuv420_tp10_ubwc(width, height); 1005e1cb72deSStanimir Varbanov default: 1006e1cb72deSStanimir Varbanov return 0; 1007e1cb72deSStanimir Varbanov } 1008e1cb72deSStanimir Varbanov } 1009e1cb72deSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_framesz_raw); 1010e1cb72deSStanimir Varbanov 1011e1cb72deSStanimir Varbanov u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height) 1012e1cb72deSStanimir Varbanov { 1013e1cb72deSStanimir Varbanov u32 hfi_fmt, sz; 1014e1cb72deSStanimir Varbanov bool compressed; 1015e1cb72deSStanimir Varbanov 1016e1cb72deSStanimir Varbanov switch (v4l2_fmt) { 1017e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_MPEG: 1018e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_H264: 1019e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_H264_NO_SC: 1020e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_H264_MVC: 1021e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_H263: 1022e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_MPEG1: 1023e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_MPEG2: 1024e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_MPEG4: 1025e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_XVID: 1026e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_VC1_ANNEX_G: 1027e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_VC1_ANNEX_L: 1028e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_VP8: 1029e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_VP9: 1030e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_HEVC: 1031e1cb72deSStanimir Varbanov compressed = true; 1032e1cb72deSStanimir Varbanov break; 1033e1cb72deSStanimir Varbanov default: 1034e1cb72deSStanimir Varbanov compressed = false; 1035e1cb72deSStanimir Varbanov break; 1036e1cb72deSStanimir Varbanov } 1037e1cb72deSStanimir Varbanov 1038e1cb72deSStanimir Varbanov if (compressed) { 1039e1cb72deSStanimir Varbanov sz = ALIGN(height, 32) * ALIGN(width, 32) * 3 / 2 / 2; 1040ddd1fc49SStanimir Varbanov if (width < 1280 || height < 720) 1041ddd1fc49SStanimir Varbanov sz *= 8; 1042e1cb72deSStanimir Varbanov return ALIGN(sz, SZ_4K); 1043e1cb72deSStanimir Varbanov } 1044e1cb72deSStanimir Varbanov 1045e1cb72deSStanimir Varbanov hfi_fmt = to_hfi_raw_fmt(v4l2_fmt); 1046e1cb72deSStanimir Varbanov if (!hfi_fmt) 1047e1cb72deSStanimir Varbanov return 0; 1048e1cb72deSStanimir Varbanov 1049e1cb72deSStanimir Varbanov return venus_helper_get_framesz_raw(hfi_fmt, width, height); 1050e1cb72deSStanimir Varbanov } 1051e1cb72deSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_framesz); 1052e1cb72deSStanimir Varbanov 1053af2c3834SStanimir Varbanov int venus_helper_set_input_resolution(struct venus_inst *inst, 1054af2c3834SStanimir Varbanov unsigned int width, unsigned int height) 1055af2c3834SStanimir Varbanov { 1056af2c3834SStanimir Varbanov u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE; 1057af2c3834SStanimir Varbanov struct hfi_framesize fs; 1058af2c3834SStanimir Varbanov 1059af2c3834SStanimir Varbanov fs.buffer_type = HFI_BUFFER_INPUT; 1060af2c3834SStanimir Varbanov fs.width = width; 1061af2c3834SStanimir Varbanov fs.height = height; 1062af2c3834SStanimir Varbanov 1063af2c3834SStanimir Varbanov return hfi_session_set_property(inst, ptype, &fs); 1064af2c3834SStanimir Varbanov } 1065af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_input_resolution); 1066af2c3834SStanimir Varbanov 1067af2c3834SStanimir Varbanov int venus_helper_set_output_resolution(struct venus_inst *inst, 1068404054e1SStanimir Varbanov unsigned int width, unsigned int height, 1069404054e1SStanimir Varbanov u32 buftype) 1070af2c3834SStanimir Varbanov { 1071af2c3834SStanimir Varbanov u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE; 1072af2c3834SStanimir Varbanov struct hfi_framesize fs; 1073af2c3834SStanimir Varbanov 1074404054e1SStanimir Varbanov fs.buffer_type = buftype; 1075af2c3834SStanimir Varbanov fs.width = width; 1076af2c3834SStanimir Varbanov fs.height = height; 1077af2c3834SStanimir Varbanov 1078af2c3834SStanimir Varbanov return hfi_session_set_property(inst, ptype, &fs); 1079af2c3834SStanimir Varbanov } 1080af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_output_resolution); 1081af2c3834SStanimir Varbanov 108201165b84SStanimir Varbanov int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode) 108301165b84SStanimir Varbanov { 108401165b84SStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_WORK_MODE; 108501165b84SStanimir Varbanov struct hfi_video_work_mode wm; 108601165b84SStanimir Varbanov 108701165b84SStanimir Varbanov if (!IS_V4(inst->core)) 108801165b84SStanimir Varbanov return 0; 108901165b84SStanimir Varbanov 109001165b84SStanimir Varbanov wm.video_work_mode = mode; 109101165b84SStanimir Varbanov 109201165b84SStanimir Varbanov return hfi_session_set_property(inst, ptype, &wm); 109301165b84SStanimir Varbanov } 109401165b84SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_work_mode); 109501165b84SStanimir Varbanov 1096af2c3834SStanimir Varbanov int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, 10971eb04b2eSStanimir Varbanov unsigned int output_bufs, 10981eb04b2eSStanimir Varbanov unsigned int output2_bufs) 1099af2c3834SStanimir Varbanov { 1100af2c3834SStanimir Varbanov u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL; 1101af2c3834SStanimir Varbanov struct hfi_buffer_count_actual buf_count; 1102af2c3834SStanimir Varbanov int ret; 1103af2c3834SStanimir Varbanov 1104af2c3834SStanimir Varbanov buf_count.type = HFI_BUFFER_INPUT; 1105af2c3834SStanimir Varbanov buf_count.count_actual = input_bufs; 1106af2c3834SStanimir Varbanov 1107af2c3834SStanimir Varbanov ret = hfi_session_set_property(inst, ptype, &buf_count); 1108af2c3834SStanimir Varbanov if (ret) 1109af2c3834SStanimir Varbanov return ret; 1110af2c3834SStanimir Varbanov 1111af2c3834SStanimir Varbanov buf_count.type = HFI_BUFFER_OUTPUT; 1112af2c3834SStanimir Varbanov buf_count.count_actual = output_bufs; 1113af2c3834SStanimir Varbanov 11141eb04b2eSStanimir Varbanov ret = hfi_session_set_property(inst, ptype, &buf_count); 11151eb04b2eSStanimir Varbanov if (ret) 11161eb04b2eSStanimir Varbanov return ret; 11171eb04b2eSStanimir Varbanov 11181eb04b2eSStanimir Varbanov if (output2_bufs) { 11191eb04b2eSStanimir Varbanov buf_count.type = HFI_BUFFER_OUTPUT2; 11201eb04b2eSStanimir Varbanov buf_count.count_actual = output2_bufs; 11211eb04b2eSStanimir Varbanov 11221eb04b2eSStanimir Varbanov ret = hfi_session_set_property(inst, ptype, &buf_count); 11231eb04b2eSStanimir Varbanov } 11241eb04b2eSStanimir Varbanov 11251eb04b2eSStanimir Varbanov return ret; 1126af2c3834SStanimir Varbanov } 1127af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_num_bufs); 1128af2c3834SStanimir Varbanov 1129ab97a3fbSStanimir Varbanov int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format, 1130ab97a3fbSStanimir Varbanov u32 buftype) 1131ab97a3fbSStanimir Varbanov { 1132ab97a3fbSStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT; 1133ab97a3fbSStanimir Varbanov struct hfi_uncompressed_format_select fmt; 1134ab97a3fbSStanimir Varbanov 1135ab97a3fbSStanimir Varbanov fmt.buffer_type = buftype; 1136ab97a3fbSStanimir Varbanov fmt.format = hfi_format; 1137ab97a3fbSStanimir Varbanov 1138ab97a3fbSStanimir Varbanov return hfi_session_set_property(inst, ptype, &fmt); 1139ab97a3fbSStanimir Varbanov } 1140ab97a3fbSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_raw_format); 1141ab97a3fbSStanimir Varbanov 1142af2c3834SStanimir Varbanov int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt) 1143af2c3834SStanimir Varbanov { 1144ab97a3fbSStanimir Varbanov u32 hfi_format, buftype; 1145af2c3834SStanimir Varbanov 1146af2c3834SStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_DEC) 1147ab97a3fbSStanimir Varbanov buftype = HFI_BUFFER_OUTPUT; 1148af2c3834SStanimir Varbanov else if (inst->session_type == VIDC_SESSION_TYPE_ENC) 1149ab97a3fbSStanimir Varbanov buftype = HFI_BUFFER_INPUT; 1150af2c3834SStanimir Varbanov else 1151af2c3834SStanimir Varbanov return -EINVAL; 1152af2c3834SStanimir Varbanov 1153ab97a3fbSStanimir Varbanov hfi_format = to_hfi_raw_fmt(pixfmt); 1154ab97a3fbSStanimir Varbanov if (!hfi_format) 1155af2c3834SStanimir Varbanov return -EINVAL; 1156af2c3834SStanimir Varbanov 1157ab97a3fbSStanimir Varbanov return venus_helper_set_raw_format(inst, hfi_format, buftype); 1158af2c3834SStanimir Varbanov } 1159af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_color_format); 1160af2c3834SStanimir Varbanov 1161f012b23dSStanimir Varbanov int venus_helper_set_multistream(struct venus_inst *inst, bool out_en, 1162f012b23dSStanimir Varbanov bool out2_en) 1163f012b23dSStanimir Varbanov { 1164f012b23dSStanimir Varbanov struct hfi_multi_stream multi = {0}; 1165f012b23dSStanimir Varbanov u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM; 1166f012b23dSStanimir Varbanov int ret; 1167f012b23dSStanimir Varbanov 1168f012b23dSStanimir Varbanov multi.buffer_type = HFI_BUFFER_OUTPUT; 1169f012b23dSStanimir Varbanov multi.enable = out_en; 1170f012b23dSStanimir Varbanov 1171f012b23dSStanimir Varbanov ret = hfi_session_set_property(inst, ptype, &multi); 1172f012b23dSStanimir Varbanov if (ret) 1173f012b23dSStanimir Varbanov return ret; 1174f012b23dSStanimir Varbanov 1175f012b23dSStanimir Varbanov multi.buffer_type = HFI_BUFFER_OUTPUT2; 1176f012b23dSStanimir Varbanov multi.enable = out2_en; 1177f012b23dSStanimir Varbanov 1178f012b23dSStanimir Varbanov return hfi_session_set_property(inst, ptype, &multi); 1179f012b23dSStanimir Varbanov } 1180f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_multistream); 1181f012b23dSStanimir Varbanov 11822b0a8517SStanimir Varbanov int venus_helper_set_dyn_bufmode(struct venus_inst *inst) 11832b0a8517SStanimir Varbanov { 11842b0a8517SStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE; 11852b0a8517SStanimir Varbanov struct hfi_buffer_alloc_mode mode; 11862b0a8517SStanimir Varbanov int ret; 11872b0a8517SStanimir Varbanov 11882b0a8517SStanimir Varbanov if (!is_dynamic_bufmode(inst)) 11892b0a8517SStanimir Varbanov return 0; 11902b0a8517SStanimir Varbanov 11912b0a8517SStanimir Varbanov mode.type = HFI_BUFFER_OUTPUT; 11922b0a8517SStanimir Varbanov mode.mode = HFI_BUFFER_MODE_DYNAMIC; 11932b0a8517SStanimir Varbanov 11942b0a8517SStanimir Varbanov ret = hfi_session_set_property(inst, ptype, &mode); 11952b0a8517SStanimir Varbanov if (ret) 11962b0a8517SStanimir Varbanov return ret; 11972b0a8517SStanimir Varbanov 11982b0a8517SStanimir Varbanov mode.type = HFI_BUFFER_OUTPUT2; 11992b0a8517SStanimir Varbanov 12002b0a8517SStanimir Varbanov return hfi_session_set_property(inst, ptype, &mode); 12012b0a8517SStanimir Varbanov } 12022b0a8517SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_dyn_bufmode); 12032b0a8517SStanimir Varbanov 1204d4a5b0a6SStanimir Varbanov int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype) 1205d4a5b0a6SStanimir Varbanov { 1206d4a5b0a6SStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL; 1207d4a5b0a6SStanimir Varbanov struct hfi_buffer_size_actual bufsz; 1208d4a5b0a6SStanimir Varbanov 1209d4a5b0a6SStanimir Varbanov bufsz.type = buftype; 1210d4a5b0a6SStanimir Varbanov bufsz.size = bufsize; 1211d4a5b0a6SStanimir Varbanov 1212d4a5b0a6SStanimir Varbanov return hfi_session_set_property(inst, ptype, &bufsz); 1213d4a5b0a6SStanimir Varbanov } 1214d4a5b0a6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_bufsize); 1215d4a5b0a6SStanimir Varbanov 1216130c0117SStanimir Varbanov unsigned int venus_helper_get_opb_size(struct venus_inst *inst) 1217130c0117SStanimir Varbanov { 1218130c0117SStanimir Varbanov /* the encoder has only one output */ 1219130c0117SStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_ENC) 1220130c0117SStanimir Varbanov return inst->output_buf_size; 1221130c0117SStanimir Varbanov 1222130c0117SStanimir Varbanov if (inst->opb_buftype == HFI_BUFFER_OUTPUT) 1223130c0117SStanimir Varbanov return inst->output_buf_size; 1224130c0117SStanimir Varbanov else if (inst->opb_buftype == HFI_BUFFER_OUTPUT2) 1225130c0117SStanimir Varbanov return inst->output2_buf_size; 1226130c0117SStanimir Varbanov 1227130c0117SStanimir Varbanov return 0; 1228130c0117SStanimir Varbanov } 1229130c0117SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_opb_size); 1230130c0117SStanimir Varbanov 1231af2c3834SStanimir Varbanov static void delayed_process_buf_func(struct work_struct *work) 1232af2c3834SStanimir Varbanov { 1233af2c3834SStanimir Varbanov struct venus_buffer *buf, *n; 1234af2c3834SStanimir Varbanov struct venus_inst *inst; 1235af2c3834SStanimir Varbanov int ret; 1236af2c3834SStanimir Varbanov 1237af2c3834SStanimir Varbanov inst = container_of(work, struct venus_inst, delayed_process_work); 1238af2c3834SStanimir Varbanov 1239af2c3834SStanimir Varbanov mutex_lock(&inst->lock); 1240af2c3834SStanimir Varbanov 1241af2c3834SStanimir Varbanov if (!(inst->streamon_out & inst->streamon_cap)) 1242af2c3834SStanimir Varbanov goto unlock; 1243af2c3834SStanimir Varbanov 1244af2c3834SStanimir Varbanov list_for_each_entry_safe(buf, n, &inst->delayed_process, ref_list) { 1245af2c3834SStanimir Varbanov if (buf->flags & HFI_BUFFERFLAG_READONLY) 1246af2c3834SStanimir Varbanov continue; 1247af2c3834SStanimir Varbanov 1248af2c3834SStanimir Varbanov ret = session_process_buf(inst, &buf->vb); 1249af2c3834SStanimir Varbanov if (ret) 1250af2c3834SStanimir Varbanov return_buf_error(inst, &buf->vb); 1251af2c3834SStanimir Varbanov 1252af2c3834SStanimir Varbanov list_del_init(&buf->ref_list); 1253af2c3834SStanimir Varbanov } 1254af2c3834SStanimir Varbanov unlock: 1255af2c3834SStanimir Varbanov mutex_unlock(&inst->lock); 1256af2c3834SStanimir Varbanov } 1257af2c3834SStanimir Varbanov 1258af2c3834SStanimir Varbanov void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx) 1259af2c3834SStanimir Varbanov { 1260af2c3834SStanimir Varbanov struct venus_buffer *buf; 1261af2c3834SStanimir Varbanov 1262af2c3834SStanimir Varbanov list_for_each_entry(buf, &inst->registeredbufs, reg_list) { 1263af2c3834SStanimir Varbanov if (buf->vb.vb2_buf.index == idx) { 1264af2c3834SStanimir Varbanov buf->flags &= ~HFI_BUFFERFLAG_READONLY; 1265af2c3834SStanimir Varbanov schedule_work(&inst->delayed_process_work); 1266af2c3834SStanimir Varbanov break; 1267af2c3834SStanimir Varbanov } 1268af2c3834SStanimir Varbanov } 1269af2c3834SStanimir Varbanov } 1270af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_release_buf_ref); 1271af2c3834SStanimir Varbanov 1272af2c3834SStanimir Varbanov void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf) 1273af2c3834SStanimir Varbanov { 1274af2c3834SStanimir Varbanov struct venus_buffer *buf = to_venus_buffer(vbuf); 1275af2c3834SStanimir Varbanov 1276af2c3834SStanimir Varbanov buf->flags |= HFI_BUFFERFLAG_READONLY; 1277af2c3834SStanimir Varbanov } 1278af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_acquire_buf_ref); 1279af2c3834SStanimir Varbanov 1280af2c3834SStanimir Varbanov static int is_buf_refed(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) 1281af2c3834SStanimir Varbanov { 1282af2c3834SStanimir Varbanov struct venus_buffer *buf = to_venus_buffer(vbuf); 1283af2c3834SStanimir Varbanov 1284af2c3834SStanimir Varbanov if (buf->flags & HFI_BUFFERFLAG_READONLY) { 1285af2c3834SStanimir Varbanov list_add_tail(&buf->ref_list, &inst->delayed_process); 1286af2c3834SStanimir Varbanov schedule_work(&inst->delayed_process_work); 1287af2c3834SStanimir Varbanov return 1; 1288af2c3834SStanimir Varbanov } 1289af2c3834SStanimir Varbanov 1290af2c3834SStanimir Varbanov return 0; 1291af2c3834SStanimir Varbanov } 1292af2c3834SStanimir Varbanov 1293af2c3834SStanimir Varbanov struct vb2_v4l2_buffer * 1294af2c3834SStanimir Varbanov venus_helper_find_buf(struct venus_inst *inst, unsigned int type, u32 idx) 1295af2c3834SStanimir Varbanov { 1296af2c3834SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 1297af2c3834SStanimir Varbanov 1298af2c3834SStanimir Varbanov if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1299af2c3834SStanimir Varbanov return v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, idx); 1300af2c3834SStanimir Varbanov else 1301af2c3834SStanimir Varbanov return v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx, idx); 1302af2c3834SStanimir Varbanov } 1303af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_find_buf); 1304af2c3834SStanimir Varbanov 1305af2c3834SStanimir Varbanov int venus_helper_vb2_buf_init(struct vb2_buffer *vb) 1306af2c3834SStanimir Varbanov { 1307af2c3834SStanimir Varbanov struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1308af2c3834SStanimir Varbanov struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1309af2c3834SStanimir Varbanov struct venus_buffer *buf = to_venus_buffer(vbuf); 1310af2c3834SStanimir Varbanov 1311af2c3834SStanimir Varbanov buf->size = vb2_plane_size(vb, 0); 1312cc82fd69SAlexandre Courbot buf->dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); 1313af2c3834SStanimir Varbanov 1314af2c3834SStanimir Varbanov if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1315af2c3834SStanimir Varbanov list_add_tail(&buf->reg_list, &inst->registeredbufs); 1316af2c3834SStanimir Varbanov 1317af2c3834SStanimir Varbanov return 0; 1318af2c3834SStanimir Varbanov } 1319af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_init); 1320af2c3834SStanimir Varbanov 1321af2c3834SStanimir Varbanov int venus_helper_vb2_buf_prepare(struct vb2_buffer *vb) 1322af2c3834SStanimir Varbanov { 1323af2c3834SStanimir Varbanov struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1324f012b23dSStanimir Varbanov unsigned int out_buf_size = venus_helper_get_opb_size(inst); 132505979046SStanimir Varbanov struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 132605979046SStanimir Varbanov 132705979046SStanimir Varbanov if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { 132805979046SStanimir Varbanov if (vbuf->field == V4L2_FIELD_ANY) 132905979046SStanimir Varbanov vbuf->field = V4L2_FIELD_NONE; 133005979046SStanimir Varbanov if (vbuf->field != V4L2_FIELD_NONE) { 133105979046SStanimir Varbanov dev_err(inst->core->dev, "%s field isn't supported\n", 133205979046SStanimir Varbanov __func__); 133305979046SStanimir Varbanov return -EINVAL; 133405979046SStanimir Varbanov } 133505979046SStanimir Varbanov } 1336af2c3834SStanimir Varbanov 1337af2c3834SStanimir Varbanov if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 1338f012b23dSStanimir Varbanov vb2_plane_size(vb, 0) < out_buf_size) 1339af2c3834SStanimir Varbanov return -EINVAL; 1340af2c3834SStanimir Varbanov if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 1341af2c3834SStanimir Varbanov vb2_plane_size(vb, 0) < inst->input_buf_size) 1342af2c3834SStanimir Varbanov return -EINVAL; 1343af2c3834SStanimir Varbanov 1344af2c3834SStanimir Varbanov return 0; 1345af2c3834SStanimir Varbanov } 1346af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_prepare); 1347af2c3834SStanimir Varbanov 1348fd1ee315SStanimir Varbanov static void cache_payload(struct venus_inst *inst, struct vb2_buffer *vb) 1349fd1ee315SStanimir Varbanov { 1350fd1ee315SStanimir Varbanov struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1351fd1ee315SStanimir Varbanov unsigned int idx = vbuf->vb2_buf.index; 1352fd1ee315SStanimir Varbanov 1353fd1ee315SStanimir Varbanov if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1354fd1ee315SStanimir Varbanov inst->payloads[idx] = vb2_get_plane_payload(vb, 0); 1355fd1ee315SStanimir Varbanov } 1356fd1ee315SStanimir Varbanov 1357af2c3834SStanimir Varbanov void venus_helper_vb2_buf_queue(struct vb2_buffer *vb) 1358af2c3834SStanimir Varbanov { 1359af2c3834SStanimir Varbanov struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1360af2c3834SStanimir Varbanov struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1361af2c3834SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 1362af2c3834SStanimir Varbanov int ret; 1363af2c3834SStanimir Varbanov 1364af2c3834SStanimir Varbanov v4l2_m2m_buf_queue(m2m_ctx, vbuf); 1365af2c3834SStanimir Varbanov 1366acf8a57dSStanimir Varbanov /* Skip processing queued capture buffers after LAST flag */ 1367acf8a57dSStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_DEC && 1368acf8a57dSStanimir Varbanov V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && 1369acf8a57dSStanimir Varbanov inst->codec_state == VENUS_DEC_STATE_DRC) 137021560ddfSStanimir Varbanov return; 1371acf8a57dSStanimir Varbanov 1372fd1ee315SStanimir Varbanov cache_payload(inst, vb); 1373fd1ee315SStanimir Varbanov 1374beac8290SStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_ENC && 1375beac8290SStanimir Varbanov !(inst->streamon_out && inst->streamon_cap)) 137621560ddfSStanimir Varbanov return; 1377af2c3834SStanimir Varbanov 1378beac8290SStanimir Varbanov if (vb2_start_streaming_called(vb->vb2_queue)) { 1379af2c3834SStanimir Varbanov ret = is_buf_refed(inst, vbuf); 1380af2c3834SStanimir Varbanov if (ret) 138121560ddfSStanimir Varbanov return; 1382af2c3834SStanimir Varbanov 1383af2c3834SStanimir Varbanov ret = session_process_buf(inst, vbuf); 1384af2c3834SStanimir Varbanov if (ret) 1385af2c3834SStanimir Varbanov return_buf_error(inst, vbuf); 1386beac8290SStanimir Varbanov } 1387af2c3834SStanimir Varbanov } 1388af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_queue); 1389af2c3834SStanimir Varbanov 13900febf923SStanimir Varbanov void venus_helper_buffers_done(struct venus_inst *inst, unsigned int type, 1391af2c3834SStanimir Varbanov enum vb2_buffer_state state) 1392af2c3834SStanimir Varbanov { 1393af2c3834SStanimir Varbanov struct vb2_v4l2_buffer *buf; 1394af2c3834SStanimir Varbanov 13950febf923SStanimir Varbanov if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 1396af2c3834SStanimir Varbanov while ((buf = v4l2_m2m_src_buf_remove(inst->m2m_ctx))) 1397af2c3834SStanimir Varbanov v4l2_m2m_buf_done(buf, state); 13980febf923SStanimir Varbanov } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 1399af2c3834SStanimir Varbanov while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx))) 1400af2c3834SStanimir Varbanov v4l2_m2m_buf_done(buf, state); 1401af2c3834SStanimir Varbanov } 14020febf923SStanimir Varbanov } 1403af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_buffers_done); 1404af2c3834SStanimir Varbanov 1405af2c3834SStanimir Varbanov void venus_helper_vb2_stop_streaming(struct vb2_queue *q) 1406af2c3834SStanimir Varbanov { 1407af2c3834SStanimir Varbanov struct venus_inst *inst = vb2_get_drv_priv(q); 1408af2c3834SStanimir Varbanov struct venus_core *core = inst->core; 1409af2c3834SStanimir Varbanov int ret; 1410af2c3834SStanimir Varbanov 1411af2c3834SStanimir Varbanov mutex_lock(&inst->lock); 1412af2c3834SStanimir Varbanov 1413af2c3834SStanimir Varbanov if (inst->streamon_out & inst->streamon_cap) { 1414af2c3834SStanimir Varbanov ret = hfi_session_stop(inst); 1415af2c3834SStanimir Varbanov ret |= hfi_session_unload_res(inst); 14161e485ee5SStanimir Varbanov ret |= venus_helper_unregister_bufs(inst); 14171e485ee5SStanimir Varbanov ret |= venus_helper_intbufs_free(inst); 1418af2c3834SStanimir Varbanov ret |= hfi_session_deinit(inst); 1419af2c3834SStanimir Varbanov 1420af2c3834SStanimir Varbanov if (inst->session_error || core->sys_error) 1421af2c3834SStanimir Varbanov ret = -EIO; 1422af2c3834SStanimir Varbanov 1423af2c3834SStanimir Varbanov if (ret) 1424af2c3834SStanimir Varbanov hfi_session_abort(inst); 1425af2c3834SStanimir Varbanov 1426f012b23dSStanimir Varbanov venus_helper_free_dpb_bufs(inst); 1427f012b23dSStanimir Varbanov 14287482a983SStanimir Varbanov venus_pm_load_scale(inst); 1429bbd770aeSStanimir Varbanov INIT_LIST_HEAD(&inst->registeredbufs); 1430af2c3834SStanimir Varbanov } 1431af2c3834SStanimir Varbanov 14320febf923SStanimir Varbanov venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 14330febf923SStanimir Varbanov VB2_BUF_STATE_ERROR); 14340febf923SStanimir Varbanov venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 14350febf923SStanimir Varbanov VB2_BUF_STATE_ERROR); 1436af2c3834SStanimir Varbanov 1437af2c3834SStanimir Varbanov if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1438af2c3834SStanimir Varbanov inst->streamon_out = 0; 1439af2c3834SStanimir Varbanov else 1440af2c3834SStanimir Varbanov inst->streamon_cap = 0; 1441af2c3834SStanimir Varbanov 14424ebf9693SAniket Masule venus_pm_release_core(inst); 14434ebf9693SAniket Masule 1444af2c3834SStanimir Varbanov mutex_unlock(&inst->lock); 1445af2c3834SStanimir Varbanov } 1446af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming); 1447af2c3834SStanimir Varbanov 144814ea00d6SStanimir Varbanov int venus_helper_process_initial_cap_bufs(struct venus_inst *inst) 144914ea00d6SStanimir Varbanov { 145014ea00d6SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 145114ea00d6SStanimir Varbanov struct v4l2_m2m_buffer *buf, *n; 145214ea00d6SStanimir Varbanov int ret; 145314ea00d6SStanimir Varbanov 145414ea00d6SStanimir Varbanov v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) { 145514ea00d6SStanimir Varbanov ret = session_process_buf(inst, &buf->vb); 145614ea00d6SStanimir Varbanov if (ret) { 145714ea00d6SStanimir Varbanov return_buf_error(inst, &buf->vb); 145814ea00d6SStanimir Varbanov return ret; 145914ea00d6SStanimir Varbanov } 146014ea00d6SStanimir Varbanov } 146114ea00d6SStanimir Varbanov 146214ea00d6SStanimir Varbanov return 0; 146314ea00d6SStanimir Varbanov } 146414ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_process_initial_cap_bufs); 146514ea00d6SStanimir Varbanov 146614ea00d6SStanimir Varbanov int venus_helper_process_initial_out_bufs(struct venus_inst *inst) 146714ea00d6SStanimir Varbanov { 146814ea00d6SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 146914ea00d6SStanimir Varbanov struct v4l2_m2m_buffer *buf, *n; 147014ea00d6SStanimir Varbanov int ret; 147114ea00d6SStanimir Varbanov 147214ea00d6SStanimir Varbanov v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) { 147314ea00d6SStanimir Varbanov ret = session_process_buf(inst, &buf->vb); 147414ea00d6SStanimir Varbanov if (ret) { 147514ea00d6SStanimir Varbanov return_buf_error(inst, &buf->vb); 147614ea00d6SStanimir Varbanov return ret; 147714ea00d6SStanimir Varbanov } 147814ea00d6SStanimir Varbanov } 147914ea00d6SStanimir Varbanov 148014ea00d6SStanimir Varbanov return 0; 148114ea00d6SStanimir Varbanov } 148214ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_process_initial_out_bufs); 148314ea00d6SStanimir Varbanov 1484af2c3834SStanimir Varbanov int venus_helper_vb2_start_streaming(struct venus_inst *inst) 1485af2c3834SStanimir Varbanov { 1486af2c3834SStanimir Varbanov int ret; 1487af2c3834SStanimir Varbanov 14881e485ee5SStanimir Varbanov ret = venus_helper_intbufs_alloc(inst); 1489af2c3834SStanimir Varbanov if (ret) 1490af2c3834SStanimir Varbanov return ret; 1491af2c3834SStanimir Varbanov 1492af2c3834SStanimir Varbanov ret = session_register_bufs(inst); 1493af2c3834SStanimir Varbanov if (ret) 1494af2c3834SStanimir Varbanov goto err_bufs_free; 1495af2c3834SStanimir Varbanov 14967482a983SStanimir Varbanov venus_pm_load_scale(inst); 1497af2c3834SStanimir Varbanov 1498af2c3834SStanimir Varbanov ret = hfi_session_load_res(inst); 1499af2c3834SStanimir Varbanov if (ret) 1500af2c3834SStanimir Varbanov goto err_unreg_bufs; 1501af2c3834SStanimir Varbanov 1502af2c3834SStanimir Varbanov ret = hfi_session_start(inst); 1503af2c3834SStanimir Varbanov if (ret) 1504af2c3834SStanimir Varbanov goto err_unload_res; 1505af2c3834SStanimir Varbanov 1506af2c3834SStanimir Varbanov return 0; 1507af2c3834SStanimir Varbanov 1508af2c3834SStanimir Varbanov err_unload_res: 1509af2c3834SStanimir Varbanov hfi_session_unload_res(inst); 1510af2c3834SStanimir Varbanov err_unreg_bufs: 15111e485ee5SStanimir Varbanov venus_helper_unregister_bufs(inst); 1512af2c3834SStanimir Varbanov err_bufs_free: 15131e485ee5SStanimir Varbanov venus_helper_intbufs_free(inst); 1514af2c3834SStanimir Varbanov return ret; 1515af2c3834SStanimir Varbanov } 1516af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_start_streaming); 1517af2c3834SStanimir Varbanov 1518af2c3834SStanimir Varbanov void venus_helper_m2m_device_run(void *priv) 1519af2c3834SStanimir Varbanov { 1520af2c3834SStanimir Varbanov struct venus_inst *inst = priv; 1521af2c3834SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 1522af2c3834SStanimir Varbanov struct v4l2_m2m_buffer *buf, *n; 1523af2c3834SStanimir Varbanov int ret; 1524af2c3834SStanimir Varbanov 1525af2c3834SStanimir Varbanov mutex_lock(&inst->lock); 1526af2c3834SStanimir Varbanov 1527af2c3834SStanimir Varbanov v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) { 1528af2c3834SStanimir Varbanov ret = session_process_buf(inst, &buf->vb); 1529af2c3834SStanimir Varbanov if (ret) 1530af2c3834SStanimir Varbanov return_buf_error(inst, &buf->vb); 1531af2c3834SStanimir Varbanov } 1532af2c3834SStanimir Varbanov 1533af2c3834SStanimir Varbanov v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) { 1534af2c3834SStanimir Varbanov ret = session_process_buf(inst, &buf->vb); 1535af2c3834SStanimir Varbanov if (ret) 1536af2c3834SStanimir Varbanov return_buf_error(inst, &buf->vb); 1537af2c3834SStanimir Varbanov } 1538af2c3834SStanimir Varbanov 1539af2c3834SStanimir Varbanov mutex_unlock(&inst->lock); 1540af2c3834SStanimir Varbanov } 1541af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_m2m_device_run); 1542af2c3834SStanimir Varbanov 1543af2c3834SStanimir Varbanov void venus_helper_m2m_job_abort(void *priv) 1544af2c3834SStanimir Varbanov { 1545af2c3834SStanimir Varbanov struct venus_inst *inst = priv; 1546af2c3834SStanimir Varbanov 1547af2c3834SStanimir Varbanov v4l2_m2m_job_finish(inst->m2m_dev, inst->m2m_ctx); 1548af2c3834SStanimir Varbanov } 1549af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_m2m_job_abort); 1550af2c3834SStanimir Varbanov 1551aa603389SStanimir Varbanov int venus_helper_session_init(struct venus_inst *inst) 1552aa603389SStanimir Varbanov { 1553aa603389SStanimir Varbanov enum hfi_version version = inst->core->res->hfi_version; 1554aa603389SStanimir Varbanov u32 session_type = inst->session_type; 1555aa603389SStanimir Varbanov u32 codec; 1556aa603389SStanimir Varbanov int ret; 1557aa603389SStanimir Varbanov 1558aa603389SStanimir Varbanov codec = inst->session_type == VIDC_SESSION_TYPE_DEC ? 1559aa603389SStanimir Varbanov inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt; 1560aa603389SStanimir Varbanov 1561aa603389SStanimir Varbanov ret = hfi_session_init(inst, codec); 1562aa603389SStanimir Varbanov if (ret) 1563aa603389SStanimir Varbanov return ret; 1564aa603389SStanimir Varbanov 1565aa603389SStanimir Varbanov inst->clk_data.vpp_freq = hfi_platform_get_codec_vpp_freq(version, codec, 1566aa603389SStanimir Varbanov session_type); 1567aa603389SStanimir Varbanov inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(version, codec, 1568aa603389SStanimir Varbanov session_type); 1569aa603389SStanimir Varbanov 1570aa603389SStanimir Varbanov return 0; 1571aa603389SStanimir Varbanov } 1572aa603389SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_session_init); 1573aa603389SStanimir Varbanov 1574af2c3834SStanimir Varbanov void venus_helper_init_instance(struct venus_inst *inst) 1575af2c3834SStanimir Varbanov { 1576af2c3834SStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_DEC) { 1577af2c3834SStanimir Varbanov INIT_LIST_HEAD(&inst->delayed_process); 1578af2c3834SStanimir Varbanov INIT_WORK(&inst->delayed_process_work, 1579af2c3834SStanimir Varbanov delayed_process_buf_func); 1580af2c3834SStanimir Varbanov } 1581af2c3834SStanimir Varbanov } 1582af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_init_instance); 1583aa3a8414SStanimir Varbanov 15848f3b41dcSStanimir Varbanov static bool find_fmt_from_caps(struct hfi_plat_caps *caps, u32 buftype, u32 fmt) 1585f012b23dSStanimir Varbanov { 1586f012b23dSStanimir Varbanov unsigned int i; 1587f012b23dSStanimir Varbanov 1588f012b23dSStanimir Varbanov for (i = 0; i < caps->num_fmts; i++) { 1589f012b23dSStanimir Varbanov if (caps->fmts[i].buftype == buftype && 1590f012b23dSStanimir Varbanov caps->fmts[i].fmt == fmt) 1591f012b23dSStanimir Varbanov return true; 1592f012b23dSStanimir Varbanov } 1593f012b23dSStanimir Varbanov 1594f012b23dSStanimir Varbanov return false; 1595f012b23dSStanimir Varbanov } 1596f012b23dSStanimir Varbanov 1597f012b23dSStanimir Varbanov int venus_helper_get_out_fmts(struct venus_inst *inst, u32 v4l2_fmt, 1598f012b23dSStanimir Varbanov u32 *out_fmt, u32 *out2_fmt, bool ubwc) 1599f012b23dSStanimir Varbanov { 1600f012b23dSStanimir Varbanov struct venus_core *core = inst->core; 16018f3b41dcSStanimir Varbanov struct hfi_plat_caps *caps; 1602f012b23dSStanimir Varbanov u32 ubwc_fmt, fmt = to_hfi_raw_fmt(v4l2_fmt); 1603f012b23dSStanimir Varbanov bool found, found_ubwc; 1604f012b23dSStanimir Varbanov 1605f012b23dSStanimir Varbanov *out_fmt = *out2_fmt = 0; 1606f012b23dSStanimir Varbanov 1607f012b23dSStanimir Varbanov if (!fmt) 1608f012b23dSStanimir Varbanov return -EINVAL; 1609f012b23dSStanimir Varbanov 1610f012b23dSStanimir Varbanov caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type); 1611f012b23dSStanimir Varbanov if (!caps) 1612f012b23dSStanimir Varbanov return -EINVAL; 1613f012b23dSStanimir Varbanov 1614ab1eda44SAniket Masule if (inst->bit_depth == VIDC_BITDEPTH_10 && 1615ab1eda44SAniket Masule inst->session_type == VIDC_SESSION_TYPE_DEC) { 1616ab1eda44SAniket Masule found_ubwc = 1617ab1eda44SAniket Masule find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, 1618ab1eda44SAniket Masule HFI_COLOR_FORMAT_YUV420_TP10_UBWC); 1619ab1eda44SAniket Masule found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, 1620ab1eda44SAniket Masule HFI_COLOR_FORMAT_NV12); 1621ab1eda44SAniket Masule if (found_ubwc && found) { 1622ab1eda44SAniket Masule /* 1623ab1eda44SAniket Masule * Hard-code DPB buffers to be 10bit UBWC and decoder 1624ab1eda44SAniket Masule * output buffers in 8bit NV12 until V4L2 is able to 1625ab1eda44SAniket Masule * expose compressed/tiled formats to applications. 1626ab1eda44SAniket Masule */ 1627ab1eda44SAniket Masule *out_fmt = HFI_COLOR_FORMAT_YUV420_TP10_UBWC; 1628ab1eda44SAniket Masule *out2_fmt = HFI_COLOR_FORMAT_NV12; 1629ab1eda44SAniket Masule return 0; 1630ab1eda44SAniket Masule } 1631ab1eda44SAniket Masule 1632ab1eda44SAniket Masule return -EINVAL; 1633ab1eda44SAniket Masule } 1634ab1eda44SAniket Masule 1635f012b23dSStanimir Varbanov if (ubwc) { 1636f012b23dSStanimir Varbanov ubwc_fmt = fmt | HFI_COLOR_FORMAT_UBWC_BASE; 1637f012b23dSStanimir Varbanov found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, 1638f012b23dSStanimir Varbanov ubwc_fmt); 1639f012b23dSStanimir Varbanov found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt); 1640f012b23dSStanimir Varbanov 1641f012b23dSStanimir Varbanov if (found_ubwc && found) { 1642f012b23dSStanimir Varbanov *out_fmt = ubwc_fmt; 1643f012b23dSStanimir Varbanov *out2_fmt = fmt; 1644f012b23dSStanimir Varbanov return 0; 1645f012b23dSStanimir Varbanov } 1646f012b23dSStanimir Varbanov } 1647f012b23dSStanimir Varbanov 1648f012b23dSStanimir Varbanov found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, fmt); 1649f012b23dSStanimir Varbanov if (found) { 1650f012b23dSStanimir Varbanov *out_fmt = fmt; 1651f012b23dSStanimir Varbanov *out2_fmt = 0; 1652f012b23dSStanimir Varbanov return 0; 1653f012b23dSStanimir Varbanov } 1654f012b23dSStanimir Varbanov 1655f012b23dSStanimir Varbanov found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt); 1656f012b23dSStanimir Varbanov if (found) { 1657f012b23dSStanimir Varbanov *out_fmt = 0; 1658f012b23dSStanimir Varbanov *out2_fmt = fmt; 1659f012b23dSStanimir Varbanov return 0; 1660f012b23dSStanimir Varbanov } 1661f012b23dSStanimir Varbanov 1662f012b23dSStanimir Varbanov return -EINVAL; 1663f012b23dSStanimir Varbanov } 1664f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_out_fmts); 1665