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 */ 640d87aafSMansur Alisha Shaik #include <linux/idr.h> 7af2c3834SStanimir Varbanov #include <linux/list.h> 8af2c3834SStanimir Varbanov #include <linux/mutex.h> 9af2c3834SStanimir Varbanov #include <linux/slab.h> 102c2dc2fdSStanimir Varbanov #include <linux/kernel.h> 11cc82fd69SAlexandre Courbot #include <media/videobuf2-dma-contig.h> 12af2c3834SStanimir Varbanov #include <media/v4l2-mem2mem.h> 13af2c3834SStanimir Varbanov #include <asm/div64.h> 14af2c3834SStanimir Varbanov 15af2c3834SStanimir Varbanov #include "core.h" 16af2c3834SStanimir Varbanov #include "helpers.h" 17af2c3834SStanimir Varbanov #include "hfi_helper.h" 187482a983SStanimir Varbanov #include "pm_helpers.h" 19aa603389SStanimir Varbanov #include "hfi_platform.h" 207371093fSStanimir Varbanov #include "hfi_parser.h" 21af2c3834SStanimir Varbanov 22fa622c3dSDikshita Agarwal #define NUM_MBS_720P (((ALIGN(1280, 16)) >> 4) * ((ALIGN(736, 16)) >> 4)) 23fa622c3dSDikshita Agarwal #define NUM_MBS_4K (((ALIGN(4096, 16)) >> 4) * ((ALIGN(2304, 16)) >> 4)) 241ad17595SDikshita Agarwal 2540d87aafSMansur Alisha Shaik enum dpb_buf_owner { 2640d87aafSMansur Alisha Shaik DRIVER, 2740d87aafSMansur Alisha Shaik FIRMWARE, 2840d87aafSMansur Alisha Shaik }; 2940d87aafSMansur Alisha Shaik 30af2c3834SStanimir Varbanov struct intbuf { 31af2c3834SStanimir Varbanov struct list_head list; 32af2c3834SStanimir Varbanov u32 type; 33af2c3834SStanimir Varbanov size_t size; 34af2c3834SStanimir Varbanov void *va; 35af2c3834SStanimir Varbanov dma_addr_t da; 36af2c3834SStanimir Varbanov unsigned long attrs; 3740d87aafSMansur Alisha Shaik enum dpb_buf_owner owned_by; 3840d87aafSMansur Alisha Shaik u32 dpb_out_tag; 39af2c3834SStanimir Varbanov }; 40af2c3834SStanimir Varbanov 41d8db57c2SStanimir Varbanov bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt) 42d8db57c2SStanimir Varbanov { 43d8db57c2SStanimir Varbanov struct venus_core *core = inst->core; 44d8db57c2SStanimir Varbanov u32 session_type = inst->session_type; 45d8db57c2SStanimir Varbanov u32 codec; 46d8db57c2SStanimir Varbanov 47d8db57c2SStanimir Varbanov switch (v4l2_pixfmt) { 48d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_H264: 49d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_H264; 50d8db57c2SStanimir Varbanov break; 51d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_H263: 52d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_H263; 53d8db57c2SStanimir Varbanov break; 54d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_MPEG1: 55d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_MPEG1; 56d8db57c2SStanimir Varbanov break; 57d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_MPEG2: 58d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_MPEG2; 59d8db57c2SStanimir Varbanov break; 60d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_MPEG4: 61d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_MPEG4; 62d8db57c2SStanimir Varbanov break; 63d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_VC1_ANNEX_G: 64d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_VC1_ANNEX_L: 65d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_VC1; 66d8db57c2SStanimir Varbanov break; 67d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_VP8: 68d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_VP8; 69d8db57c2SStanimir Varbanov break; 70d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_VP9: 71d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_VP9; 72d8db57c2SStanimir Varbanov break; 73d8db57c2SStanimir Varbanov case V4L2_PIX_FMT_XVID: 74d8db57c2SStanimir Varbanov codec = HFI_VIDEO_CODEC_DIVX; 75d8db57c2SStanimir Varbanov break; 761fb9a605SStanimir Varbanov case V4L2_PIX_FMT_HEVC: 771fb9a605SStanimir Varbanov codec = HFI_VIDEO_CODEC_HEVC; 781fb9a605SStanimir Varbanov break; 79d8db57c2SStanimir Varbanov default: 80d8db57c2SStanimir Varbanov return false; 81d8db57c2SStanimir Varbanov } 82d8db57c2SStanimir Varbanov 83d8db57c2SStanimir Varbanov if (session_type == VIDC_SESSION_TYPE_ENC && core->enc_codecs & codec) 84d8db57c2SStanimir Varbanov return true; 85d8db57c2SStanimir Varbanov 86d8db57c2SStanimir Varbanov if (session_type == VIDC_SESSION_TYPE_DEC && core->dec_codecs & codec) 87d8db57c2SStanimir Varbanov return true; 88d8db57c2SStanimir Varbanov 89d8db57c2SStanimir Varbanov return false; 90d8db57c2SStanimir Varbanov } 91d8db57c2SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_check_codec); 92d8db57c2SStanimir Varbanov 9373664f10SVikash Garodia static void free_dpb_buf(struct venus_inst *inst, struct intbuf *buf) 9473664f10SVikash Garodia { 9573664f10SVikash Garodia ida_free(&inst->dpb_ids, buf->dpb_out_tag); 9673664f10SVikash Garodia 9773664f10SVikash Garodia list_del_init(&buf->list); 9873664f10SVikash Garodia dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, 9973664f10SVikash Garodia buf->attrs); 10073664f10SVikash Garodia kfree(buf); 10173664f10SVikash Garodia } 10273664f10SVikash Garodia 1031e485ee5SStanimir Varbanov int venus_helper_queue_dpb_bufs(struct venus_inst *inst) 104f012b23dSStanimir Varbanov { 10573664f10SVikash Garodia struct intbuf *buf, *next; 10673664f10SVikash Garodia unsigned int dpb_size = 0; 107f012b23dSStanimir Varbanov int ret = 0; 108f012b23dSStanimir Varbanov 10973664f10SVikash Garodia if (inst->dpb_buftype == HFI_BUFFER_OUTPUT) 11073664f10SVikash Garodia dpb_size = inst->output_buf_size; 11173664f10SVikash Garodia else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2) 11273664f10SVikash Garodia dpb_size = inst->output2_buf_size; 11373664f10SVikash Garodia 11473664f10SVikash Garodia list_for_each_entry_safe(buf, next, &inst->dpbbufs, list) { 115f012b23dSStanimir Varbanov struct hfi_frame_data fdata; 116f012b23dSStanimir Varbanov 117f012b23dSStanimir Varbanov memset(&fdata, 0, sizeof(fdata)); 118f012b23dSStanimir Varbanov fdata.alloc_len = buf->size; 119f012b23dSStanimir Varbanov fdata.device_addr = buf->da; 120f012b23dSStanimir Varbanov fdata.buffer_type = buf->type; 121f012b23dSStanimir Varbanov 12240d87aafSMansur Alisha Shaik if (buf->owned_by == FIRMWARE) 12340d87aafSMansur Alisha Shaik continue; 12440d87aafSMansur Alisha Shaik 12573664f10SVikash Garodia /* free buffer from previous sequence which was released later */ 12673664f10SVikash Garodia if (dpb_size > buf->size) { 12773664f10SVikash Garodia free_dpb_buf(inst, buf); 12873664f10SVikash Garodia continue; 12973664f10SVikash Garodia } 13073664f10SVikash Garodia 13140d87aafSMansur Alisha Shaik fdata.clnt_data = buf->dpb_out_tag; 13240d87aafSMansur Alisha Shaik 133f012b23dSStanimir Varbanov ret = hfi_session_process_buf(inst, &fdata); 134f012b23dSStanimir Varbanov if (ret) 135f012b23dSStanimir Varbanov goto fail; 13640d87aafSMansur Alisha Shaik 13740d87aafSMansur Alisha Shaik buf->owned_by = FIRMWARE; 138f012b23dSStanimir Varbanov } 139f012b23dSStanimir Varbanov 140f012b23dSStanimir Varbanov fail: 141f012b23dSStanimir Varbanov return ret; 142f012b23dSStanimir Varbanov } 1431e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_queue_dpb_bufs); 144f012b23dSStanimir Varbanov 145f012b23dSStanimir Varbanov int venus_helper_free_dpb_bufs(struct venus_inst *inst) 146f012b23dSStanimir Varbanov { 147f012b23dSStanimir Varbanov struct intbuf *buf, *n; 148f012b23dSStanimir Varbanov 149f012b23dSStanimir Varbanov list_for_each_entry_safe(buf, n, &inst->dpbbufs, list) { 15040d87aafSMansur Alisha Shaik if (buf->owned_by == FIRMWARE) 15140d87aafSMansur Alisha Shaik continue; 15273664f10SVikash Garodia free_dpb_buf(inst, buf); 153f012b23dSStanimir Varbanov } 154f012b23dSStanimir Varbanov 15540d87aafSMansur Alisha Shaik if (list_empty(&inst->dpbbufs)) 156f012b23dSStanimir Varbanov INIT_LIST_HEAD(&inst->dpbbufs); 157f012b23dSStanimir Varbanov 158f012b23dSStanimir Varbanov return 0; 159f012b23dSStanimir Varbanov } 160f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_free_dpb_bufs); 161f012b23dSStanimir Varbanov 162f012b23dSStanimir Varbanov int venus_helper_alloc_dpb_bufs(struct venus_inst *inst) 163f012b23dSStanimir Varbanov { 164f012b23dSStanimir Varbanov struct venus_core *core = inst->core; 165f012b23dSStanimir Varbanov struct device *dev = core->dev; 166f012b23dSStanimir Varbanov enum hfi_version ver = core->res->hfi_version; 167f012b23dSStanimir Varbanov struct hfi_buffer_requirements bufreq; 168f012b23dSStanimir Varbanov u32 buftype = inst->dpb_buftype; 169f012b23dSStanimir Varbanov unsigned int dpb_size = 0; 170f012b23dSStanimir Varbanov struct intbuf *buf; 171f012b23dSStanimir Varbanov unsigned int i; 172f012b23dSStanimir Varbanov u32 count; 173f012b23dSStanimir Varbanov int ret; 17440d87aafSMansur Alisha Shaik int id; 175f012b23dSStanimir Varbanov 176f012b23dSStanimir Varbanov /* no need to allocate dpb buffers */ 177f012b23dSStanimir Varbanov if (!inst->dpb_fmt) 178f012b23dSStanimir Varbanov return 0; 179f012b23dSStanimir Varbanov 180f012b23dSStanimir Varbanov if (inst->dpb_buftype == HFI_BUFFER_OUTPUT) 181f012b23dSStanimir Varbanov dpb_size = inst->output_buf_size; 182f012b23dSStanimir Varbanov else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2) 183f012b23dSStanimir Varbanov dpb_size = inst->output2_buf_size; 184f012b23dSStanimir Varbanov 185f012b23dSStanimir Varbanov if (!dpb_size) 186f012b23dSStanimir Varbanov return 0; 187f012b23dSStanimir Varbanov 188f012b23dSStanimir Varbanov ret = venus_helper_get_bufreq(inst, buftype, &bufreq); 189f012b23dSStanimir Varbanov if (ret) 190f012b23dSStanimir Varbanov return ret; 191f012b23dSStanimir Varbanov 192*bbfc89e6SKonrad Dybcio count = hfi_bufreq_get_count_min(&bufreq, ver); 193f012b23dSStanimir Varbanov 194f012b23dSStanimir Varbanov for (i = 0; i < count; i++) { 195f012b23dSStanimir Varbanov buf = kzalloc(sizeof(*buf), GFP_KERNEL); 196f012b23dSStanimir Varbanov if (!buf) { 197f012b23dSStanimir Varbanov ret = -ENOMEM; 198f012b23dSStanimir Varbanov goto fail; 199f012b23dSStanimir Varbanov } 200f012b23dSStanimir Varbanov 201f012b23dSStanimir Varbanov buf->type = buftype; 202f012b23dSStanimir Varbanov buf->size = dpb_size; 203f012b23dSStanimir Varbanov buf->attrs = DMA_ATTR_WRITE_COMBINE | 204f012b23dSStanimir Varbanov DMA_ATTR_NO_KERNEL_MAPPING; 205f012b23dSStanimir Varbanov buf->va = dma_alloc_attrs(dev, buf->size, &buf->da, GFP_KERNEL, 206f012b23dSStanimir Varbanov buf->attrs); 207f012b23dSStanimir Varbanov if (!buf->va) { 208f012b23dSStanimir Varbanov ret = -ENOMEM; 209f012b23dSStanimir Varbanov goto fail; 210f012b23dSStanimir Varbanov } 21140d87aafSMansur Alisha Shaik buf->owned_by = DRIVER; 21240d87aafSMansur Alisha Shaik 21340d87aafSMansur Alisha Shaik id = ida_alloc_min(&inst->dpb_ids, VB2_MAX_FRAME, GFP_KERNEL); 21440d87aafSMansur Alisha Shaik if (id < 0) { 21540d87aafSMansur Alisha Shaik ret = id; 21640d87aafSMansur Alisha Shaik goto fail; 21740d87aafSMansur Alisha Shaik } 21840d87aafSMansur Alisha Shaik 21940d87aafSMansur Alisha Shaik buf->dpb_out_tag = id; 220f012b23dSStanimir Varbanov 221f012b23dSStanimir Varbanov list_add_tail(&buf->list, &inst->dpbbufs); 222f012b23dSStanimir Varbanov } 223f012b23dSStanimir Varbanov 224f012b23dSStanimir Varbanov return 0; 225f012b23dSStanimir Varbanov 226f012b23dSStanimir Varbanov fail: 2278403fdd7SAmeer Hamza kfree(buf); 228f012b23dSStanimir Varbanov venus_helper_free_dpb_bufs(inst); 229f012b23dSStanimir Varbanov return ret; 230f012b23dSStanimir Varbanov } 231f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_alloc_dpb_bufs); 232f012b23dSStanimir Varbanov 233af2c3834SStanimir Varbanov static int intbufs_set_buffer(struct venus_inst *inst, u32 type) 234af2c3834SStanimir Varbanov { 235af2c3834SStanimir Varbanov struct venus_core *core = inst->core; 236af2c3834SStanimir Varbanov struct device *dev = core->dev; 237af2c3834SStanimir Varbanov struct hfi_buffer_requirements bufreq; 238af2c3834SStanimir Varbanov struct hfi_buffer_desc bd; 239af2c3834SStanimir Varbanov struct intbuf *buf; 240af2c3834SStanimir Varbanov unsigned int i; 241af2c3834SStanimir Varbanov int ret; 242af2c3834SStanimir Varbanov 243af2c3834SStanimir Varbanov ret = venus_helper_get_bufreq(inst, type, &bufreq); 244af2c3834SStanimir Varbanov if (ret) 245af2c3834SStanimir Varbanov return 0; 246af2c3834SStanimir Varbanov 247af2c3834SStanimir Varbanov if (!bufreq.size) 248af2c3834SStanimir Varbanov return 0; 249af2c3834SStanimir Varbanov 250af2c3834SStanimir Varbanov for (i = 0; i < bufreq.count_actual; i++) { 251af2c3834SStanimir Varbanov buf = kzalloc(sizeof(*buf), GFP_KERNEL); 252af2c3834SStanimir Varbanov if (!buf) { 253af2c3834SStanimir Varbanov ret = -ENOMEM; 254af2c3834SStanimir Varbanov goto fail; 255af2c3834SStanimir Varbanov } 256af2c3834SStanimir Varbanov 257af2c3834SStanimir Varbanov buf->type = bufreq.type; 258af2c3834SStanimir Varbanov buf->size = bufreq.size; 259af2c3834SStanimir Varbanov buf->attrs = DMA_ATTR_WRITE_COMBINE | 260af2c3834SStanimir Varbanov DMA_ATTR_NO_KERNEL_MAPPING; 261af2c3834SStanimir Varbanov buf->va = dma_alloc_attrs(dev, buf->size, &buf->da, GFP_KERNEL, 262af2c3834SStanimir Varbanov buf->attrs); 263af2c3834SStanimir Varbanov if (!buf->va) { 264af2c3834SStanimir Varbanov ret = -ENOMEM; 265af2c3834SStanimir Varbanov goto fail; 266af2c3834SStanimir Varbanov } 267af2c3834SStanimir Varbanov 268af2c3834SStanimir Varbanov memset(&bd, 0, sizeof(bd)); 269af2c3834SStanimir Varbanov bd.buffer_size = buf->size; 270af2c3834SStanimir Varbanov bd.buffer_type = buf->type; 271af2c3834SStanimir Varbanov bd.num_buffers = 1; 272af2c3834SStanimir Varbanov bd.device_addr = buf->da; 273af2c3834SStanimir Varbanov 274af2c3834SStanimir Varbanov ret = hfi_session_set_buffers(inst, &bd); 275af2c3834SStanimir Varbanov if (ret) { 276af2c3834SStanimir Varbanov dev_err(dev, "set session buffers failed\n"); 277af2c3834SStanimir Varbanov goto dma_free; 278af2c3834SStanimir Varbanov } 279af2c3834SStanimir Varbanov 280af2c3834SStanimir Varbanov list_add_tail(&buf->list, &inst->internalbufs); 281af2c3834SStanimir Varbanov } 282af2c3834SStanimir Varbanov 283af2c3834SStanimir Varbanov return 0; 284af2c3834SStanimir Varbanov 285af2c3834SStanimir Varbanov dma_free: 286af2c3834SStanimir Varbanov dma_free_attrs(dev, buf->size, buf->va, buf->da, buf->attrs); 287af2c3834SStanimir Varbanov fail: 288af2c3834SStanimir Varbanov kfree(buf); 289af2c3834SStanimir Varbanov return ret; 290af2c3834SStanimir Varbanov } 291af2c3834SStanimir Varbanov 292af2c3834SStanimir Varbanov static int intbufs_unset_buffers(struct venus_inst *inst) 293af2c3834SStanimir Varbanov { 294af2c3834SStanimir Varbanov struct hfi_buffer_desc bd = {0}; 295af2c3834SStanimir Varbanov struct intbuf *buf, *n; 296af2c3834SStanimir Varbanov int ret = 0; 297af2c3834SStanimir Varbanov 298af2c3834SStanimir Varbanov list_for_each_entry_safe(buf, n, &inst->internalbufs, list) { 299af2c3834SStanimir Varbanov bd.buffer_size = buf->size; 300af2c3834SStanimir Varbanov bd.buffer_type = buf->type; 301af2c3834SStanimir Varbanov bd.num_buffers = 1; 302af2c3834SStanimir Varbanov bd.device_addr = buf->da; 303af2c3834SStanimir Varbanov bd.response_required = true; 304af2c3834SStanimir Varbanov 305af2c3834SStanimir Varbanov ret = hfi_session_unset_buffers(inst, &bd); 306af2c3834SStanimir Varbanov 307af2c3834SStanimir Varbanov list_del_init(&buf->list); 308af2c3834SStanimir Varbanov dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, 309af2c3834SStanimir Varbanov buf->attrs); 310af2c3834SStanimir Varbanov kfree(buf); 311af2c3834SStanimir Varbanov } 312af2c3834SStanimir Varbanov 313af2c3834SStanimir Varbanov return ret; 314af2c3834SStanimir Varbanov } 315af2c3834SStanimir Varbanov 316f04997bdSStanimir Varbanov static const unsigned int intbuf_types_1xx[] = { 317f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_1XX), 318f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_1XX), 319f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_1XX), 320f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_PERSIST, 321f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_PERSIST_1, 322f04997bdSStanimir Varbanov }; 323f04997bdSStanimir Varbanov 324f04997bdSStanimir Varbanov static const unsigned int intbuf_types_4xx[] = { 325f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_4XX), 326f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_4XX), 327f04997bdSStanimir Varbanov HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_4XX), 328af2c3834SStanimir Varbanov HFI_BUFFER_INTERNAL_PERSIST, 329af2c3834SStanimir Varbanov HFI_BUFFER_INTERNAL_PERSIST_1, 330af2c3834SStanimir Varbanov }; 331af2c3834SStanimir Varbanov 332c934d9d4SDikshita Agarwal static const unsigned int intbuf_types_6xx[] = { 333c934d9d4SDikshita Agarwal HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_6XX), 334c934d9d4SDikshita Agarwal HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_6XX), 335c934d9d4SDikshita Agarwal HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_6XX), 336c934d9d4SDikshita Agarwal HFI_BUFFER_INTERNAL_PERSIST, 337c934d9d4SDikshita Agarwal HFI_BUFFER_INTERNAL_PERSIST_1, 338c934d9d4SDikshita Agarwal }; 339c934d9d4SDikshita Agarwal 3401e485ee5SStanimir Varbanov int venus_helper_intbufs_alloc(struct venus_inst *inst) 341af2c3834SStanimir Varbanov { 342f04997bdSStanimir Varbanov const unsigned int *intbuf; 343f04997bdSStanimir Varbanov size_t arr_sz, i; 344af2c3834SStanimir Varbanov int ret; 345af2c3834SStanimir Varbanov 346c934d9d4SDikshita Agarwal if (IS_V6(inst->core)) { 347c934d9d4SDikshita Agarwal arr_sz = ARRAY_SIZE(intbuf_types_6xx); 348c934d9d4SDikshita Agarwal intbuf = intbuf_types_6xx; 349c934d9d4SDikshita Agarwal } else if (IS_V4(inst->core)) { 350f04997bdSStanimir Varbanov arr_sz = ARRAY_SIZE(intbuf_types_4xx); 351f04997bdSStanimir Varbanov intbuf = intbuf_types_4xx; 352f04997bdSStanimir Varbanov } else { 353f04997bdSStanimir Varbanov arr_sz = ARRAY_SIZE(intbuf_types_1xx); 354f04997bdSStanimir Varbanov intbuf = intbuf_types_1xx; 355f04997bdSStanimir Varbanov } 356f04997bdSStanimir Varbanov 357f04997bdSStanimir Varbanov for (i = 0; i < arr_sz; i++) { 358f04997bdSStanimir Varbanov ret = intbufs_set_buffer(inst, intbuf[i]); 359af2c3834SStanimir Varbanov if (ret) 360af2c3834SStanimir Varbanov goto error; 361af2c3834SStanimir Varbanov } 362af2c3834SStanimir Varbanov 363af2c3834SStanimir Varbanov return 0; 364af2c3834SStanimir Varbanov 365af2c3834SStanimir Varbanov error: 366af2c3834SStanimir Varbanov intbufs_unset_buffers(inst); 367af2c3834SStanimir Varbanov return ret; 368af2c3834SStanimir Varbanov } 3691e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_intbufs_alloc); 370af2c3834SStanimir Varbanov 3711e485ee5SStanimir Varbanov int venus_helper_intbufs_free(struct venus_inst *inst) 372af2c3834SStanimir Varbanov { 373af2c3834SStanimir Varbanov return intbufs_unset_buffers(inst); 374af2c3834SStanimir Varbanov } 3751e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_intbufs_free); 376af2c3834SStanimir Varbanov 37714ea00d6SStanimir Varbanov int venus_helper_intbufs_realloc(struct venus_inst *inst) 37814ea00d6SStanimir Varbanov { 37914ea00d6SStanimir Varbanov enum hfi_version ver = inst->core->res->hfi_version; 38014ea00d6SStanimir Varbanov struct hfi_buffer_desc bd; 38114ea00d6SStanimir Varbanov struct intbuf *buf, *n; 38214ea00d6SStanimir Varbanov int ret; 38314ea00d6SStanimir Varbanov 38414ea00d6SStanimir Varbanov list_for_each_entry_safe(buf, n, &inst->internalbufs, list) { 38514ea00d6SStanimir Varbanov if (buf->type == HFI_BUFFER_INTERNAL_PERSIST || 38614ea00d6SStanimir Varbanov buf->type == HFI_BUFFER_INTERNAL_PERSIST_1) 38714ea00d6SStanimir Varbanov continue; 38814ea00d6SStanimir Varbanov 38914ea00d6SStanimir Varbanov memset(&bd, 0, sizeof(bd)); 39014ea00d6SStanimir Varbanov bd.buffer_size = buf->size; 39114ea00d6SStanimir Varbanov bd.buffer_type = buf->type; 39214ea00d6SStanimir Varbanov bd.num_buffers = 1; 39314ea00d6SStanimir Varbanov bd.device_addr = buf->da; 39414ea00d6SStanimir Varbanov bd.response_required = true; 39514ea00d6SStanimir Varbanov 39614ea00d6SStanimir Varbanov ret = hfi_session_unset_buffers(inst, &bd); 39714ea00d6SStanimir Varbanov 39814ea00d6SStanimir Varbanov dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, 39914ea00d6SStanimir Varbanov buf->attrs); 40014ea00d6SStanimir Varbanov 40114ea00d6SStanimir Varbanov list_del_init(&buf->list); 40214ea00d6SStanimir Varbanov kfree(buf); 40314ea00d6SStanimir Varbanov } 40414ea00d6SStanimir Varbanov 40514ea00d6SStanimir Varbanov ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH(ver)); 40614ea00d6SStanimir Varbanov if (ret) 40714ea00d6SStanimir Varbanov goto err; 40814ea00d6SStanimir Varbanov 40914ea00d6SStanimir Varbanov ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_1(ver)); 41014ea00d6SStanimir Varbanov if (ret) 41114ea00d6SStanimir Varbanov goto err; 41214ea00d6SStanimir Varbanov 41314ea00d6SStanimir Varbanov ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_2(ver)); 41414ea00d6SStanimir Varbanov if (ret) 41514ea00d6SStanimir Varbanov goto err; 41614ea00d6SStanimir Varbanov 41714ea00d6SStanimir Varbanov return 0; 41814ea00d6SStanimir Varbanov err: 41914ea00d6SStanimir Varbanov return ret; 42014ea00d6SStanimir Varbanov } 42114ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_intbufs_realloc); 42214ea00d6SStanimir Varbanov 423af2c3834SStanimir Varbanov static void fill_buffer_desc(const struct venus_buffer *buf, 424af2c3834SStanimir Varbanov struct hfi_buffer_desc *bd, bool response) 425af2c3834SStanimir Varbanov { 426af2c3834SStanimir Varbanov memset(bd, 0, sizeof(*bd)); 427af2c3834SStanimir Varbanov bd->buffer_type = HFI_BUFFER_OUTPUT; 428af2c3834SStanimir Varbanov bd->buffer_size = buf->size; 429af2c3834SStanimir Varbanov bd->num_buffers = 1; 430af2c3834SStanimir Varbanov bd->device_addr = buf->dma_addr; 431af2c3834SStanimir Varbanov bd->response_required = response; 432af2c3834SStanimir Varbanov } 433af2c3834SStanimir Varbanov 434af2c3834SStanimir Varbanov static void return_buf_error(struct venus_inst *inst, 435af2c3834SStanimir Varbanov struct vb2_v4l2_buffer *vbuf) 436af2c3834SStanimir Varbanov { 437af2c3834SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 438af2c3834SStanimir Varbanov 439af2c3834SStanimir Varbanov if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 440af2c3834SStanimir Varbanov v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf); 441af2c3834SStanimir Varbanov else 4420de0ef6cSGustavo A. R. Silva v4l2_m2m_dst_buf_remove_by_buf(m2m_ctx, vbuf); 443af2c3834SStanimir Varbanov 444af2c3834SStanimir Varbanov v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); 445af2c3834SStanimir Varbanov } 446af2c3834SStanimir Varbanov 447d42974e4SStanimir Varbanov static void 448d42974e4SStanimir Varbanov put_ts_metadata(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) 449d42974e4SStanimir Varbanov { 450d42974e4SStanimir Varbanov struct vb2_buffer *vb = &vbuf->vb2_buf; 451d42974e4SStanimir Varbanov unsigned int i; 452d42974e4SStanimir Varbanov int slot = -1; 453d42974e4SStanimir Varbanov u64 ts_us = vb->timestamp; 454d42974e4SStanimir Varbanov 455d42974e4SStanimir Varbanov for (i = 0; i < ARRAY_SIZE(inst->tss); i++) { 456d42974e4SStanimir Varbanov if (!inst->tss[i].used) { 457d42974e4SStanimir Varbanov slot = i; 458d42974e4SStanimir Varbanov break; 459d42974e4SStanimir Varbanov } 460d42974e4SStanimir Varbanov } 461d42974e4SStanimir Varbanov 462d42974e4SStanimir Varbanov if (slot == -1) { 4638c91dc08SStanimir Varbanov dev_dbg(inst->core->dev, VDBGL "no free slot\n"); 464d42974e4SStanimir Varbanov return; 465d42974e4SStanimir Varbanov } 466d42974e4SStanimir Varbanov 467d42974e4SStanimir Varbanov do_div(ts_us, NSEC_PER_USEC); 468d42974e4SStanimir Varbanov 469d42974e4SStanimir Varbanov inst->tss[slot].used = true; 470d42974e4SStanimir Varbanov inst->tss[slot].flags = vbuf->flags; 471d42974e4SStanimir Varbanov inst->tss[slot].tc = vbuf->timecode; 472d42974e4SStanimir Varbanov inst->tss[slot].ts_us = ts_us; 473d42974e4SStanimir Varbanov inst->tss[slot].ts_ns = vb->timestamp; 474d42974e4SStanimir Varbanov } 475d42974e4SStanimir Varbanov 476d42974e4SStanimir Varbanov void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us, 477d42974e4SStanimir Varbanov struct vb2_v4l2_buffer *vbuf) 478d42974e4SStanimir Varbanov { 479d42974e4SStanimir Varbanov struct vb2_buffer *vb = &vbuf->vb2_buf; 480d42974e4SStanimir Varbanov unsigned int i; 481d42974e4SStanimir Varbanov 482d42974e4SStanimir Varbanov for (i = 0; i < ARRAY_SIZE(inst->tss); ++i) { 483d42974e4SStanimir Varbanov if (!inst->tss[i].used) 484d42974e4SStanimir Varbanov continue; 485d42974e4SStanimir Varbanov 486d42974e4SStanimir Varbanov if (inst->tss[i].ts_us != timestamp_us) 487d42974e4SStanimir Varbanov continue; 488d42974e4SStanimir Varbanov 489d42974e4SStanimir Varbanov inst->tss[i].used = false; 490d42974e4SStanimir Varbanov vbuf->flags |= inst->tss[i].flags; 491d42974e4SStanimir Varbanov vbuf->timecode = inst->tss[i].tc; 492d42974e4SStanimir Varbanov vb->timestamp = inst->tss[i].ts_ns; 493d42974e4SStanimir Varbanov break; 494d42974e4SStanimir Varbanov } 495d42974e4SStanimir Varbanov } 496d42974e4SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_ts_metadata); 497d42974e4SStanimir Varbanov 498af2c3834SStanimir Varbanov static int 499af2c3834SStanimir Varbanov session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) 500af2c3834SStanimir Varbanov { 501af2c3834SStanimir Varbanov struct venus_buffer *buf = to_venus_buffer(vbuf); 502af2c3834SStanimir Varbanov struct vb2_buffer *vb = &vbuf->vb2_buf; 503af2c3834SStanimir Varbanov unsigned int type = vb->type; 504af2c3834SStanimir Varbanov struct hfi_frame_data fdata; 505af2c3834SStanimir Varbanov 506af2c3834SStanimir Varbanov memset(&fdata, 0, sizeof(fdata)); 507af2c3834SStanimir Varbanov fdata.alloc_len = buf->size; 508af2c3834SStanimir Varbanov fdata.device_addr = buf->dma_addr; 509af2c3834SStanimir Varbanov fdata.timestamp = vb->timestamp; 510af2c3834SStanimir Varbanov do_div(fdata.timestamp, NSEC_PER_USEC); 511af2c3834SStanimir Varbanov fdata.flags = 0; 512af2c3834SStanimir Varbanov fdata.clnt_data = vbuf->vb2_buf.index; 513af2c3834SStanimir Varbanov 514af2c3834SStanimir Varbanov if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 515af2c3834SStanimir Varbanov fdata.buffer_type = HFI_BUFFER_INPUT; 516af2c3834SStanimir Varbanov fdata.filled_len = vb2_get_plane_payload(vb, 0); 517af2c3834SStanimir Varbanov fdata.offset = vb->planes[0].data_offset; 518af2c3834SStanimir Varbanov 519af2c3834SStanimir Varbanov if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len) 520af2c3834SStanimir Varbanov fdata.flags |= HFI_BUFFERFLAG_EOS; 521d42974e4SStanimir Varbanov 522d42974e4SStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_DEC) 523d42974e4SStanimir Varbanov put_ts_metadata(inst, vbuf); 524c0e284ccSAniket Masule 5257482a983SStanimir Varbanov venus_pm_load_scale(inst); 526af2c3834SStanimir Varbanov } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 527f012b23dSStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_ENC) 528af2c3834SStanimir Varbanov fdata.buffer_type = HFI_BUFFER_OUTPUT; 529f012b23dSStanimir Varbanov else 530f012b23dSStanimir Varbanov fdata.buffer_type = inst->opb_buftype; 531af2c3834SStanimir Varbanov fdata.filled_len = 0; 532af2c3834SStanimir Varbanov fdata.offset = 0; 533af2c3834SStanimir Varbanov } 534af2c3834SStanimir Varbanov 53598d43518SQinglang Miao return hfi_session_process_buf(inst, &fdata); 536af2c3834SStanimir Varbanov } 537af2c3834SStanimir Varbanov 538f0383520SStanimir Varbanov static bool is_dynamic_bufmode(struct venus_inst *inst) 539af2c3834SStanimir Varbanov { 540f0383520SStanimir Varbanov struct venus_core *core = inst->core; 5418f3b41dcSStanimir Varbanov struct hfi_plat_caps *caps; 542f0383520SStanimir Varbanov 543bc8c479aSStanimir Varbanov /* 544bc8c479aSStanimir Varbanov * v4 doesn't send BUFFER_ALLOC_MODE_SUPPORTED property and supports 545bc8c479aSStanimir Varbanov * dynamic buffer mode by default for HFI_BUFFER_OUTPUT/OUTPUT2. 546bc8c479aSStanimir Varbanov */ 5477ed9e0b3SBryan O'Donoghue if (IS_V4(core) || IS_V6(core)) 548bc8c479aSStanimir Varbanov return true; 549bc8c479aSStanimir Varbanov 550f0383520SStanimir Varbanov caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type); 551f0383520SStanimir Varbanov if (!caps) 5521cafbb86SGustavo A. R. Silva return false; 553af2c3834SStanimir Varbanov 554f0383520SStanimir Varbanov return caps->cap_bufs_mode_dynamic; 555af2c3834SStanimir Varbanov } 556af2c3834SStanimir Varbanov 5571e485ee5SStanimir Varbanov int venus_helper_unregister_bufs(struct venus_inst *inst) 558af2c3834SStanimir Varbanov { 559af2c3834SStanimir Varbanov struct venus_buffer *buf, *n; 560af2c3834SStanimir Varbanov struct hfi_buffer_desc bd; 561af2c3834SStanimir Varbanov int ret = 0; 562af2c3834SStanimir Varbanov 563f0383520SStanimir Varbanov if (is_dynamic_bufmode(inst)) 564af2c3834SStanimir Varbanov return 0; 565af2c3834SStanimir Varbanov 566af2c3834SStanimir Varbanov list_for_each_entry_safe(buf, n, &inst->registeredbufs, reg_list) { 567af2c3834SStanimir Varbanov fill_buffer_desc(buf, &bd, true); 568af2c3834SStanimir Varbanov ret = hfi_session_unset_buffers(inst, &bd); 569af2c3834SStanimir Varbanov list_del_init(&buf->reg_list); 570af2c3834SStanimir Varbanov } 571af2c3834SStanimir Varbanov 572af2c3834SStanimir Varbanov return ret; 573af2c3834SStanimir Varbanov } 5741e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_unregister_bufs); 575af2c3834SStanimir Varbanov 576af2c3834SStanimir Varbanov static int session_register_bufs(struct venus_inst *inst) 577af2c3834SStanimir Varbanov { 578af2c3834SStanimir Varbanov struct venus_core *core = inst->core; 579af2c3834SStanimir Varbanov struct device *dev = core->dev; 580af2c3834SStanimir Varbanov struct hfi_buffer_desc bd; 581af2c3834SStanimir Varbanov struct venus_buffer *buf; 582af2c3834SStanimir Varbanov int ret = 0; 583af2c3834SStanimir Varbanov 584f0383520SStanimir Varbanov if (is_dynamic_bufmode(inst)) 585af2c3834SStanimir Varbanov return 0; 586af2c3834SStanimir Varbanov 587af2c3834SStanimir Varbanov list_for_each_entry(buf, &inst->registeredbufs, reg_list) { 588af2c3834SStanimir Varbanov fill_buffer_desc(buf, &bd, false); 589af2c3834SStanimir Varbanov ret = hfi_session_set_buffers(inst, &bd); 590af2c3834SStanimir Varbanov if (ret) { 591af2c3834SStanimir Varbanov dev_err(dev, "%s: set buffer failed\n", __func__); 592af2c3834SStanimir Varbanov break; 593af2c3834SStanimir Varbanov } 594af2c3834SStanimir Varbanov } 595af2c3834SStanimir Varbanov 596af2c3834SStanimir Varbanov return ret; 597af2c3834SStanimir Varbanov } 598af2c3834SStanimir Varbanov 599ab97a3fbSStanimir Varbanov static u32 to_hfi_raw_fmt(u32 v4l2_fmt) 600ab97a3fbSStanimir Varbanov { 601ab97a3fbSStanimir Varbanov switch (v4l2_fmt) { 602ab97a3fbSStanimir Varbanov case V4L2_PIX_FMT_NV12: 603ab97a3fbSStanimir Varbanov return HFI_COLOR_FORMAT_NV12; 604ab97a3fbSStanimir Varbanov case V4L2_PIX_FMT_NV21: 605ab97a3fbSStanimir Varbanov return HFI_COLOR_FORMAT_NV21; 6069593126dSStanimir Varbanov case V4L2_PIX_FMT_QC08C: 6079593126dSStanimir Varbanov return HFI_COLOR_FORMAT_NV12_UBWC; 608cef92b14SStanimir Varbanov case V4L2_PIX_FMT_QC10C: 609cef92b14SStanimir Varbanov return HFI_COLOR_FORMAT_YUV420_TP10_UBWC; 61030956077SDikshita Agarwal case V4L2_PIX_FMT_P010: 61130956077SDikshita Agarwal return HFI_COLOR_FORMAT_P010; 612ab97a3fbSStanimir Varbanov default: 613ab97a3fbSStanimir Varbanov break; 614ab97a3fbSStanimir Varbanov } 615ab97a3fbSStanimir Varbanov 616ab97a3fbSStanimir Varbanov return 0; 617ab97a3fbSStanimir Varbanov } 618ab97a3fbSStanimir Varbanov 6197371093fSStanimir Varbanov static int platform_get_bufreq(struct venus_inst *inst, u32 buftype, 6207371093fSStanimir Varbanov struct hfi_buffer_requirements *req) 6217371093fSStanimir Varbanov { 6227371093fSStanimir Varbanov enum hfi_version version = inst->core->res->hfi_version; 6237371093fSStanimir Varbanov const struct hfi_platform *hfi_plat; 6247371093fSStanimir Varbanov struct hfi_plat_buffers_params params; 6257371093fSStanimir Varbanov bool is_dec = inst->session_type == VIDC_SESSION_TYPE_DEC; 6267371093fSStanimir Varbanov struct venc_controls *enc_ctr = &inst->controls.enc; 6277371093fSStanimir Varbanov 6287371093fSStanimir Varbanov hfi_plat = hfi_platform_get(version); 6297371093fSStanimir Varbanov 6307371093fSStanimir Varbanov if (!hfi_plat || !hfi_plat->bufreq) 6317371093fSStanimir Varbanov return -EINVAL; 6327371093fSStanimir Varbanov 6337371093fSStanimir Varbanov params.version = version; 634920173c7SDikshita Agarwal params.num_vpp_pipes = inst->core->res->num_vpp_pipes; 6357371093fSStanimir Varbanov 6367371093fSStanimir Varbanov if (is_dec) { 6377371093fSStanimir Varbanov params.width = inst->width; 6387371093fSStanimir Varbanov params.height = inst->height; 63958b64dd0SDikshita Agarwal params.out_width = inst->out_width; 64058b64dd0SDikshita Agarwal params.out_height = inst->out_height; 6417371093fSStanimir Varbanov params.codec = inst->fmt_out->pixfmt; 6427371093fSStanimir Varbanov params.hfi_color_fmt = to_hfi_raw_fmt(inst->fmt_cap->pixfmt); 6437371093fSStanimir Varbanov params.dec.max_mbs_per_frame = mbs_per_frame_max(inst); 6447371093fSStanimir Varbanov params.dec.buffer_size_limit = 0; 6457371093fSStanimir Varbanov params.dec.is_secondary_output = 6467371093fSStanimir Varbanov inst->opb_buftype == HFI_BUFFER_OUTPUT2; 64758b64dd0SDikshita Agarwal if (params.dec.is_secondary_output) 64858b64dd0SDikshita Agarwal params.hfi_dpb_color_fmt = inst->dpb_fmt; 6497371093fSStanimir Varbanov params.dec.is_interlaced = 6506fc46680SZhen Lei inst->pic_struct != HFI_INTERLACE_FRAME_PROGRESSIVE; 6517371093fSStanimir Varbanov } else { 6527371093fSStanimir Varbanov params.width = inst->out_width; 6537371093fSStanimir Varbanov params.height = inst->out_height; 6547371093fSStanimir Varbanov params.codec = inst->fmt_cap->pixfmt; 6557371093fSStanimir Varbanov params.hfi_color_fmt = to_hfi_raw_fmt(inst->fmt_out->pixfmt); 6567371093fSStanimir Varbanov params.enc.work_mode = VIDC_WORK_MODE_2; 6577371093fSStanimir Varbanov params.enc.rc_type = HFI_RATE_CONTROL_OFF; 6587371093fSStanimir Varbanov if (enc_ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) 6597371093fSStanimir Varbanov params.enc.rc_type = HFI_RATE_CONTROL_CQ; 6607371093fSStanimir Varbanov params.enc.num_b_frames = enc_ctr->num_b_frames; 6617371093fSStanimir Varbanov params.enc.is_tenbit = inst->bit_depth == VIDC_BITDEPTH_10; 6627371093fSStanimir Varbanov } 6637371093fSStanimir Varbanov 6647371093fSStanimir Varbanov return hfi_plat->bufreq(¶ms, inst->session_type, buftype, req); 6657371093fSStanimir Varbanov } 6667371093fSStanimir Varbanov 667af2c3834SStanimir Varbanov int venus_helper_get_bufreq(struct venus_inst *inst, u32 type, 668af2c3834SStanimir Varbanov struct hfi_buffer_requirements *req) 669af2c3834SStanimir Varbanov { 670af2c3834SStanimir Varbanov u32 ptype = HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS; 671af2c3834SStanimir Varbanov union hfi_get_property hprop; 672af2c3834SStanimir Varbanov unsigned int i; 673af2c3834SStanimir Varbanov int ret; 674af2c3834SStanimir Varbanov 675af2c3834SStanimir Varbanov memset(req, 0, sizeof(*req)); 676af2c3834SStanimir Varbanov 67716545aa3SDikshita Agarwal if (type == HFI_BUFFER_OUTPUT || type == HFI_BUFFER_OUTPUT2) 67816545aa3SDikshita Agarwal req->count_min = inst->fw_min_cnt; 67916545aa3SDikshita Agarwal 6807371093fSStanimir Varbanov ret = platform_get_bufreq(inst, type, req); 68116545aa3SDikshita Agarwal if (!ret) { 68216545aa3SDikshita Agarwal if (type == HFI_BUFFER_OUTPUT || type == HFI_BUFFER_OUTPUT2) 68316545aa3SDikshita Agarwal inst->fw_min_cnt = req->count_min; 6847371093fSStanimir Varbanov return 0; 68516545aa3SDikshita Agarwal } 6867371093fSStanimir Varbanov 687af2c3834SStanimir Varbanov ret = hfi_session_get_property(inst, ptype, &hprop); 688af2c3834SStanimir Varbanov if (ret) 689af2c3834SStanimir Varbanov return ret; 690af2c3834SStanimir Varbanov 691af2c3834SStanimir Varbanov ret = -EINVAL; 692af2c3834SStanimir Varbanov 693af2c3834SStanimir Varbanov for (i = 0; i < HFI_BUFFER_TYPE_MAX; i++) { 694af2c3834SStanimir Varbanov if (hprop.bufreq[i].type != type) 695af2c3834SStanimir Varbanov continue; 696af2c3834SStanimir Varbanov 697af2c3834SStanimir Varbanov memcpy(req, &hprop.bufreq[i], sizeof(*req)); 698af2c3834SStanimir Varbanov ret = 0; 699af2c3834SStanimir Varbanov break; 700af2c3834SStanimir Varbanov } 701af2c3834SStanimir Varbanov 702af2c3834SStanimir Varbanov return ret; 703af2c3834SStanimir Varbanov } 704af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_bufreq); 705af2c3834SStanimir Varbanov 7062c2dc2fdSStanimir Varbanov struct id_mapping { 7072c2dc2fdSStanimir Varbanov u32 hfi_id; 7082c2dc2fdSStanimir Varbanov u32 v4l2_id; 7092c2dc2fdSStanimir Varbanov }; 7102c2dc2fdSStanimir Varbanov 7112c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg4_profiles[] = { 7122c2dc2fdSStanimir Varbanov { HFI_MPEG4_PROFILE_SIMPLE, V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE }, 7132c2dc2fdSStanimir Varbanov { HFI_MPEG4_PROFILE_ADVANCEDSIMPLE, V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE }, 7142c2dc2fdSStanimir Varbanov }; 7152c2dc2fdSStanimir Varbanov 7162c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg4_levels[] = { 7172c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 }, 7182c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_0b, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B }, 7192c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_1, V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 }, 7202c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_2, V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 }, 7212c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_3, V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 }, 7222c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_4, V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 }, 7232c2dc2fdSStanimir Varbanov { HFI_MPEG4_LEVEL_5, V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 }, 7242c2dc2fdSStanimir Varbanov }; 7252c2dc2fdSStanimir Varbanov 7262c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg2_profiles[] = { 7272c2dc2fdSStanimir Varbanov { HFI_MPEG2_PROFILE_SIMPLE, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE }, 7282c2dc2fdSStanimir Varbanov { HFI_MPEG2_PROFILE_MAIN, V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN }, 7292c2dc2fdSStanimir Varbanov { HFI_MPEG2_PROFILE_SNR, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE }, 7302c2dc2fdSStanimir Varbanov { HFI_MPEG2_PROFILE_SPATIAL, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE }, 7312c2dc2fdSStanimir Varbanov { HFI_MPEG2_PROFILE_HIGH, V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH }, 7322c2dc2fdSStanimir Varbanov }; 7332c2dc2fdSStanimir Varbanov 7342c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg2_levels[] = { 7352c2dc2fdSStanimir Varbanov { HFI_MPEG2_LEVEL_LL, V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW }, 7362c2dc2fdSStanimir Varbanov { HFI_MPEG2_LEVEL_ML, V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN }, 7372c2dc2fdSStanimir Varbanov { HFI_MPEG2_LEVEL_H14, V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440 }, 7382c2dc2fdSStanimir Varbanov { HFI_MPEG2_LEVEL_HL, V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH }, 7392c2dc2fdSStanimir Varbanov }; 7402c2dc2fdSStanimir Varbanov 7412c2dc2fdSStanimir Varbanov static const struct id_mapping h264_profiles[] = { 7422c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_BASELINE, V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE }, 7432c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_MAIN, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN }, 7442c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH }, 7452c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_STEREO_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH }, 7462c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_MULTIVIEW_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH }, 7472c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_CONSTRAINED_BASE, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE }, 7482c2dc2fdSStanimir Varbanov { HFI_H264_PROFILE_CONSTRAINED_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH }, 7492c2dc2fdSStanimir Varbanov }; 7502c2dc2fdSStanimir Varbanov 7512c2dc2fdSStanimir Varbanov static const struct id_mapping h264_levels[] = { 7522c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_1, V4L2_MPEG_VIDEO_H264_LEVEL_1_0 }, 7532c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_1b, V4L2_MPEG_VIDEO_H264_LEVEL_1B }, 7542c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_11, V4L2_MPEG_VIDEO_H264_LEVEL_1_1 }, 7552c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_12, V4L2_MPEG_VIDEO_H264_LEVEL_1_2 }, 7562c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_13, V4L2_MPEG_VIDEO_H264_LEVEL_1_3 }, 7572c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_2, V4L2_MPEG_VIDEO_H264_LEVEL_2_0 }, 7582c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_21, V4L2_MPEG_VIDEO_H264_LEVEL_2_1 }, 7592c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_22, V4L2_MPEG_VIDEO_H264_LEVEL_2_2 }, 7602c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_3, V4L2_MPEG_VIDEO_H264_LEVEL_3_0 }, 7612c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_31, V4L2_MPEG_VIDEO_H264_LEVEL_3_1 }, 7622c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_32, V4L2_MPEG_VIDEO_H264_LEVEL_3_2 }, 7632c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_4, V4L2_MPEG_VIDEO_H264_LEVEL_4_0 }, 7642c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_41, V4L2_MPEG_VIDEO_H264_LEVEL_4_1 }, 7652c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_42, V4L2_MPEG_VIDEO_H264_LEVEL_4_2 }, 7662c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_5, V4L2_MPEG_VIDEO_H264_LEVEL_5_0 }, 7672c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_51, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 }, 7682c2dc2fdSStanimir Varbanov { HFI_H264_LEVEL_52, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 }, 7692c2dc2fdSStanimir Varbanov }; 7702c2dc2fdSStanimir Varbanov 7712c2dc2fdSStanimir Varbanov static const struct id_mapping hevc_profiles[] = { 7722c2dc2fdSStanimir Varbanov { HFI_HEVC_PROFILE_MAIN, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN }, 7732c2dc2fdSStanimir Varbanov { HFI_HEVC_PROFILE_MAIN_STILL_PIC, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE }, 7742c2dc2fdSStanimir Varbanov { HFI_HEVC_PROFILE_MAIN10, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10 }, 7752c2dc2fdSStanimir Varbanov }; 7762c2dc2fdSStanimir Varbanov 7772c2dc2fdSStanimir Varbanov static const struct id_mapping hevc_levels[] = { 7782c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_1, V4L2_MPEG_VIDEO_HEVC_LEVEL_1 }, 7792c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_2, V4L2_MPEG_VIDEO_HEVC_LEVEL_2 }, 7802c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_21, V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 }, 7812c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_3, V4L2_MPEG_VIDEO_HEVC_LEVEL_3 }, 7822c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_31, V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 }, 7832c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_4, V4L2_MPEG_VIDEO_HEVC_LEVEL_4 }, 7842c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_41, V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 }, 7852c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_5, V4L2_MPEG_VIDEO_HEVC_LEVEL_5 }, 7862c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_51, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 }, 7872c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_52, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 }, 7882c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_6, V4L2_MPEG_VIDEO_HEVC_LEVEL_6 }, 7892c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_61, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 }, 7902c2dc2fdSStanimir Varbanov { HFI_HEVC_LEVEL_62, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 }, 7912c2dc2fdSStanimir Varbanov }; 7922c2dc2fdSStanimir Varbanov 7932c2dc2fdSStanimir Varbanov static const struct id_mapping vp8_profiles[] = { 7942c2dc2fdSStanimir Varbanov { HFI_VPX_PROFILE_VERSION_0, V4L2_MPEG_VIDEO_VP8_PROFILE_0 }, 7952c2dc2fdSStanimir Varbanov { HFI_VPX_PROFILE_VERSION_1, V4L2_MPEG_VIDEO_VP8_PROFILE_1 }, 7962c2dc2fdSStanimir Varbanov { HFI_VPX_PROFILE_VERSION_2, V4L2_MPEG_VIDEO_VP8_PROFILE_2 }, 7972c2dc2fdSStanimir Varbanov { HFI_VPX_PROFILE_VERSION_3, V4L2_MPEG_VIDEO_VP8_PROFILE_3 }, 7982c2dc2fdSStanimir Varbanov }; 7992c2dc2fdSStanimir Varbanov 8002c2dc2fdSStanimir Varbanov static const struct id_mapping vp9_profiles[] = { 8012c2dc2fdSStanimir Varbanov { HFI_VP9_PROFILE_P0, V4L2_MPEG_VIDEO_VP9_PROFILE_0 }, 8022c2dc2fdSStanimir Varbanov { HFI_VP9_PROFILE_P2_10B, V4L2_MPEG_VIDEO_VP9_PROFILE_2 }, 8032c2dc2fdSStanimir Varbanov }; 8042c2dc2fdSStanimir Varbanov 8052c2dc2fdSStanimir Varbanov static const struct id_mapping vp9_levels[] = { 8062c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_1, V4L2_MPEG_VIDEO_VP9_LEVEL_1_0 }, 8072c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_11, V4L2_MPEG_VIDEO_VP9_LEVEL_1_1 }, 8082c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_2, V4L2_MPEG_VIDEO_VP9_LEVEL_2_0}, 8092c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_21, V4L2_MPEG_VIDEO_VP9_LEVEL_2_1 }, 8102c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_3, V4L2_MPEG_VIDEO_VP9_LEVEL_3_0}, 8112c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_31, V4L2_MPEG_VIDEO_VP9_LEVEL_3_1 }, 8122c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_4, V4L2_MPEG_VIDEO_VP9_LEVEL_4_0 }, 8132c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_41, V4L2_MPEG_VIDEO_VP9_LEVEL_4_1 }, 8142c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_5, V4L2_MPEG_VIDEO_VP9_LEVEL_5_0 }, 8152c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_51, V4L2_MPEG_VIDEO_VP9_LEVEL_5_1 }, 8162c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_6, V4L2_MPEG_VIDEO_VP9_LEVEL_6_0 }, 8172c2dc2fdSStanimir Varbanov { HFI_VP9_LEVEL_61, V4L2_MPEG_VIDEO_VP9_LEVEL_6_1 }, 8182c2dc2fdSStanimir Varbanov }; 8192c2dc2fdSStanimir Varbanov 8202c2dc2fdSStanimir Varbanov static u32 find_v4l2_id(u32 hfi_id, const struct id_mapping *array, unsigned int array_sz) 8212c2dc2fdSStanimir Varbanov { 8222c2dc2fdSStanimir Varbanov unsigned int i; 8232c2dc2fdSStanimir Varbanov 8242c2dc2fdSStanimir Varbanov if (!array || !array_sz) 8252c2dc2fdSStanimir Varbanov return 0; 8262c2dc2fdSStanimir Varbanov 8272c2dc2fdSStanimir Varbanov for (i = 0; i < array_sz; i++) 8282c2dc2fdSStanimir Varbanov if (hfi_id == array[i].hfi_id) 8292c2dc2fdSStanimir Varbanov return array[i].v4l2_id; 8302c2dc2fdSStanimir Varbanov 8312c2dc2fdSStanimir Varbanov return 0; 8322c2dc2fdSStanimir Varbanov } 8332c2dc2fdSStanimir Varbanov 8342c2dc2fdSStanimir Varbanov static u32 find_hfi_id(u32 v4l2_id, const struct id_mapping *array, unsigned int array_sz) 8352c2dc2fdSStanimir Varbanov { 8362c2dc2fdSStanimir Varbanov unsigned int i; 8372c2dc2fdSStanimir Varbanov 8382c2dc2fdSStanimir Varbanov if (!array || !array_sz) 8392c2dc2fdSStanimir Varbanov return 0; 8402c2dc2fdSStanimir Varbanov 8412c2dc2fdSStanimir Varbanov for (i = 0; i < array_sz; i++) 8422c2dc2fdSStanimir Varbanov if (v4l2_id == array[i].v4l2_id) 8432c2dc2fdSStanimir Varbanov return array[i].hfi_id; 8442c2dc2fdSStanimir Varbanov 8452c2dc2fdSStanimir Varbanov return 0; 8462c2dc2fdSStanimir Varbanov } 8472c2dc2fdSStanimir Varbanov 8482c2dc2fdSStanimir Varbanov static void 8492c2dc2fdSStanimir Varbanov v4l2_id_profile_level(u32 hfi_codec, struct hfi_profile_level *pl, u32 *profile, u32 *level) 8502c2dc2fdSStanimir Varbanov { 8512c2dc2fdSStanimir Varbanov u32 hfi_pf = pl->profile; 8522c2dc2fdSStanimir Varbanov u32 hfi_lvl = pl->level; 8532c2dc2fdSStanimir Varbanov 8542c2dc2fdSStanimir Varbanov switch (hfi_codec) { 8552c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_H264: 8562c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, h264_profiles, ARRAY_SIZE(h264_profiles)); 8572c2dc2fdSStanimir Varbanov *level = find_v4l2_id(hfi_lvl, h264_levels, ARRAY_SIZE(h264_levels)); 8582c2dc2fdSStanimir Varbanov break; 8592c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_MPEG2: 8602c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, mpeg2_profiles, ARRAY_SIZE(mpeg2_profiles)); 8612c2dc2fdSStanimir Varbanov *level = find_v4l2_id(hfi_lvl, mpeg2_levels, ARRAY_SIZE(mpeg2_levels)); 8622c2dc2fdSStanimir Varbanov break; 8632c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_MPEG4: 8642c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, mpeg4_profiles, ARRAY_SIZE(mpeg4_profiles)); 8652c2dc2fdSStanimir Varbanov *level = find_v4l2_id(hfi_lvl, mpeg4_levels, ARRAY_SIZE(mpeg4_levels)); 8662c2dc2fdSStanimir Varbanov break; 8672c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_VP8: 8682c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, vp8_profiles, ARRAY_SIZE(vp8_profiles)); 8692c2dc2fdSStanimir Varbanov *level = 0; 8702c2dc2fdSStanimir Varbanov break; 8712c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_VP9: 8722c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, vp9_profiles, ARRAY_SIZE(vp9_profiles)); 8732c2dc2fdSStanimir Varbanov *level = find_v4l2_id(hfi_lvl, vp9_levels, ARRAY_SIZE(vp9_levels)); 8742c2dc2fdSStanimir Varbanov break; 8752c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_HEVC: 8762c2dc2fdSStanimir Varbanov *profile = find_v4l2_id(hfi_pf, hevc_profiles, ARRAY_SIZE(hevc_profiles)); 8772c2dc2fdSStanimir Varbanov *level = find_v4l2_id(hfi_lvl, hevc_levels, ARRAY_SIZE(hevc_levels)); 8782c2dc2fdSStanimir Varbanov break; 8792c2dc2fdSStanimir Varbanov default: 8802c2dc2fdSStanimir Varbanov break; 8812c2dc2fdSStanimir Varbanov } 8822c2dc2fdSStanimir Varbanov } 8832c2dc2fdSStanimir Varbanov 8842c2dc2fdSStanimir Varbanov static void 8852c2dc2fdSStanimir Varbanov hfi_id_profile_level(u32 hfi_codec, u32 v4l2_pf, u32 v4l2_lvl, struct hfi_profile_level *pl) 8862c2dc2fdSStanimir Varbanov { 8872c2dc2fdSStanimir Varbanov switch (hfi_codec) { 8882c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_H264: 8892c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, h264_profiles, ARRAY_SIZE(h264_profiles)); 8902c2dc2fdSStanimir Varbanov pl->level = find_hfi_id(v4l2_lvl, h264_levels, ARRAY_SIZE(h264_levels)); 8912c2dc2fdSStanimir Varbanov break; 8922c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_MPEG2: 8932c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, mpeg2_profiles, ARRAY_SIZE(mpeg2_profiles)); 8942c2dc2fdSStanimir Varbanov pl->level = find_hfi_id(v4l2_lvl, mpeg2_levels, ARRAY_SIZE(mpeg2_levels)); 8952c2dc2fdSStanimir Varbanov break; 8962c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_MPEG4: 8972c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, mpeg4_profiles, ARRAY_SIZE(mpeg4_profiles)); 8982c2dc2fdSStanimir Varbanov pl->level = find_hfi_id(v4l2_lvl, mpeg4_levels, ARRAY_SIZE(mpeg4_levels)); 8992c2dc2fdSStanimir Varbanov break; 9002c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_VP8: 9012c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, vp8_profiles, ARRAY_SIZE(vp8_profiles)); 9022c2dc2fdSStanimir Varbanov pl->level = 0; 9032c2dc2fdSStanimir Varbanov break; 9042c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_VP9: 9052c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, vp9_profiles, ARRAY_SIZE(vp9_profiles)); 9062c2dc2fdSStanimir Varbanov pl->level = find_hfi_id(v4l2_lvl, vp9_levels, ARRAY_SIZE(vp9_levels)); 9072c2dc2fdSStanimir Varbanov break; 9082c2dc2fdSStanimir Varbanov case HFI_VIDEO_CODEC_HEVC: 9092c2dc2fdSStanimir Varbanov pl->profile = find_hfi_id(v4l2_pf, hevc_profiles, ARRAY_SIZE(hevc_profiles)); 9102c2dc2fdSStanimir Varbanov pl->level = find_hfi_id(v4l2_lvl, hevc_levels, ARRAY_SIZE(hevc_levels)); 9112c2dc2fdSStanimir Varbanov break; 9122c2dc2fdSStanimir Varbanov default: 9132c2dc2fdSStanimir Varbanov break; 9142c2dc2fdSStanimir Varbanov } 9152c2dc2fdSStanimir Varbanov } 9162c2dc2fdSStanimir Varbanov 9172c2dc2fdSStanimir Varbanov int venus_helper_get_profile_level(struct venus_inst *inst, u32 *profile, u32 *level) 9182c2dc2fdSStanimir Varbanov { 9192c2dc2fdSStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT; 9202c2dc2fdSStanimir Varbanov union hfi_get_property hprop; 9212c2dc2fdSStanimir Varbanov int ret; 9222c2dc2fdSStanimir Varbanov 9232c2dc2fdSStanimir Varbanov ret = hfi_session_get_property(inst, ptype, &hprop); 9242c2dc2fdSStanimir Varbanov if (ret) 9252c2dc2fdSStanimir Varbanov return ret; 9262c2dc2fdSStanimir Varbanov 9272c2dc2fdSStanimir Varbanov v4l2_id_profile_level(inst->hfi_codec, &hprop.profile_level, profile, level); 9282c2dc2fdSStanimir Varbanov 9292c2dc2fdSStanimir Varbanov return 0; 9302c2dc2fdSStanimir Varbanov } 9312c2dc2fdSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_profile_level); 9322c2dc2fdSStanimir Varbanov 9332c2dc2fdSStanimir Varbanov int venus_helper_set_profile_level(struct venus_inst *inst, u32 profile, u32 level) 9342c2dc2fdSStanimir Varbanov { 9352c2dc2fdSStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT; 9362c2dc2fdSStanimir Varbanov struct hfi_profile_level pl; 9372c2dc2fdSStanimir Varbanov 9382c2dc2fdSStanimir Varbanov hfi_id_profile_level(inst->hfi_codec, profile, level, &pl); 9392c2dc2fdSStanimir Varbanov 9402c2dc2fdSStanimir Varbanov return hfi_session_set_property(inst, ptype, &pl); 9412c2dc2fdSStanimir Varbanov } 9422c2dc2fdSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_profile_level); 9432c2dc2fdSStanimir Varbanov 944e1cb72deSStanimir Varbanov static u32 get_framesize_raw_nv12(u32 width, u32 height) 945e1cb72deSStanimir Varbanov { 946e1cb72deSStanimir Varbanov u32 y_stride, uv_stride, y_plane; 947e1cb72deSStanimir Varbanov u32 y_sclines, uv_sclines, uv_plane; 948e1cb72deSStanimir Varbanov u32 size; 949e1cb72deSStanimir Varbanov 950e1cb72deSStanimir Varbanov y_stride = ALIGN(width, 128); 951e1cb72deSStanimir Varbanov uv_stride = ALIGN(width, 128); 952e1cb72deSStanimir Varbanov y_sclines = ALIGN(height, 32); 953e1cb72deSStanimir Varbanov uv_sclines = ALIGN(((height + 1) >> 1), 16); 954e1cb72deSStanimir Varbanov 955e1cb72deSStanimir Varbanov y_plane = y_stride * y_sclines; 956e1cb72deSStanimir Varbanov uv_plane = uv_stride * uv_sclines + SZ_4K; 957e1cb72deSStanimir Varbanov size = y_plane + uv_plane + SZ_8K; 958e1cb72deSStanimir Varbanov 959e1cb72deSStanimir Varbanov return ALIGN(size, SZ_4K); 960e1cb72deSStanimir Varbanov } 961e1cb72deSStanimir Varbanov 962e1cb72deSStanimir Varbanov static u32 get_framesize_raw_nv12_ubwc(u32 width, u32 height) 963e1cb72deSStanimir Varbanov { 964e1cb72deSStanimir Varbanov u32 y_meta_stride, y_meta_plane; 965e1cb72deSStanimir Varbanov u32 y_stride, y_plane; 966e1cb72deSStanimir Varbanov u32 uv_meta_stride, uv_meta_plane; 967e1cb72deSStanimir Varbanov u32 uv_stride, uv_plane; 968e1cb72deSStanimir Varbanov u32 extradata = SZ_16K; 969e1cb72deSStanimir Varbanov 970e1cb72deSStanimir Varbanov y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64); 971e1cb72deSStanimir Varbanov y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(height, 8), 16); 972e1cb72deSStanimir Varbanov y_meta_plane = ALIGN(y_meta_plane, SZ_4K); 973e1cb72deSStanimir Varbanov 974e1cb72deSStanimir Varbanov y_stride = ALIGN(width, 128); 975e1cb72deSStanimir Varbanov y_plane = ALIGN(y_stride * ALIGN(height, 32), SZ_4K); 976e1cb72deSStanimir Varbanov 977e1cb72deSStanimir Varbanov uv_meta_stride = ALIGN(DIV_ROUND_UP(width / 2, 16), 64); 978e1cb72deSStanimir Varbanov uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(height / 2, 8), 16); 979e1cb72deSStanimir Varbanov uv_meta_plane = ALIGN(uv_meta_plane, SZ_4K); 980e1cb72deSStanimir Varbanov 981e1cb72deSStanimir Varbanov uv_stride = ALIGN(width, 128); 982e1cb72deSStanimir Varbanov uv_plane = ALIGN(uv_stride * ALIGN(height / 2, 32), SZ_4K); 983e1cb72deSStanimir Varbanov 984e1cb72deSStanimir Varbanov return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane + 985e1cb72deSStanimir Varbanov max(extradata, y_stride * 48), SZ_4K); 986e1cb72deSStanimir Varbanov } 987e1cb72deSStanimir Varbanov 988ab1eda44SAniket Masule static u32 get_framesize_raw_p010(u32 width, u32 height) 989ab1eda44SAniket Masule { 990ab1eda44SAniket Masule u32 y_plane, uv_plane, y_stride, uv_stride, y_sclines, uv_sclines; 991ab1eda44SAniket Masule 992a47a3ae5SFritz Koenig y_stride = ALIGN(width * 2, 128); 993a47a3ae5SFritz Koenig uv_stride = ALIGN(width * 2, 128); 994ab1eda44SAniket Masule y_sclines = ALIGN(height, 32); 995ab1eda44SAniket Masule uv_sclines = ALIGN((height + 1) >> 1, 16); 996ab1eda44SAniket Masule y_plane = y_stride * y_sclines; 997ab1eda44SAniket Masule uv_plane = uv_stride * uv_sclines; 998ab1eda44SAniket Masule 999ab1eda44SAniket Masule return ALIGN((y_plane + uv_plane), SZ_4K); 1000ab1eda44SAniket Masule } 1001ab1eda44SAniket Masule 1002ab1eda44SAniket Masule static u32 get_framesize_raw_p010_ubwc(u32 width, u32 height) 1003ab1eda44SAniket Masule { 1004ab1eda44SAniket Masule u32 y_stride, uv_stride, y_sclines, uv_sclines; 1005ab1eda44SAniket Masule u32 y_ubwc_plane, uv_ubwc_plane; 1006ab1eda44SAniket Masule u32 y_meta_stride, y_meta_scanlines; 1007ab1eda44SAniket Masule u32 uv_meta_stride, uv_meta_scanlines; 1008ab1eda44SAniket Masule u32 y_meta_plane, uv_meta_plane; 1009ab1eda44SAniket Masule u32 size; 1010ab1eda44SAniket Masule 1011ab1eda44SAniket Masule y_stride = ALIGN(width * 2, 256); 1012ab1eda44SAniket Masule uv_stride = ALIGN(width * 2, 256); 1013ab1eda44SAniket Masule y_sclines = ALIGN(height, 16); 1014ab1eda44SAniket Masule uv_sclines = ALIGN((height + 1) >> 1, 16); 1015ab1eda44SAniket Masule 1016ab1eda44SAniket Masule y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K); 1017ab1eda44SAniket Masule uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K); 1018ab1eda44SAniket Masule y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64); 1019ab1eda44SAniket Masule y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16); 1020ab1eda44SAniket Masule y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K); 1021ab1eda44SAniket Masule uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64); 1022ab1eda44SAniket Masule uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16); 1023ab1eda44SAniket Masule uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K); 1024ab1eda44SAniket Masule 1025ab1eda44SAniket Masule size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane; 1026ab1eda44SAniket Masule 1027ab1eda44SAniket Masule return ALIGN(size, SZ_4K); 1028ab1eda44SAniket Masule } 1029ab1eda44SAniket Masule 1030ab1eda44SAniket Masule static u32 get_framesize_raw_yuv420_tp10_ubwc(u32 width, u32 height) 1031ab1eda44SAniket Masule { 1032ab1eda44SAniket Masule u32 y_stride, uv_stride, y_sclines, uv_sclines; 1033ab1eda44SAniket Masule u32 y_ubwc_plane, uv_ubwc_plane; 1034ab1eda44SAniket Masule u32 y_meta_stride, y_meta_scanlines; 1035ab1eda44SAniket Masule u32 uv_meta_stride, uv_meta_scanlines; 1036ab1eda44SAniket Masule u32 y_meta_plane, uv_meta_plane; 1037ab1eda44SAniket Masule u32 extradata = SZ_16K; 1038ab1eda44SAniket Masule u32 size; 1039ab1eda44SAniket Masule 1040927e78acSRikard Falkeborn y_stride = ALIGN(width * 4 / 3, 256); 1041927e78acSRikard Falkeborn uv_stride = ALIGN(width * 4 / 3, 256); 1042ab1eda44SAniket Masule y_sclines = ALIGN(height, 16); 1043ab1eda44SAniket Masule uv_sclines = ALIGN((height + 1) >> 1, 16); 1044ab1eda44SAniket Masule 1045ab1eda44SAniket Masule y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K); 1046ab1eda44SAniket Masule uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K); 1047ab1eda44SAniket Masule y_meta_stride = ALIGN(DIV_ROUND_UP(width, 48), 64); 1048ab1eda44SAniket Masule y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16); 1049ab1eda44SAniket Masule y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K); 1050ab1eda44SAniket Masule uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64); 1051ab1eda44SAniket Masule uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16); 1052ab1eda44SAniket Masule uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K); 1053ab1eda44SAniket Masule 1054ab1eda44SAniket Masule size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane; 1055ab1eda44SAniket Masule size += max(extradata + SZ_8K, y_stride * 48); 1056ab1eda44SAniket Masule 1057ab1eda44SAniket Masule return ALIGN(size, SZ_4K); 1058ab1eda44SAniket Masule } 1059ab1eda44SAniket Masule 1060e1cb72deSStanimir Varbanov u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height) 1061e1cb72deSStanimir Varbanov { 1062e1cb72deSStanimir Varbanov switch (hfi_fmt) { 1063e1cb72deSStanimir Varbanov case HFI_COLOR_FORMAT_NV12: 1064e1cb72deSStanimir Varbanov case HFI_COLOR_FORMAT_NV21: 1065e1cb72deSStanimir Varbanov return get_framesize_raw_nv12(width, height); 1066e1cb72deSStanimir Varbanov case HFI_COLOR_FORMAT_NV12_UBWC: 1067e1cb72deSStanimir Varbanov return get_framesize_raw_nv12_ubwc(width, height); 1068ab1eda44SAniket Masule case HFI_COLOR_FORMAT_P010: 1069ab1eda44SAniket Masule return get_framesize_raw_p010(width, height); 1070ab1eda44SAniket Masule case HFI_COLOR_FORMAT_P010_UBWC: 1071ab1eda44SAniket Masule return get_framesize_raw_p010_ubwc(width, height); 1072ab1eda44SAniket Masule case HFI_COLOR_FORMAT_YUV420_TP10_UBWC: 1073ab1eda44SAniket Masule return get_framesize_raw_yuv420_tp10_ubwc(width, height); 1074e1cb72deSStanimir Varbanov default: 1075e1cb72deSStanimir Varbanov return 0; 1076e1cb72deSStanimir Varbanov } 1077e1cb72deSStanimir Varbanov } 1078e1cb72deSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_framesz_raw); 1079e1cb72deSStanimir Varbanov 1080e1cb72deSStanimir Varbanov u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height) 1081e1cb72deSStanimir Varbanov { 1082e1cb72deSStanimir Varbanov u32 hfi_fmt, sz; 1083e1cb72deSStanimir Varbanov bool compressed; 1084e1cb72deSStanimir Varbanov 1085e1cb72deSStanimir Varbanov switch (v4l2_fmt) { 1086e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_MPEG: 1087e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_H264: 1088e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_H264_NO_SC: 1089e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_H264_MVC: 1090e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_H263: 1091e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_MPEG1: 1092e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_MPEG2: 1093e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_MPEG4: 1094e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_XVID: 1095e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_VC1_ANNEX_G: 1096e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_VC1_ANNEX_L: 1097e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_VP8: 1098e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_VP9: 1099e1cb72deSStanimir Varbanov case V4L2_PIX_FMT_HEVC: 1100e1cb72deSStanimir Varbanov compressed = true; 1101e1cb72deSStanimir Varbanov break; 1102e1cb72deSStanimir Varbanov default: 1103e1cb72deSStanimir Varbanov compressed = false; 1104e1cb72deSStanimir Varbanov break; 1105e1cb72deSStanimir Varbanov } 1106e1cb72deSStanimir Varbanov 1107e1cb72deSStanimir Varbanov if (compressed) { 1108e1cb72deSStanimir Varbanov sz = ALIGN(height, 32) * ALIGN(width, 32) * 3 / 2 / 2; 1109ddd1fc49SStanimir Varbanov if (width < 1280 || height < 720) 1110ddd1fc49SStanimir Varbanov sz *= 8; 1111e1cb72deSStanimir Varbanov return ALIGN(sz, SZ_4K); 1112e1cb72deSStanimir Varbanov } 1113e1cb72deSStanimir Varbanov 1114e1cb72deSStanimir Varbanov hfi_fmt = to_hfi_raw_fmt(v4l2_fmt); 1115e1cb72deSStanimir Varbanov if (!hfi_fmt) 1116e1cb72deSStanimir Varbanov return 0; 1117e1cb72deSStanimir Varbanov 1118e1cb72deSStanimir Varbanov return venus_helper_get_framesz_raw(hfi_fmt, width, height); 1119e1cb72deSStanimir Varbanov } 1120e1cb72deSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_framesz); 1121e1cb72deSStanimir Varbanov 1122af2c3834SStanimir Varbanov int venus_helper_set_input_resolution(struct venus_inst *inst, 1123af2c3834SStanimir Varbanov unsigned int width, unsigned int height) 1124af2c3834SStanimir Varbanov { 1125af2c3834SStanimir Varbanov u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE; 1126af2c3834SStanimir Varbanov struct hfi_framesize fs; 1127af2c3834SStanimir Varbanov 1128af2c3834SStanimir Varbanov fs.buffer_type = HFI_BUFFER_INPUT; 1129af2c3834SStanimir Varbanov fs.width = width; 1130af2c3834SStanimir Varbanov fs.height = height; 1131af2c3834SStanimir Varbanov 1132af2c3834SStanimir Varbanov return hfi_session_set_property(inst, ptype, &fs); 1133af2c3834SStanimir Varbanov } 1134af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_input_resolution); 1135af2c3834SStanimir Varbanov 1136af2c3834SStanimir Varbanov int venus_helper_set_output_resolution(struct venus_inst *inst, 1137404054e1SStanimir Varbanov unsigned int width, unsigned int height, 1138404054e1SStanimir Varbanov u32 buftype) 1139af2c3834SStanimir Varbanov { 1140af2c3834SStanimir Varbanov u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE; 1141af2c3834SStanimir Varbanov struct hfi_framesize fs; 1142af2c3834SStanimir Varbanov 1143404054e1SStanimir Varbanov fs.buffer_type = buftype; 1144af2c3834SStanimir Varbanov fs.width = width; 1145af2c3834SStanimir Varbanov fs.height = height; 1146af2c3834SStanimir Varbanov 1147af2c3834SStanimir Varbanov return hfi_session_set_property(inst, ptype, &fs); 1148af2c3834SStanimir Varbanov } 1149af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_output_resolution); 1150af2c3834SStanimir Varbanov 11511ad17595SDikshita Agarwal static u32 venus_helper_get_work_mode(struct venus_inst *inst) 11521ad17595SDikshita Agarwal { 11531ad17595SDikshita Agarwal u32 mode; 11541ad17595SDikshita Agarwal u32 num_mbs; 11551ad17595SDikshita Agarwal 11561ad17595SDikshita Agarwal mode = VIDC_WORK_MODE_2; 11571ad17595SDikshita Agarwal if (inst->session_type == VIDC_SESSION_TYPE_DEC) { 11581ad17595SDikshita Agarwal num_mbs = (ALIGN(inst->height, 16) * ALIGN(inst->width, 16)) / 256; 11591ad17595SDikshita Agarwal if (inst->hfi_codec == HFI_VIDEO_CODEC_MPEG2 || 11601ad17595SDikshita Agarwal inst->pic_struct != HFI_INTERLACE_FRAME_PROGRESSIVE || 11611ad17595SDikshita Agarwal num_mbs <= NUM_MBS_720P) 11621ad17595SDikshita Agarwal mode = VIDC_WORK_MODE_1; 11631ad17595SDikshita Agarwal } else { 11641ad17595SDikshita Agarwal num_mbs = (ALIGN(inst->out_height, 16) * ALIGN(inst->out_width, 16)) / 256; 11651ad17595SDikshita Agarwal if (inst->hfi_codec == HFI_VIDEO_CODEC_VP8 && 11661ad17595SDikshita Agarwal num_mbs <= NUM_MBS_4K) 11671ad17595SDikshita Agarwal mode = VIDC_WORK_MODE_1; 11681ad17595SDikshita Agarwal } 11691ad17595SDikshita Agarwal 11701ad17595SDikshita Agarwal return mode; 11711ad17595SDikshita Agarwal } 11721ad17595SDikshita Agarwal 11731ad17595SDikshita Agarwal int venus_helper_set_work_mode(struct venus_inst *inst) 117401165b84SStanimir Varbanov { 117501165b84SStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_WORK_MODE; 117601165b84SStanimir Varbanov struct hfi_video_work_mode wm; 11771ad17595SDikshita Agarwal u32 mode; 117801165b84SStanimir Varbanov 11797ed9e0b3SBryan O'Donoghue if (!IS_V4(inst->core) && !IS_V6(inst->core)) 118001165b84SStanimir Varbanov return 0; 118101165b84SStanimir Varbanov 11821ad17595SDikshita Agarwal mode = venus_helper_get_work_mode(inst); 118301165b84SStanimir Varbanov wm.video_work_mode = mode; 118401165b84SStanimir Varbanov return hfi_session_set_property(inst, ptype, &wm); 118501165b84SStanimir Varbanov } 118601165b84SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_work_mode); 118701165b84SStanimir Varbanov 1188bc28936bSDikshita Agarwal int venus_helper_set_format_constraints(struct venus_inst *inst) 1189bc28936bSDikshita Agarwal { 1190bc28936bSDikshita Agarwal const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO; 1191bc28936bSDikshita Agarwal struct hfi_uncompressed_plane_actual_constraints_info pconstraint; 1192bc28936bSDikshita Agarwal 1193bc28936bSDikshita Agarwal if (!IS_V6(inst->core)) 1194bc28936bSDikshita Agarwal return 0; 1195bc28936bSDikshita Agarwal 1196cef92b14SStanimir Varbanov if (inst->opb_fmt == HFI_COLOR_FORMAT_NV12_UBWC || 1197cef92b14SStanimir Varbanov inst->opb_fmt == HFI_COLOR_FORMAT_YUV420_TP10_UBWC) 11981ac61fafSMansur Alisha Shaik return 0; 11991ac61fafSMansur Alisha Shaik 1200bc28936bSDikshita Agarwal pconstraint.buffer_type = HFI_BUFFER_OUTPUT2; 1201bc28936bSDikshita Agarwal pconstraint.num_planes = 2; 1202bc28936bSDikshita Agarwal pconstraint.plane_format[0].stride_multiples = 128; 1203bc28936bSDikshita Agarwal pconstraint.plane_format[0].max_stride = 8192; 1204bc28936bSDikshita Agarwal pconstraint.plane_format[0].min_plane_buffer_height_multiple = 32; 1205bc28936bSDikshita Agarwal pconstraint.plane_format[0].buffer_alignment = 256; 1206bc28936bSDikshita Agarwal 1207bc28936bSDikshita Agarwal pconstraint.plane_format[1].stride_multiples = 128; 1208bc28936bSDikshita Agarwal pconstraint.plane_format[1].max_stride = 8192; 1209bc28936bSDikshita Agarwal pconstraint.plane_format[1].min_plane_buffer_height_multiple = 16; 1210bc28936bSDikshita Agarwal pconstraint.plane_format[1].buffer_alignment = 256; 1211bc28936bSDikshita Agarwal 1212bc28936bSDikshita Agarwal return hfi_session_set_property(inst, ptype, &pconstraint); 1213bc28936bSDikshita Agarwal } 1214bc28936bSDikshita Agarwal EXPORT_SYMBOL_GPL(venus_helper_set_format_constraints); 1215bc28936bSDikshita Agarwal 1216af2c3834SStanimir Varbanov int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, 12171eb04b2eSStanimir Varbanov unsigned int output_bufs, 12181eb04b2eSStanimir Varbanov unsigned int output2_bufs) 1219af2c3834SStanimir Varbanov { 1220af2c3834SStanimir Varbanov u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL; 1221af2c3834SStanimir Varbanov struct hfi_buffer_count_actual buf_count; 1222af2c3834SStanimir Varbanov int ret; 1223af2c3834SStanimir Varbanov 1224af2c3834SStanimir Varbanov buf_count.type = HFI_BUFFER_INPUT; 1225af2c3834SStanimir Varbanov buf_count.count_actual = input_bufs; 1226af2c3834SStanimir Varbanov 1227af2c3834SStanimir Varbanov ret = hfi_session_set_property(inst, ptype, &buf_count); 1228af2c3834SStanimir Varbanov if (ret) 1229af2c3834SStanimir Varbanov return ret; 1230af2c3834SStanimir Varbanov 1231af2c3834SStanimir Varbanov buf_count.type = HFI_BUFFER_OUTPUT; 1232af2c3834SStanimir Varbanov buf_count.count_actual = output_bufs; 1233af2c3834SStanimir Varbanov 12341eb04b2eSStanimir Varbanov ret = hfi_session_set_property(inst, ptype, &buf_count); 12351eb04b2eSStanimir Varbanov if (ret) 12361eb04b2eSStanimir Varbanov return ret; 12371eb04b2eSStanimir Varbanov 12381eb04b2eSStanimir Varbanov if (output2_bufs) { 12391eb04b2eSStanimir Varbanov buf_count.type = HFI_BUFFER_OUTPUT2; 12401eb04b2eSStanimir Varbanov buf_count.count_actual = output2_bufs; 12411eb04b2eSStanimir Varbanov 12421eb04b2eSStanimir Varbanov ret = hfi_session_set_property(inst, ptype, &buf_count); 12431eb04b2eSStanimir Varbanov } 12441eb04b2eSStanimir Varbanov 12451eb04b2eSStanimir Varbanov return ret; 1246af2c3834SStanimir Varbanov } 1247af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_num_bufs); 1248af2c3834SStanimir Varbanov 1249ab97a3fbSStanimir Varbanov int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format, 1250ab97a3fbSStanimir Varbanov u32 buftype) 1251ab97a3fbSStanimir Varbanov { 1252ab97a3fbSStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT; 1253ab97a3fbSStanimir Varbanov struct hfi_uncompressed_format_select fmt; 1254ab97a3fbSStanimir Varbanov 1255ab97a3fbSStanimir Varbanov fmt.buffer_type = buftype; 1256ab97a3fbSStanimir Varbanov fmt.format = hfi_format; 1257ab97a3fbSStanimir Varbanov 1258ab97a3fbSStanimir Varbanov return hfi_session_set_property(inst, ptype, &fmt); 1259ab97a3fbSStanimir Varbanov } 1260ab97a3fbSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_raw_format); 1261ab97a3fbSStanimir Varbanov 1262af2c3834SStanimir Varbanov int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt) 1263af2c3834SStanimir Varbanov { 1264ab97a3fbSStanimir Varbanov u32 hfi_format, buftype; 1265af2c3834SStanimir Varbanov 1266af2c3834SStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_DEC) 1267ab97a3fbSStanimir Varbanov buftype = HFI_BUFFER_OUTPUT; 1268af2c3834SStanimir Varbanov else if (inst->session_type == VIDC_SESSION_TYPE_ENC) 1269ab97a3fbSStanimir Varbanov buftype = HFI_BUFFER_INPUT; 1270af2c3834SStanimir Varbanov else 1271af2c3834SStanimir Varbanov return -EINVAL; 1272af2c3834SStanimir Varbanov 1273ab97a3fbSStanimir Varbanov hfi_format = to_hfi_raw_fmt(pixfmt); 1274ab97a3fbSStanimir Varbanov if (!hfi_format) 1275af2c3834SStanimir Varbanov return -EINVAL; 1276af2c3834SStanimir Varbanov 1277ab97a3fbSStanimir Varbanov return venus_helper_set_raw_format(inst, hfi_format, buftype); 1278af2c3834SStanimir Varbanov } 1279af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_color_format); 1280af2c3834SStanimir Varbanov 1281f012b23dSStanimir Varbanov int venus_helper_set_multistream(struct venus_inst *inst, bool out_en, 1282f012b23dSStanimir Varbanov bool out2_en) 1283f012b23dSStanimir Varbanov { 1284f012b23dSStanimir Varbanov struct hfi_multi_stream multi = {0}; 1285f012b23dSStanimir Varbanov u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM; 1286f012b23dSStanimir Varbanov int ret; 1287f012b23dSStanimir Varbanov 1288f012b23dSStanimir Varbanov multi.buffer_type = HFI_BUFFER_OUTPUT; 1289f012b23dSStanimir Varbanov multi.enable = out_en; 1290f012b23dSStanimir Varbanov 1291f012b23dSStanimir Varbanov ret = hfi_session_set_property(inst, ptype, &multi); 1292f012b23dSStanimir Varbanov if (ret) 1293f012b23dSStanimir Varbanov return ret; 1294f012b23dSStanimir Varbanov 1295f012b23dSStanimir Varbanov multi.buffer_type = HFI_BUFFER_OUTPUT2; 1296f012b23dSStanimir Varbanov multi.enable = out2_en; 1297f012b23dSStanimir Varbanov 1298f012b23dSStanimir Varbanov return hfi_session_set_property(inst, ptype, &multi); 1299f012b23dSStanimir Varbanov } 1300f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_multistream); 1301f012b23dSStanimir Varbanov 13022b0a8517SStanimir Varbanov int venus_helper_set_dyn_bufmode(struct venus_inst *inst) 13032b0a8517SStanimir Varbanov { 13042b0a8517SStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE; 13052b0a8517SStanimir Varbanov struct hfi_buffer_alloc_mode mode; 13062b0a8517SStanimir Varbanov int ret; 13072b0a8517SStanimir Varbanov 13082b0a8517SStanimir Varbanov if (!is_dynamic_bufmode(inst)) 13092b0a8517SStanimir Varbanov return 0; 13102b0a8517SStanimir Varbanov 13112b0a8517SStanimir Varbanov mode.type = HFI_BUFFER_OUTPUT; 13122b0a8517SStanimir Varbanov mode.mode = HFI_BUFFER_MODE_DYNAMIC; 13132b0a8517SStanimir Varbanov 13142b0a8517SStanimir Varbanov ret = hfi_session_set_property(inst, ptype, &mode); 13152b0a8517SStanimir Varbanov if (ret) 13162b0a8517SStanimir Varbanov return ret; 13172b0a8517SStanimir Varbanov 13182b0a8517SStanimir Varbanov mode.type = HFI_BUFFER_OUTPUT2; 13192b0a8517SStanimir Varbanov 13202b0a8517SStanimir Varbanov return hfi_session_set_property(inst, ptype, &mode); 13212b0a8517SStanimir Varbanov } 13222b0a8517SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_dyn_bufmode); 13232b0a8517SStanimir Varbanov 1324d4a5b0a6SStanimir Varbanov int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype) 1325d4a5b0a6SStanimir Varbanov { 1326d4a5b0a6SStanimir Varbanov const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL; 1327d4a5b0a6SStanimir Varbanov struct hfi_buffer_size_actual bufsz; 1328d4a5b0a6SStanimir Varbanov 1329d4a5b0a6SStanimir Varbanov bufsz.type = buftype; 1330d4a5b0a6SStanimir Varbanov bufsz.size = bufsize; 1331d4a5b0a6SStanimir Varbanov 1332d4a5b0a6SStanimir Varbanov return hfi_session_set_property(inst, ptype, &bufsz); 1333d4a5b0a6SStanimir Varbanov } 1334d4a5b0a6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_bufsize); 1335d4a5b0a6SStanimir Varbanov 1336130c0117SStanimir Varbanov unsigned int venus_helper_get_opb_size(struct venus_inst *inst) 1337130c0117SStanimir Varbanov { 1338130c0117SStanimir Varbanov /* the encoder has only one output */ 1339130c0117SStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_ENC) 1340130c0117SStanimir Varbanov return inst->output_buf_size; 1341130c0117SStanimir Varbanov 1342130c0117SStanimir Varbanov if (inst->opb_buftype == HFI_BUFFER_OUTPUT) 1343130c0117SStanimir Varbanov return inst->output_buf_size; 1344130c0117SStanimir Varbanov else if (inst->opb_buftype == HFI_BUFFER_OUTPUT2) 1345130c0117SStanimir Varbanov return inst->output2_buf_size; 1346130c0117SStanimir Varbanov 1347130c0117SStanimir Varbanov return 0; 1348130c0117SStanimir Varbanov } 1349130c0117SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_opb_size); 1350130c0117SStanimir Varbanov 1351af2c3834SStanimir Varbanov static void delayed_process_buf_func(struct work_struct *work) 1352af2c3834SStanimir Varbanov { 1353af2c3834SStanimir Varbanov struct venus_buffer *buf, *n; 1354af2c3834SStanimir Varbanov struct venus_inst *inst; 1355af2c3834SStanimir Varbanov int ret; 1356af2c3834SStanimir Varbanov 1357af2c3834SStanimir Varbanov inst = container_of(work, struct venus_inst, delayed_process_work); 1358af2c3834SStanimir Varbanov 1359af2c3834SStanimir Varbanov mutex_lock(&inst->lock); 1360af2c3834SStanimir Varbanov 1361af2c3834SStanimir Varbanov if (!(inst->streamon_out & inst->streamon_cap)) 1362af2c3834SStanimir Varbanov goto unlock; 1363af2c3834SStanimir Varbanov 1364af2c3834SStanimir Varbanov list_for_each_entry_safe(buf, n, &inst->delayed_process, ref_list) { 1365af2c3834SStanimir Varbanov if (buf->flags & HFI_BUFFERFLAG_READONLY) 1366af2c3834SStanimir Varbanov continue; 1367af2c3834SStanimir Varbanov 1368af2c3834SStanimir Varbanov ret = session_process_buf(inst, &buf->vb); 1369af2c3834SStanimir Varbanov if (ret) 1370af2c3834SStanimir Varbanov return_buf_error(inst, &buf->vb); 1371af2c3834SStanimir Varbanov 1372af2c3834SStanimir Varbanov list_del_init(&buf->ref_list); 1373af2c3834SStanimir Varbanov } 1374af2c3834SStanimir Varbanov unlock: 1375af2c3834SStanimir Varbanov mutex_unlock(&inst->lock); 1376af2c3834SStanimir Varbanov } 1377af2c3834SStanimir Varbanov 1378af2c3834SStanimir Varbanov void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx) 1379af2c3834SStanimir Varbanov { 1380af2c3834SStanimir Varbanov struct venus_buffer *buf; 1381af2c3834SStanimir Varbanov 1382af2c3834SStanimir Varbanov list_for_each_entry(buf, &inst->registeredbufs, reg_list) { 1383af2c3834SStanimir Varbanov if (buf->vb.vb2_buf.index == idx) { 1384af2c3834SStanimir Varbanov buf->flags &= ~HFI_BUFFERFLAG_READONLY; 1385af2c3834SStanimir Varbanov schedule_work(&inst->delayed_process_work); 1386af2c3834SStanimir Varbanov break; 1387af2c3834SStanimir Varbanov } 1388af2c3834SStanimir Varbanov } 1389af2c3834SStanimir Varbanov } 1390af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_release_buf_ref); 1391af2c3834SStanimir Varbanov 1392af2c3834SStanimir Varbanov void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf) 1393af2c3834SStanimir Varbanov { 1394af2c3834SStanimir Varbanov struct venus_buffer *buf = to_venus_buffer(vbuf); 1395af2c3834SStanimir Varbanov 1396af2c3834SStanimir Varbanov buf->flags |= HFI_BUFFERFLAG_READONLY; 1397af2c3834SStanimir Varbanov } 1398af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_acquire_buf_ref); 1399af2c3834SStanimir Varbanov 1400af2c3834SStanimir Varbanov static int is_buf_refed(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) 1401af2c3834SStanimir Varbanov { 1402af2c3834SStanimir Varbanov struct venus_buffer *buf = to_venus_buffer(vbuf); 1403af2c3834SStanimir Varbanov 1404af2c3834SStanimir Varbanov if (buf->flags & HFI_BUFFERFLAG_READONLY) { 1405af2c3834SStanimir Varbanov list_add_tail(&buf->ref_list, &inst->delayed_process); 1406af2c3834SStanimir Varbanov schedule_work(&inst->delayed_process_work); 1407af2c3834SStanimir Varbanov return 1; 1408af2c3834SStanimir Varbanov } 1409af2c3834SStanimir Varbanov 1410af2c3834SStanimir Varbanov return 0; 1411af2c3834SStanimir Varbanov } 1412af2c3834SStanimir Varbanov 1413af2c3834SStanimir Varbanov struct vb2_v4l2_buffer * 1414af2c3834SStanimir Varbanov venus_helper_find_buf(struct venus_inst *inst, unsigned int type, u32 idx) 1415af2c3834SStanimir Varbanov { 1416af2c3834SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 1417af2c3834SStanimir Varbanov 1418af2c3834SStanimir Varbanov if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1419af2c3834SStanimir Varbanov return v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, idx); 1420af2c3834SStanimir Varbanov else 1421af2c3834SStanimir Varbanov return v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx, idx); 1422af2c3834SStanimir Varbanov } 1423af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_find_buf); 1424af2c3834SStanimir Varbanov 142540d87aafSMansur Alisha Shaik void venus_helper_change_dpb_owner(struct venus_inst *inst, 142640d87aafSMansur Alisha Shaik struct vb2_v4l2_buffer *vbuf, unsigned int type, 142740d87aafSMansur Alisha Shaik unsigned int buf_type, u32 tag) 142840d87aafSMansur Alisha Shaik { 142940d87aafSMansur Alisha Shaik struct intbuf *dpb_buf; 143040d87aafSMansur Alisha Shaik 143140d87aafSMansur Alisha Shaik if (!V4L2_TYPE_IS_CAPTURE(type) || 143240d87aafSMansur Alisha Shaik buf_type != inst->dpb_buftype) 143340d87aafSMansur Alisha Shaik return; 143440d87aafSMansur Alisha Shaik 143540d87aafSMansur Alisha Shaik list_for_each_entry(dpb_buf, &inst->dpbbufs, list) 143640d87aafSMansur Alisha Shaik if (dpb_buf->dpb_out_tag == tag) { 143740d87aafSMansur Alisha Shaik dpb_buf->owned_by = DRIVER; 143840d87aafSMansur Alisha Shaik break; 143940d87aafSMansur Alisha Shaik } 144040d87aafSMansur Alisha Shaik } 144140d87aafSMansur Alisha Shaik EXPORT_SYMBOL_GPL(venus_helper_change_dpb_owner); 144240d87aafSMansur Alisha Shaik 1443af2c3834SStanimir Varbanov int venus_helper_vb2_buf_init(struct vb2_buffer *vb) 1444af2c3834SStanimir Varbanov { 1445af2c3834SStanimir Varbanov struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1446af2c3834SStanimir Varbanov struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1447af2c3834SStanimir Varbanov struct venus_buffer *buf = to_venus_buffer(vbuf); 1448af2c3834SStanimir Varbanov 1449af2c3834SStanimir Varbanov buf->size = vb2_plane_size(vb, 0); 1450cc82fd69SAlexandre Courbot buf->dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); 1451af2c3834SStanimir Varbanov 1452af2c3834SStanimir Varbanov if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1453af2c3834SStanimir Varbanov list_add_tail(&buf->reg_list, &inst->registeredbufs); 1454af2c3834SStanimir Varbanov 1455af2c3834SStanimir Varbanov return 0; 1456af2c3834SStanimir Varbanov } 1457af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_init); 1458af2c3834SStanimir Varbanov 1459af2c3834SStanimir Varbanov int venus_helper_vb2_buf_prepare(struct vb2_buffer *vb) 1460af2c3834SStanimir Varbanov { 1461af2c3834SStanimir Varbanov struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1462f012b23dSStanimir Varbanov unsigned int out_buf_size = venus_helper_get_opb_size(inst); 146305979046SStanimir Varbanov struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 146405979046SStanimir Varbanov 146505979046SStanimir Varbanov if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { 146605979046SStanimir Varbanov if (vbuf->field == V4L2_FIELD_ANY) 146705979046SStanimir Varbanov vbuf->field = V4L2_FIELD_NONE; 146805979046SStanimir Varbanov if (vbuf->field != V4L2_FIELD_NONE) { 146905979046SStanimir Varbanov dev_err(inst->core->dev, "%s field isn't supported\n", 147005979046SStanimir Varbanov __func__); 147105979046SStanimir Varbanov return -EINVAL; 147205979046SStanimir Varbanov } 147305979046SStanimir Varbanov } 1474af2c3834SStanimir Varbanov 1475af2c3834SStanimir Varbanov if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 1476f012b23dSStanimir Varbanov vb2_plane_size(vb, 0) < out_buf_size) 1477af2c3834SStanimir Varbanov return -EINVAL; 1478af2c3834SStanimir Varbanov if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 1479af2c3834SStanimir Varbanov vb2_plane_size(vb, 0) < inst->input_buf_size) 1480af2c3834SStanimir Varbanov return -EINVAL; 1481af2c3834SStanimir Varbanov 1482af2c3834SStanimir Varbanov return 0; 1483af2c3834SStanimir Varbanov } 1484af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_prepare); 1485af2c3834SStanimir Varbanov 1486fd1ee315SStanimir Varbanov static void cache_payload(struct venus_inst *inst, struct vb2_buffer *vb) 1487fd1ee315SStanimir Varbanov { 1488fd1ee315SStanimir Varbanov struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1489fd1ee315SStanimir Varbanov unsigned int idx = vbuf->vb2_buf.index; 1490fd1ee315SStanimir Varbanov 1491fd1ee315SStanimir Varbanov if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1492fd1ee315SStanimir Varbanov inst->payloads[idx] = vb2_get_plane_payload(vb, 0); 1493fd1ee315SStanimir Varbanov } 1494fd1ee315SStanimir Varbanov 1495af2c3834SStanimir Varbanov void venus_helper_vb2_buf_queue(struct vb2_buffer *vb) 1496af2c3834SStanimir Varbanov { 1497af2c3834SStanimir Varbanov struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1498af2c3834SStanimir Varbanov struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1499af2c3834SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 1500af2c3834SStanimir Varbanov int ret; 1501af2c3834SStanimir Varbanov 1502af2c3834SStanimir Varbanov v4l2_m2m_buf_queue(m2m_ctx, vbuf); 1503af2c3834SStanimir Varbanov 1504acf8a57dSStanimir Varbanov /* Skip processing queued capture buffers after LAST flag */ 1505acf8a57dSStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_DEC && 1506acf8a57dSStanimir Varbanov V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && 1507acf8a57dSStanimir Varbanov inst->codec_state == VENUS_DEC_STATE_DRC) 150821560ddfSStanimir Varbanov return; 1509acf8a57dSStanimir Varbanov 1510fd1ee315SStanimir Varbanov cache_payload(inst, vb); 1511fd1ee315SStanimir Varbanov 1512beac8290SStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_ENC && 1513beac8290SStanimir Varbanov !(inst->streamon_out && inst->streamon_cap)) 151421560ddfSStanimir Varbanov return; 1515af2c3834SStanimir Varbanov 1516beac8290SStanimir Varbanov if (vb2_start_streaming_called(vb->vb2_queue)) { 1517af2c3834SStanimir Varbanov ret = is_buf_refed(inst, vbuf); 1518af2c3834SStanimir Varbanov if (ret) 151921560ddfSStanimir Varbanov return; 1520af2c3834SStanimir Varbanov 1521af2c3834SStanimir Varbanov ret = session_process_buf(inst, vbuf); 1522af2c3834SStanimir Varbanov if (ret) 1523af2c3834SStanimir Varbanov return_buf_error(inst, vbuf); 1524beac8290SStanimir Varbanov } 1525af2c3834SStanimir Varbanov } 1526af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_queue); 1527af2c3834SStanimir Varbanov 15280febf923SStanimir Varbanov void venus_helper_buffers_done(struct venus_inst *inst, unsigned int type, 1529af2c3834SStanimir Varbanov enum vb2_buffer_state state) 1530af2c3834SStanimir Varbanov { 1531af2c3834SStanimir Varbanov struct vb2_v4l2_buffer *buf; 1532af2c3834SStanimir Varbanov 15330febf923SStanimir Varbanov if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 1534af2c3834SStanimir Varbanov while ((buf = v4l2_m2m_src_buf_remove(inst->m2m_ctx))) 1535af2c3834SStanimir Varbanov v4l2_m2m_buf_done(buf, state); 15360febf923SStanimir Varbanov } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 1537af2c3834SStanimir Varbanov while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx))) 1538af2c3834SStanimir Varbanov v4l2_m2m_buf_done(buf, state); 1539af2c3834SStanimir Varbanov } 15400febf923SStanimir Varbanov } 1541af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_buffers_done); 1542af2c3834SStanimir Varbanov 1543af2c3834SStanimir Varbanov void venus_helper_vb2_stop_streaming(struct vb2_queue *q) 1544af2c3834SStanimir Varbanov { 1545af2c3834SStanimir Varbanov struct venus_inst *inst = vb2_get_drv_priv(q); 1546af2c3834SStanimir Varbanov struct venus_core *core = inst->core; 1547af2c3834SStanimir Varbanov int ret; 1548af2c3834SStanimir Varbanov 1549af2c3834SStanimir Varbanov mutex_lock(&inst->lock); 1550af2c3834SStanimir Varbanov 1551af2c3834SStanimir Varbanov if (inst->streamon_out & inst->streamon_cap) { 1552af2c3834SStanimir Varbanov ret = hfi_session_stop(inst); 1553af2c3834SStanimir Varbanov ret |= hfi_session_unload_res(inst); 15541e485ee5SStanimir Varbanov ret |= venus_helper_unregister_bufs(inst); 15551e485ee5SStanimir Varbanov ret |= venus_helper_intbufs_free(inst); 1556af2c3834SStanimir Varbanov ret |= hfi_session_deinit(inst); 1557af2c3834SStanimir Varbanov 1558b46ff4ebSStanimir Varbanov if (inst->session_error || test_bit(0, &core->sys_error)) 1559af2c3834SStanimir Varbanov ret = -EIO; 1560af2c3834SStanimir Varbanov 1561af2c3834SStanimir Varbanov if (ret) 1562af2c3834SStanimir Varbanov hfi_session_abort(inst); 1563af2c3834SStanimir Varbanov 1564f012b23dSStanimir Varbanov venus_helper_free_dpb_bufs(inst); 1565f012b23dSStanimir Varbanov 15667482a983SStanimir Varbanov venus_pm_load_scale(inst); 1567bbd770aeSStanimir Varbanov INIT_LIST_HEAD(&inst->registeredbufs); 1568af2c3834SStanimir Varbanov } 1569af2c3834SStanimir Varbanov 15700febf923SStanimir Varbanov venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 15710febf923SStanimir Varbanov VB2_BUF_STATE_ERROR); 15720febf923SStanimir Varbanov venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 15730febf923SStanimir Varbanov VB2_BUF_STATE_ERROR); 1574af2c3834SStanimir Varbanov 1575af2c3834SStanimir Varbanov if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1576af2c3834SStanimir Varbanov inst->streamon_out = 0; 1577af2c3834SStanimir Varbanov else 1578af2c3834SStanimir Varbanov inst->streamon_cap = 0; 1579af2c3834SStanimir Varbanov 15804ebf9693SAniket Masule venus_pm_release_core(inst); 15814ebf9693SAniket Masule 15823227a8f7SStanimir Varbanov inst->session_error = 0; 15833227a8f7SStanimir Varbanov 1584af2c3834SStanimir Varbanov mutex_unlock(&inst->lock); 1585af2c3834SStanimir Varbanov } 1586af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming); 1587af2c3834SStanimir Varbanov 1588aa6dcf17SStanimir Varbanov void venus_helper_vb2_queue_error(struct venus_inst *inst) 1589aa6dcf17SStanimir Varbanov { 1590aa6dcf17SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 1591aa6dcf17SStanimir Varbanov struct vb2_queue *q; 1592aa6dcf17SStanimir Varbanov 1593aa6dcf17SStanimir Varbanov q = v4l2_m2m_get_src_vq(m2m_ctx); 1594aa6dcf17SStanimir Varbanov vb2_queue_error(q); 1595aa6dcf17SStanimir Varbanov q = v4l2_m2m_get_dst_vq(m2m_ctx); 1596aa6dcf17SStanimir Varbanov vb2_queue_error(q); 1597aa6dcf17SStanimir Varbanov } 1598aa6dcf17SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_queue_error); 1599aa6dcf17SStanimir Varbanov 160014ea00d6SStanimir Varbanov int venus_helper_process_initial_cap_bufs(struct venus_inst *inst) 160114ea00d6SStanimir Varbanov { 160214ea00d6SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 160314ea00d6SStanimir Varbanov struct v4l2_m2m_buffer *buf, *n; 160414ea00d6SStanimir Varbanov int ret; 160514ea00d6SStanimir Varbanov 160614ea00d6SStanimir Varbanov v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) { 160714ea00d6SStanimir Varbanov ret = session_process_buf(inst, &buf->vb); 160814ea00d6SStanimir Varbanov if (ret) { 160914ea00d6SStanimir Varbanov return_buf_error(inst, &buf->vb); 161014ea00d6SStanimir Varbanov return ret; 161114ea00d6SStanimir Varbanov } 161214ea00d6SStanimir Varbanov } 161314ea00d6SStanimir Varbanov 161414ea00d6SStanimir Varbanov return 0; 161514ea00d6SStanimir Varbanov } 161614ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_process_initial_cap_bufs); 161714ea00d6SStanimir Varbanov 161814ea00d6SStanimir Varbanov int venus_helper_process_initial_out_bufs(struct venus_inst *inst) 161914ea00d6SStanimir Varbanov { 162014ea00d6SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 162114ea00d6SStanimir Varbanov struct v4l2_m2m_buffer *buf, *n; 162214ea00d6SStanimir Varbanov int ret; 162314ea00d6SStanimir Varbanov 162414ea00d6SStanimir Varbanov v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) { 162514ea00d6SStanimir Varbanov ret = session_process_buf(inst, &buf->vb); 162614ea00d6SStanimir Varbanov if (ret) { 162714ea00d6SStanimir Varbanov return_buf_error(inst, &buf->vb); 162814ea00d6SStanimir Varbanov return ret; 162914ea00d6SStanimir Varbanov } 163014ea00d6SStanimir Varbanov } 163114ea00d6SStanimir Varbanov 163214ea00d6SStanimir Varbanov return 0; 163314ea00d6SStanimir Varbanov } 163414ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_process_initial_out_bufs); 163514ea00d6SStanimir Varbanov 1636af2c3834SStanimir Varbanov int venus_helper_vb2_start_streaming(struct venus_inst *inst) 1637af2c3834SStanimir Varbanov { 1638af2c3834SStanimir Varbanov int ret; 1639af2c3834SStanimir Varbanov 16401e485ee5SStanimir Varbanov ret = venus_helper_intbufs_alloc(inst); 1641af2c3834SStanimir Varbanov if (ret) 1642af2c3834SStanimir Varbanov return ret; 1643af2c3834SStanimir Varbanov 1644af2c3834SStanimir Varbanov ret = session_register_bufs(inst); 1645af2c3834SStanimir Varbanov if (ret) 1646af2c3834SStanimir Varbanov goto err_bufs_free; 1647af2c3834SStanimir Varbanov 16487482a983SStanimir Varbanov venus_pm_load_scale(inst); 1649af2c3834SStanimir Varbanov 1650af2c3834SStanimir Varbanov ret = hfi_session_load_res(inst); 1651af2c3834SStanimir Varbanov if (ret) 1652af2c3834SStanimir Varbanov goto err_unreg_bufs; 1653af2c3834SStanimir Varbanov 1654af2c3834SStanimir Varbanov ret = hfi_session_start(inst); 1655af2c3834SStanimir Varbanov if (ret) 1656af2c3834SStanimir Varbanov goto err_unload_res; 1657af2c3834SStanimir Varbanov 1658af2c3834SStanimir Varbanov return 0; 1659af2c3834SStanimir Varbanov 1660af2c3834SStanimir Varbanov err_unload_res: 1661af2c3834SStanimir Varbanov hfi_session_unload_res(inst); 1662af2c3834SStanimir Varbanov err_unreg_bufs: 16631e485ee5SStanimir Varbanov venus_helper_unregister_bufs(inst); 1664af2c3834SStanimir Varbanov err_bufs_free: 16651e485ee5SStanimir Varbanov venus_helper_intbufs_free(inst); 1666af2c3834SStanimir Varbanov return ret; 1667af2c3834SStanimir Varbanov } 1668af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_start_streaming); 1669af2c3834SStanimir Varbanov 1670af2c3834SStanimir Varbanov void venus_helper_m2m_device_run(void *priv) 1671af2c3834SStanimir Varbanov { 1672af2c3834SStanimir Varbanov struct venus_inst *inst = priv; 1673af2c3834SStanimir Varbanov struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 1674af2c3834SStanimir Varbanov struct v4l2_m2m_buffer *buf, *n; 1675af2c3834SStanimir Varbanov int ret; 1676af2c3834SStanimir Varbanov 1677af2c3834SStanimir Varbanov mutex_lock(&inst->lock); 1678af2c3834SStanimir Varbanov 1679af2c3834SStanimir Varbanov v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) { 1680af2c3834SStanimir Varbanov ret = session_process_buf(inst, &buf->vb); 1681af2c3834SStanimir Varbanov if (ret) 1682af2c3834SStanimir Varbanov return_buf_error(inst, &buf->vb); 1683af2c3834SStanimir Varbanov } 1684af2c3834SStanimir Varbanov 1685af2c3834SStanimir Varbanov v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) { 1686af2c3834SStanimir Varbanov ret = session_process_buf(inst, &buf->vb); 1687af2c3834SStanimir Varbanov if (ret) 1688af2c3834SStanimir Varbanov return_buf_error(inst, &buf->vb); 1689af2c3834SStanimir Varbanov } 1690af2c3834SStanimir Varbanov 1691af2c3834SStanimir Varbanov mutex_unlock(&inst->lock); 1692af2c3834SStanimir Varbanov } 1693af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_m2m_device_run); 1694af2c3834SStanimir Varbanov 1695af2c3834SStanimir Varbanov void venus_helper_m2m_job_abort(void *priv) 1696af2c3834SStanimir Varbanov { 1697af2c3834SStanimir Varbanov struct venus_inst *inst = priv; 1698af2c3834SStanimir Varbanov 1699af2c3834SStanimir Varbanov v4l2_m2m_job_finish(inst->m2m_dev, inst->m2m_ctx); 1700af2c3834SStanimir Varbanov } 1701af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_m2m_job_abort); 1702af2c3834SStanimir Varbanov 1703aa603389SStanimir Varbanov int venus_helper_session_init(struct venus_inst *inst) 1704aa603389SStanimir Varbanov { 1705aa603389SStanimir Varbanov enum hfi_version version = inst->core->res->hfi_version; 1706aa603389SStanimir Varbanov u32 session_type = inst->session_type; 1707aa603389SStanimir Varbanov u32 codec; 1708aa603389SStanimir Varbanov int ret; 1709aa603389SStanimir Varbanov 1710aa603389SStanimir Varbanov codec = inst->session_type == VIDC_SESSION_TYPE_DEC ? 1711aa603389SStanimir Varbanov inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt; 1712aa603389SStanimir Varbanov 1713aa603389SStanimir Varbanov ret = hfi_session_init(inst, codec); 1714aa603389SStanimir Varbanov if (ret) 1715aa603389SStanimir Varbanov return ret; 1716aa603389SStanimir Varbanov 1717aa603389SStanimir Varbanov inst->clk_data.vpp_freq = hfi_platform_get_codec_vpp_freq(version, codec, 1718aa603389SStanimir Varbanov session_type); 1719aa603389SStanimir Varbanov inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(version, codec, 1720aa603389SStanimir Varbanov session_type); 17213cfe5815SDikshita Agarwal inst->clk_data.low_power_freq = hfi_platform_get_codec_lp_freq(version, codec, 17223cfe5815SDikshita Agarwal session_type); 1723aa603389SStanimir Varbanov 1724aa603389SStanimir Varbanov return 0; 1725aa603389SStanimir Varbanov } 1726aa603389SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_session_init); 1727aa603389SStanimir Varbanov 1728af2c3834SStanimir Varbanov void venus_helper_init_instance(struct venus_inst *inst) 1729af2c3834SStanimir Varbanov { 1730af2c3834SStanimir Varbanov if (inst->session_type == VIDC_SESSION_TYPE_DEC) { 1731af2c3834SStanimir Varbanov INIT_LIST_HEAD(&inst->delayed_process); 1732af2c3834SStanimir Varbanov INIT_WORK(&inst->delayed_process_work, 1733af2c3834SStanimir Varbanov delayed_process_buf_func); 1734af2c3834SStanimir Varbanov } 1735af2c3834SStanimir Varbanov } 1736af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_init_instance); 1737aa3a8414SStanimir Varbanov 17388f3b41dcSStanimir Varbanov static bool find_fmt_from_caps(struct hfi_plat_caps *caps, u32 buftype, u32 fmt) 1739f012b23dSStanimir Varbanov { 1740f012b23dSStanimir Varbanov unsigned int i; 1741f012b23dSStanimir Varbanov 1742f012b23dSStanimir Varbanov for (i = 0; i < caps->num_fmts; i++) { 1743f012b23dSStanimir Varbanov if (caps->fmts[i].buftype == buftype && 1744f012b23dSStanimir Varbanov caps->fmts[i].fmt == fmt) 1745f012b23dSStanimir Varbanov return true; 1746f012b23dSStanimir Varbanov } 1747f012b23dSStanimir Varbanov 1748f012b23dSStanimir Varbanov return false; 1749f012b23dSStanimir Varbanov } 1750f012b23dSStanimir Varbanov 1751f012b23dSStanimir Varbanov int venus_helper_get_out_fmts(struct venus_inst *inst, u32 v4l2_fmt, 1752f012b23dSStanimir Varbanov u32 *out_fmt, u32 *out2_fmt, bool ubwc) 1753f012b23dSStanimir Varbanov { 1754f012b23dSStanimir Varbanov struct venus_core *core = inst->core; 17558f3b41dcSStanimir Varbanov struct hfi_plat_caps *caps; 1756f012b23dSStanimir Varbanov u32 ubwc_fmt, fmt = to_hfi_raw_fmt(v4l2_fmt); 1757f012b23dSStanimir Varbanov bool found, found_ubwc; 1758f012b23dSStanimir Varbanov 1759f012b23dSStanimir Varbanov *out_fmt = *out2_fmt = 0; 1760f012b23dSStanimir Varbanov 1761f012b23dSStanimir Varbanov if (!fmt) 1762f012b23dSStanimir Varbanov return -EINVAL; 1763f012b23dSStanimir Varbanov 1764f012b23dSStanimir Varbanov caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type); 1765f012b23dSStanimir Varbanov if (!caps) 1766f012b23dSStanimir Varbanov return -EINVAL; 1767f012b23dSStanimir Varbanov 1768996d2155SDikshita Agarwal if (inst->bit_depth == VIDC_BITDEPTH_10 && inst->session_type == VIDC_SESSION_TYPE_DEC) { 1769996d2155SDikshita Agarwal found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, 1770996d2155SDikshita Agarwal HFI_COLOR_FORMAT_YUV420_TP10_UBWC); 1771996d2155SDikshita Agarwal found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt); 1772996d2155SDikshita Agarwal if (found_ubwc && found) { 1773996d2155SDikshita Agarwal /* 1774996d2155SDikshita Agarwal * Hard-code DPB buffers to be 10bit UBWC 1775996d2155SDikshita Agarwal * until V4L2 is able to expose compressed/tiled 1776996d2155SDikshita Agarwal * formats to applications. 1777996d2155SDikshita Agarwal */ 1778996d2155SDikshita Agarwal *out_fmt = HFI_COLOR_FORMAT_YUV420_TP10_UBWC; 1779996d2155SDikshita Agarwal *out2_fmt = fmt; 1780996d2155SDikshita Agarwal return 0; 1781996d2155SDikshita Agarwal } 1782996d2155SDikshita Agarwal } 1783996d2155SDikshita Agarwal 1784f012b23dSStanimir Varbanov if (ubwc) { 1785f012b23dSStanimir Varbanov ubwc_fmt = fmt | HFI_COLOR_FORMAT_UBWC_BASE; 1786f012b23dSStanimir Varbanov found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, 1787f012b23dSStanimir Varbanov ubwc_fmt); 1788f012b23dSStanimir Varbanov found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt); 1789f012b23dSStanimir Varbanov 1790f012b23dSStanimir Varbanov if (found_ubwc && found) { 1791f012b23dSStanimir Varbanov *out_fmt = ubwc_fmt; 1792f012b23dSStanimir Varbanov *out2_fmt = fmt; 1793f012b23dSStanimir Varbanov return 0; 1794f012b23dSStanimir Varbanov } 1795f012b23dSStanimir Varbanov } 1796f012b23dSStanimir Varbanov 1797f012b23dSStanimir Varbanov found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, fmt); 1798f012b23dSStanimir Varbanov if (found) { 1799f012b23dSStanimir Varbanov *out_fmt = fmt; 1800f012b23dSStanimir Varbanov *out2_fmt = 0; 1801f012b23dSStanimir Varbanov return 0; 1802f012b23dSStanimir Varbanov } 1803f012b23dSStanimir Varbanov 1804f012b23dSStanimir Varbanov found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt); 1805f012b23dSStanimir Varbanov if (found) { 1806f012b23dSStanimir Varbanov *out_fmt = 0; 1807f012b23dSStanimir Varbanov *out2_fmt = fmt; 1808f012b23dSStanimir Varbanov return 0; 1809f012b23dSStanimir Varbanov } 1810f012b23dSStanimir Varbanov 1811f012b23dSStanimir Varbanov return -EINVAL; 1812f012b23dSStanimir Varbanov } 1813f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_out_fmts); 181401e869e7SDikshita Agarwal 1815fc00086eSStanimir Varbanov bool venus_helper_check_format(struct venus_inst *inst, u32 v4l2_pixfmt) 1816fc00086eSStanimir Varbanov { 1817fc00086eSStanimir Varbanov struct venus_core *core = inst->core; 1818fc00086eSStanimir Varbanov u32 fmt = to_hfi_raw_fmt(v4l2_pixfmt); 1819fc00086eSStanimir Varbanov struct hfi_plat_caps *caps; 18207f77fa9fSBryan O'Donoghue bool found; 1821fc00086eSStanimir Varbanov 1822fc00086eSStanimir Varbanov if (!fmt) 1823fc00086eSStanimir Varbanov return false; 1824fc00086eSStanimir Varbanov 1825fc00086eSStanimir Varbanov caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type); 1826fc00086eSStanimir Varbanov if (!caps) 1827fc00086eSStanimir Varbanov return false; 1828fc00086eSStanimir Varbanov 18297f77fa9fSBryan O'Donoghue found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, fmt); 18307f77fa9fSBryan O'Donoghue if (found) 18317f77fa9fSBryan O'Donoghue goto done; 1832fc00086eSStanimir Varbanov 18337f77fa9fSBryan O'Donoghue found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt); 18347f77fa9fSBryan O'Donoghue done: 18357f77fa9fSBryan O'Donoghue return found; 1836fc00086eSStanimir Varbanov } 1837fc00086eSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_check_format); 1838fc00086eSStanimir Varbanov 183901e869e7SDikshita Agarwal int venus_helper_set_stride(struct venus_inst *inst, 184001e869e7SDikshita Agarwal unsigned int width, unsigned int height) 184101e869e7SDikshita Agarwal { 184201e869e7SDikshita Agarwal const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO; 184301e869e7SDikshita Agarwal 184401e869e7SDikshita Agarwal struct hfi_uncompressed_plane_actual_info plane_actual_info; 184501e869e7SDikshita Agarwal 184601e869e7SDikshita Agarwal plane_actual_info.buffer_type = HFI_BUFFER_INPUT; 184701e869e7SDikshita Agarwal plane_actual_info.num_planes = 2; 184801e869e7SDikshita Agarwal plane_actual_info.plane_format[0].actual_stride = width; 184901e869e7SDikshita Agarwal plane_actual_info.plane_format[0].actual_plane_buffer_height = height; 185001e869e7SDikshita Agarwal plane_actual_info.plane_format[1].actual_stride = width; 185101e869e7SDikshita Agarwal plane_actual_info.plane_format[1].actual_plane_buffer_height = height / 2; 185201e869e7SDikshita Agarwal 185301e869e7SDikshita Agarwal return hfi_session_set_property(inst, ptype, &plane_actual_info); 185401e869e7SDikshita Agarwal } 185501e869e7SDikshita Agarwal EXPORT_SYMBOL_GPL(venus_helper_set_stride); 1856